00001 #ifndef _PG_EDGES_HPP_
00002 #define _PG_EDGES_HPP_
00003
00004 #include <map>
00005
00006 #include "PG_property.hpp"
00007
00008 namespace ParGraph
00009 {
00010 struct directed_out_edges_type {};
00011 struct directed_in_out_edges_type {};
00012
00013 struct has_out_edges {};
00014 struct has_no_out_edges {};
00015 struct has_in_edges {};
00016 struct has_no_in_edges {};
00017 struct is_double_sided_edge {};
00018 struct is_not_double_sided_edge {};
00019
00020 template< class Property, class EdgeKind >
00021 struct edgelist_kind_traits {};
00022 template< class Edge >
00023 struct edge_traits
00024 {
00025 typedef typename Edge::value_type::second_type data_type;
00026 typedef typename data_type::property_type property_type;
00027 };
00028
00029 template< class EdgeList >
00030 struct edgelist_traits : edgelist_kind_traits< typename EdgeList::property_type, typename EdgeList::edge_kind >
00031 {
00032 };
00033
00034 template< class P >
00035 class DirectedOutEdges;
00036 template< class P >
00037 class DirectedInOutEdges;
00038
00039 template< class Iter >
00040 struct user_edge_type
00041 {
00042 typedef typename Iter::value_type::second_type::property_type edge_property;
00043 known_vertex_type source, target;
00044 Iter edge;
00045
00046 user_edge_type() {}
00047 user_edge_type( known_vertex_type v1, known_vertex_type v2, Iter e ) : source(v1), target(v2), edge(e) {}
00048 };
00049
00051 template< class Edge >
00052 inline EdgeID_t get_edge_id( Edge e )
00053 {
00054 return e.edge->first;
00055 }
00056
00058 template< class Edge, class Graph >
00059 inline known_vertex_type source( Edge e, const Graph &g )
00060 {
00061 return e.source;
00062 }
00063
00065 template< class Edge, class Graph >
00066 inline known_vertex_type target( Edge e, const Graph &g )
00067 {
00068 return e.target;
00069 }
00070
00071 template< class Edge >
00072 inline known_vertex_type get_v2( Edge e )
00073 {
00074 return e.edge->second.get_v2();
00075 }
00076
00077 template< class Edge >
00078 inline EdgeID_t get_v2_id( Edge e )
00079 {
00080 return get_id( e.edge->second.get_v2());
00081 }
00082
00083 template< class Edge >
00084 inline bool is_out_edge( Edge &e )
00085 {
00086 return e.target == e.edge->second.get_v2();
00087 }
00088
00090 template< class Edge >
00091 inline typename Edge::edge_property &
00092 get_edge_property( Edge &e )
00093 {
00094 return e.edge->second.get_property_reference();
00095 }
00096
00097 template< class PropertyWrapper >
00098 class EdgeBase
00099 {
00100 known_vertex_type other_vertex;
00101 PropertyWrapper prop_wrapper;
00102
00103 public:
00104 typedef typename PropertyWrapper::property_type property_type;
00105 EdgeBase() {}
00106 EdgeBase( known_vertex_type id ) : other_vertex( id ) {}
00107 EdgeBase( known_vertex_type id, typename PropertyWrapper::constructor_argument_type p ) :
00108 other_vertex( id ), prop_wrapper(p) {}
00109
00110 known_vertex_type get_v2() const { return other_vertex; }
00111 void set_v2( known_vertex_type v ) { other_vertex = v; }
00112
00113 typename PropertyWrapper::property_type & get_property_reference()
00114 { return prop_wrapper.get_reference(); }
00115 const typename PropertyWrapper::property_type & get_property_reference() const
00116 { return prop_wrapper.get_reference(); }
00117
00118 void join( EdgeBase< PropertyWrapper > & e2 )
00119 { prop_wrapper.join( e2.prop_wrapper ); }
00120 void delete_property()
00121 { prop_wrapper.delete_property(); }
00122
00123 friend class DirectedOutEdges< typename PropertyWrapper::property_type >;
00124 friend class DirectedInOutEdges< typename PropertyWrapper::property_type >;
00125 };
00126
00127
00128
00129 template< class Property >
00130 struct SimpleEdgePropertyWrapper
00131 {
00132 Property prop;
00133
00134 typedef Property property_type;
00135 typedef Property & constructor_argument_type;
00136
00137 SimpleEdgePropertyWrapper() {}
00138 SimpleEdgePropertyWrapper( Property & p ) : prop(p) {}
00139 Property & get_reference() { return prop; }
00140 const Property & get_reference() const { return prop; }
00141 };
00142
00143 template< class Property >
00144 struct DoubleSidedEdgePropertyWrapper
00145 {
00146 Property * prop;
00147
00148 typedef Property property_type;
00149 typedef Property * constructor_argument_type;
00150
00151 DoubleSidedEdgePropertyWrapper() {}
00152 DoubleSidedEdgePropertyWrapper( Property * p ) : prop(p) {}
00153
00154 Property & get_reference() { return *prop; }
00155 const Property & get_reference() const { return *prop; }
00156 void delete_property() { delete prop; }
00157 void new_property() { prop = new Property; }
00158 static Property * static_new_property() { return new Property; }
00159 static Property * static_new_property( const Property & p ) { return new Property(p); }
00160 void join( DoubleSidedEdgePropertyWrapper<Property> & w2 )
00161 {
00162 if( prop != w2.prop )
00163 {
00164 delete w2.prop;
00165 w2.prop = prop;
00166 }
00167 }
00168 };
00169
00170 template<>
00171 struct DoubleSidedEdgePropertyWrapper< no_property >
00172 {
00173 no_property prop;
00174 typedef no_property property_type;
00175 typedef no_property constructor_argument_type;
00176
00177 DoubleSidedEdgePropertyWrapper() {}
00178 DoubleSidedEdgePropertyWrapper( const no_property & ) {}
00179 no_property & get_reference() { return prop; }
00180 const no_property & get_reference() const { return prop; }
00181 void delete_property() { }
00182 void join( DoubleSidedEdgePropertyWrapper<no_property> & ) { }
00183 void new_property() {}
00184 static no_property static_new_property() { return no_property(); }
00185 static no_property static_new_property( const no_property & ) { return no_property(); }
00186 };
00187
00188
00189 template< class Iter >
00190 class InEdgeIterator
00191 {
00192 known_vertex_type target;
00193 Iter iter;
00194 public:
00195 typedef user_edge_type< Iter > value_type;
00196 InEdgeIterator() : iter() {}
00197 InEdgeIterator( known_vertex_type v, Iter _iter ) : target(v), iter(_iter) {}
00198 InEdgeIterator( const InEdgeIterator<Iter> & other ) : target( other.target ), iter( other.iter ) {}
00199 void operator++(int)
00200 {
00201 iter++;
00202 }
00203 void operator++()
00204 {
00205 iter++;
00206 }
00207 bool operator==( const InEdgeIterator<Iter> & other ) const
00208 {
00209 return iter == other.iter;
00210 }
00211 bool operator!=( const InEdgeIterator<Iter> & other ) const
00212 {
00213 return iter != other.iter;
00214 }
00215 value_type operator*() const
00216 {
00217 return value_type( iter->second.get_v2(), target, iter);
00218 }
00219 InEdgeIterator & operator=( const InEdgeIterator<Iter> & other )
00220 {
00221 iter = other.iter;
00222 target = other.target;
00223 return *this;
00224 }
00225 };
00226
00227 template< class Iter >
00228 class OutEdgeIterator
00229 {
00230 known_vertex_type source;
00231 Iter iter;
00232 public:
00233 typedef user_edge_type< Iter > value_type;
00234 OutEdgeIterator() : iter() {}
00235 OutEdgeIterator( known_vertex_type v, Iter _iter ) : source(v), iter(_iter) {}
00236 OutEdgeIterator( const OutEdgeIterator<Iter> & other ) : source( other.source ), iter( other.iter ) {}
00237 void operator++(int)
00238 {
00239 iter++;
00240 }
00241 void operator++()
00242 {
00243 iter++;
00244 }
00245 bool operator==( const OutEdgeIterator<Iter> & other ) const
00246 {
00247 return iter == other.iter;
00248 }
00249 bool operator!=( const OutEdgeIterator<Iter> & other ) const
00250 {
00251 return iter != other.iter;
00252 }
00253 value_type operator*() const
00254 {
00255 return value_type( source, iter->second.get_v2(), iter);
00256 }
00257 OutEdgeIterator & operator=( const OutEdgeIterator<Iter> & other )
00258 {
00259 iter = other.iter;
00260 source = other.source;
00261 return *this;
00262 }
00263 };
00264
00265
00266
00267 template< class Property >
00268 class DirectedOutEdges
00269 {
00270 public:
00271 typedef EdgeBase<SimpleEdgePropertyWrapper<Property> > edge_type;
00272 typedef std::pair< EdgeID_t, edge_type > Edge_with_ID_t;
00273 typedef typename std::map< const EdgeID_t, edge_type > map_type;
00274 typedef OutEdgeIterator< typename map_type::iterator > out_iterator;
00275 typedef OutEdgeIterator< typename map_type::const_iterator > const_out_iterator;
00276 typedef user_edge_type< typename map_type::iterator > Edge;
00277 typedef typename map_type::iterator mapiterator;
00278 typedef typename map_type::const_iterator const_mapiterator;
00279
00280 public:
00281 std::map< const EdgeID_t, edge_type > out_edges;
00282
00283 public:
00284 DirectedOutEdges() : out_edges() {}
00285
00286 void clear()
00287 {
00288 out_edges.clear();
00289 }
00290
00291
00292
00293
00294
00295
00296
00297
00298
00299
00300
00301
00302
00303
00304
00305
00306
00307
00308
00309
00310
00311
00312
00313
00314
00315 template< class Tag, class Graph, class DistHelper >
00316 void _pgdist_fill_buf( Tag t, Graph & g, DistHelper & dh, AllToAllBuffer & buf ) const
00317 {
00318 typename std::map< const EdgeID_t, edge_type >::const_iterator it = out_edges.begin();
00319 buf.put( out_edges.size() );
00320 for(; it != out_edges.end() ; it++ )
00321 {
00322 buf.put( &(*it).first, 1 );
00323 buf.put( get_id((*it).second.other_vertex) );
00324 dh.write_proc( (*it).second.other_vertex, buf );
00325 g.dek_known_vertex_counter((*it).second.other_vertex);
00326 put_property_into_buffer( (*it).second.prop_wrapper.prop, buf );
00327 }
00328 }
00329 template< class Tag, class Graph, class DistHelper >
00330 void _pgdist_read_buf( Tag t, Graph & g, DistHelper & dh, AllToAllBuffer & buf )
00331 {
00332 Edge_with_ID_t tmp;
00333 size_t size;
00334 buf.get( &size, 1 );
00335 for( unsigned int i = 0 ; i < size ; i++ )
00336 {
00337 buf.get( &tmp.first, 1 );
00338 VertexID_t v;
00339 buf.get( &v, 1 );
00340 proc_t p = dh.read_proc( buf );
00341 if( p == _libbase.rank() ) p = _libbase.size();
00342 tmp.second.other_vertex = g.ink_known_vertex_counter_and_set_processor( v, p );
00343 get_property_from_buffer( tmp.second.prop_wrapper.prop, buf );
00344 out_edges.insert( tmp );
00345 }
00346 }
00347
00348 void add( EdgeID_t id, VertexID_t v )
00349 {
00350 out_edges.insert( std::make_pair( id, edge_type( v ) ) );
00351 }
00352
00353 void add( EdgeID_t id, VertexID_t v, Property & p )
00354 {
00355 out_edges.insert( std::make_pair( id, edge_type( v, p ) ) );
00356 }
00357
00358
00359
00360
00361 };
00362
00363 template< class Property >
00364 class DirectedInOutEdges
00365 {
00366 public:
00367 typedef EdgeBase<DoubleSidedEdgePropertyWrapper<Property> > edge_type;
00368 typedef std::pair< EdgeID_t, edge_type > Edge_with_ID_t;
00369 typedef typename std::map< const EdgeID_t, edge_type > map_type;
00370 typedef InEdgeIterator< typename map_type::iterator > in_iterator;
00371 typedef OutEdgeIterator< typename map_type::iterator > out_iterator;
00372 typedef InEdgeIterator< typename map_type::const_iterator > const_in_iterator;
00373 typedef OutEdgeIterator< typename map_type::const_iterator > const_out_iterator;
00374 typedef typename map_type::const_iterator const_mapiterator;
00375 typedef typename map_type::iterator mapiterator;
00376 typedef user_edge_type< typename map_type::iterator > Edge;
00377
00378 public:
00379 std::map< const EdgeID_t, edge_type > in_edges;
00380 std::map< const EdgeID_t, edge_type > out_edges;
00381
00382 public:
00383 DirectedInOutEdges() : in_edges(), out_edges() {}
00384
00385 edge_type & get_edge_reference( EdgeID_t id );
00386 const edge_type & get_edge_reference( EdgeID_t id ) const;
00387 edge_type & get_inedge_reference( EdgeID_t id );
00388 const edge_type & get_inedge_reference( EdgeID_t id ) const;
00389 template< class G, class M >
00390 void remove_edges( G&, M );
00391 template< class G >
00392 void complete_graph_remove_edges( G& );
00393 template< class V, class G, class M, class F >
00394 void remove_edges_if( V, G&, M, F& );
00395 template< class G, class M >
00396 void remove_in_edges( G&, M );
00397 template< class G, class M >
00398 void remove_in_edges( G&, M, AllToAllBuffer& );
00399 void remove_edge( EdgeID_t );
00400 template< class G, class M >
00401 void remove_in_edge( Edge, G&, M );
00402 template< class G, class M >
00403 void remove_out_edge( Edge, G&, M );
00404 template< class G, class M >
00405 void remove_in_edge( mapiterator, G&, M );
00406 template< class G, class M >
00407 void remove_out_edge( mapiterator, G&, M );
00408 template< class G, class M >
00409 void remove_in_edge( Edge, G&, M, AllToAllBuffer& );
00410 template< class G, class M >
00411 void remove_out_edge( Edge, G&, M, AllToAllBuffer& );
00412
00413 void clear()
00414 {
00415 in_edges.clear();
00416 out_edges.clear();
00417 }
00418
00419
00420
00421
00422
00423
00424
00425
00426
00427
00428
00429
00430
00431
00432
00433
00434
00435
00436
00437
00438
00439
00440
00441
00442
00443
00444
00445
00446
00447
00448
00449
00450
00451
00452
00453
00454
00455
00456
00457
00458
00459
00460
00461 template< class Tag, class Graph, class DistHelper >
00462 void _pgdist_fill_buf( Tag t, Graph & g, DistHelper & dh, AllToAllBuffer & buf )
00463 {
00464 buf.put( in_edges.size() );
00465 mapiterator it = in_edges.begin();
00466 for(; it != in_edges.end() ; it++ )
00467 {
00468 buf.put( &(it->first), 1 );
00469 buf.put( get_id(it->second.other_vertex) );
00470 dh.write_proc( it->second.other_vertex, buf );
00471 g.dek_known_vertex_counter(it->second.other_vertex);
00472 put_property_into_buffer( it->second.get_property_reference(), buf );
00473 if( ! g.is_vertex_local( it->second.other_vertex ) )
00474 {
00475 it->second.prop_wrapper.delete_property();
00476 }
00477 }
00478 buf.put( out_edges.size() );
00479 it = out_edges.begin();
00480 for(; it != out_edges.end() ; it++ )
00481 {
00482 buf.put( &(it->first), 1 );
00483 buf.put( get_id(it->second.other_vertex) );
00484 dh.write_proc( it->second.other_vertex, buf );
00485 g.dek_known_vertex_counter(it->second.other_vertex);
00486 put_property_into_buffer( it->second.get_property_reference(), buf );
00487 if( ! g.is_vertex_local( it->second.other_vertex ) )
00488 {
00489 it->second.prop_wrapper.delete_property();
00490 }
00491 }
00492 }
00493 template< class Tag, class Graph, class DistHelper >
00494 void _pgdist_read_buf( Tag t, Graph & g, DistHelper & dh, AllToAllBuffer & buf )
00495 {
00496 Edge_with_ID_t tmp;
00497 size_t size;
00498 Property trash;
00499 buf.get( &size, 1 );
00500 for( size_t i = 0 ; i < size ; i++ )
00501 {
00502 buf.get( &tmp.first, 1 );
00503 VertexID_t v;
00504 buf.get( &v, 1 );
00505 proc_t p = dh.read_proc( buf );
00506 if( p == _libbase.rank() ) p = _libbase.size();
00507 tmp.second.other_vertex = g.ink_known_vertex_counter_and_set_processor( v, p );
00508 if( g.is_vertex_local( tmp.second.other_vertex ) )
00509 {
00510 get_property_from_buffer( trash, buf );
00511 tmp.second.prop_wrapper.prop = get_property_value(
00512 g.get_property_reference( tmp.second.other_vertex ), t ).get_edge_reference( tmp.first ).prop_wrapper.prop;
00513 }
00514 else
00515 {
00516 tmp.second.prop_wrapper.new_property();
00517 get_property_from_buffer( tmp.second.get_property_reference(), buf );
00518 }
00519 in_edges.insert( tmp );
00520 }
00521 buf.get( &size, 1 );
00522 for( size_t i = 0 ; i < size ; i++ )
00523 {
00524 buf.get( &tmp.first, 1 );
00525 VertexID_t v;
00526 buf.get( &v, 1 );
00527 proc_t p = dh.read_proc( buf );
00528 if( p == _libbase.rank() ) p = _libbase.size();
00529 tmp.second.other_vertex = g.ink_known_vertex_counter_and_set_processor( v, p );
00530 if( g.is_vertex_local( tmp.second.other_vertex ) )
00531 {
00532 get_property_from_buffer( trash, buf );
00533 tmp.second.prop_wrapper.prop = get_property_value(
00534 g.get_property_reference( tmp.second.other_vertex ), t ).get_edge_reference( tmp.first ).prop_wrapper.prop;
00535 }
00536 else
00537 {
00538 tmp.second.prop_wrapper.new_property();
00539 get_property_from_buffer( tmp.second.get_property_reference(), buf );
00540 }
00541 out_edges.insert( tmp );
00542 }
00543 }
00544
00545
00546
00547
00548
00549
00550
00551
00552
00553 };
00554
00555 template< class P >
00556 typename DirectedInOutEdges<P>::edge_type &
00557 DirectedInOutEdges<P>::get_edge_reference( EdgeID_t id )
00558 {
00559 if( out_edges.find( id ) != out_edges.end() )
00560 return (*out_edges.find( id )).second;
00561 return (*in_edges.find( id )).second;
00562 }
00563
00564 template< class P >
00565 const typename DirectedInOutEdges<P>::edge_type &
00566 DirectedInOutEdges<P>::get_edge_reference( EdgeID_t id ) const
00567 {
00568 if( out_edges.find( id ) != out_edges.end() )
00569 return (*out_edges.find( id )).second;
00570 return (*in_edges.find( id )).second;
00571 }
00572
00573 template< class P >
00574 typename DirectedInOutEdges<P>::edge_type &
00575 DirectedInOutEdges<P>::get_inedge_reference( EdgeID_t id )
00576 {
00577 return (*in_edges.find( id )).second;
00578 }
00579
00580 template< class P >
00581 const typename DirectedInOutEdges<P>::edge_type &
00582 DirectedInOutEdges<P>::get_inedge_reference( EdgeID_t id ) const
00583 {
00584 return (*in_edges.find( id )).second;
00585 }
00586
00587 template< class P>
00588 template< class Graph, class EdgeMap >
00589 void
00590 DirectedInOutEdges<P>::remove_edges( Graph &g, EdgeMap m )
00591 {
00592 mapiterator eit, eitnext;
00593 eit = out_edges.begin();
00594 for(; eit != out_edges.end() ; eit = eitnext )
00595 {
00596 eitnext = eit; eitnext++;
00597 remove_out_edge( eit, g, m );
00598 }
00599 mapiterator eit2, eitnext2;
00600 eit2 = in_edges.begin();
00601 for(; eit2 != in_edges.end() ; eit2 = eitnext2 )
00602 {
00603 eitnext2 = eit2; eitnext2++;
00604 remove_in_edge( eit2, g, m );
00605 }
00606 }
00607
00608 template< class P>
00609 template< class Graph >
00610 void
00611 DirectedInOutEdges<P>::complete_graph_remove_edges( Graph &g )
00612 {
00613 mapiterator eit, eitnext;
00614 eit = out_edges.begin();
00615 for(; eit != out_edges.end() ; eit = eitnext )
00616 {
00617 eitnext = eit; eitnext++;
00618 (*eit).second.delete_property();
00619 out_edges.erase( eit );
00620 }
00621 mapiterator eit2, eitnext2;
00622 eit2 = in_edges.begin();
00623 for(; eit2 != in_edges.end() ; eit2 = eitnext2 )
00624 {
00625 eitnext2 = eit2; eitnext2++;
00626 if( ! g.is_vertex_local( (*eit2).second.get_v2() ) )
00627 (*eit2).second.delete_property();
00628 in_edges.erase( eit2 );
00629 }
00630 }
00631
00632 template< class P>
00633 template< class Vertex, class Graph, class EdgeMap, class Function >
00634 void
00635 DirectedInOutEdges<P>::remove_edges_if( Vertex v, Graph &g, EdgeMap m, Function & f )
00636 {
00637 mapiterator eit, eitnext;
00638 eit = out_edges.begin();
00639 for(; eit != out_edges.end() ; eit = eitnext )
00640 {
00641 eitnext = eit; eitnext++;
00642 if( f( Edge( v, eit->second.get_v2(), eit ) ) )
00643 {
00644 remove_out_edge( eit, g, m );
00645 }
00646 }
00647 mapiterator eit2, eitnext2;
00648 eit2 = in_edges.begin();
00649 for(; eit2 != in_edges.end() ; eit2 = eitnext2 )
00650 {
00651 eitnext2 = eit2; eitnext2++;
00652 if( f( Edge( eit2->second.get_v2(), v, eit2 ) ) )
00653 {
00654 remove_in_edge( eit2, g, m );
00655 }
00656 }
00657 }
00658
00659 template< class P>
00660 void
00661 DirectedInOutEdges<P>::remove_edge( EdgeID_t e )
00662 {
00663 bool prop_deleted = false;
00664 mapiterator outit = out_edges.find(e);
00665 if( outit != out_edges.end() )
00666 {
00667 (*outit).second.prop_wrapper.delete_property();
00668 out_edges.erase( outit );
00669 prop_deleted = true;
00670 }
00671 mapiterator init = in_edges.find(e);
00672 if( init != in_edges.end() )
00673 {
00674 if( prop_deleted == false ) (*init).second.prop_wrapper.delete_property();
00675 in_edges.erase( init );
00676 }
00677 }
00678
00679 template< class P>
00680 template< class Graph, class EdgeMap >
00681 void
00682 DirectedInOutEdges<P>::remove_in_edges( Graph &g, EdgeMap m )
00683 {
00684 Edge eit, eitnext;
00685 eit = get_in_edges( m, *this ).begin();
00686 for(; eit != in_edges.end() ; eit = eitnext )
00687 {
00688 eitnext = eit; eitnext++;
00689 remove_in_edge( eit, g, m );
00690 }
00691 }
00692
00693 template< class P>
00694 template< class Graph, class EdgeMap >
00695 void
00696 DirectedInOutEdges<P>::remove_in_edges( Graph &g, EdgeMap m, AllToAllBuffer &buf )
00697 {
00698 Edge eit, eitnext;
00699 eit = get_in_edges( m, *this ).begin();
00700 for(; eit != get_in_edges( m, *this ).end() ; eit = eitnext )
00701 {
00702 eitnext = eit; eitnext++;
00703 remove_in_edge( eit, g, m, buf );
00704 }
00705 }
00706
00707 template< class P>
00708 template< class Graph, class EdgeMap >
00709 void
00710 DirectedInOutEdges<P>::remove_in_edge( Edge e, Graph &g, EdgeMap m )
00711 {
00712 e.edge->second.delete_property();
00713 if( g.is_vertex_local( e.source ) )
00714 {
00715 get_out_edges( m, e.source, g ).erase( e.edge->first );
00716 }
00717 in_edges.erase( e.edge );
00718 }
00719
00720 template< class P>
00721 template< class Graph, class EdgeMap >
00722 void
00723 DirectedInOutEdges<P>::remove_out_edge( Edge e, Graph &g, EdgeMap m )
00724 {
00725 e.edge->second.delete_property();
00726 if( g.is_vertex_local( e.target ) )
00727 {
00728 get_in_edges( m, e.target, g ).erase( e.edge->first );
00729 }
00730 out_edges.erase( e.edge );
00731 }
00732
00733 template< class P>
00734 template< class Graph, class EdgeMap >
00735 void
00736 DirectedInOutEdges<P>::remove_in_edge( mapiterator e, Graph &g, EdgeMap m )
00737 {
00738 e->second.delete_property();
00739 if( g.is_vertex_local( e->second.get_v2() ) )
00740 {
00741 get_out_edges( m, e->second.get_v2(), g ).erase( e->first );
00742 }
00743 in_edges.erase( e );
00744 }
00745
00746 template< class P>
00747 template< class Graph, class EdgeMap >
00748 void
00749 DirectedInOutEdges<P>::remove_out_edge( mapiterator e, Graph &g, EdgeMap m )
00750 {
00751 e->second.delete_property();
00752 if( g.is_vertex_local( e->second.get_v2() ) )
00753 {
00754 get_in_edges( m, e->second.get_v2(), g ).erase( e->first );
00755 }
00756 out_edges.erase( e );
00757 }
00758
00759 template< class P>
00760 template< class Graph, class EdgeMap >
00761 void
00762 DirectedInOutEdges<P>::remove_in_edge( Edge e, Graph &g, EdgeMap m, AllToAllBuffer & buf )
00763 {
00764 e.edge->second.prop_wrapper.delete_property();
00765
00766 if( g.is_vertex_local( e.source ) )
00767 {
00768 get_out_edges( m, e.source, g ).erase( e.edge->first );
00769 }
00770 else
00771 {
00772 buf.put( e.edge->first );
00773 buf.put( e.source );
00774 }
00775 in_edges.erase( e.edge );
00776 }
00777
00778 template< class P>
00779 template< class Graph, class EdgeMap >
00780 void
00781 DirectedInOutEdges<P>::remove_out_edge( Edge e, Graph &g, EdgeMap m, AllToAllBuffer & buf )
00782 {
00783 (*e).second.prop_wrapper.delete_property();
00784 if( g.is_vertex_local( e.target ) )
00785 {
00786 get_in_edges( m, e.target, g ).erase( e.edge->first );
00787 }
00788 else
00789 {
00790 buf.put( e.edge->first );
00791 buf.put( e.target );
00792 }
00793 out_edges.erase( e.edge );
00794 }
00795
00796
00797
00798 template< class Property >
00799 struct edgelist_kind_traits<Property,directed_out_edges_type>
00800 {
00801 typedef has_out_edges has_out_edges_tag;
00802 typedef has_no_in_edges has_in_edges_tag;
00803 typedef is_not_double_sided_edge is_double_sided_edge_tag;
00804
00805 typedef DirectedOutEdges<Property> base;
00806
00807 typedef typename base::out_iterator out_iterator;
00808 typedef typename base::const_iterator const_iterator;
00809 typedef typename base::out_iterator out_iterator;
00810 typedef typename base::const_out_iterator const_out_iterator;
00811 typedef typename base::Edge Edge;
00812 typedef typename base::const_Edge const_Edge;
00813 };
00814
00815 template< class Property >
00816 struct edgelist_kind_traits<Property,directed_in_out_edges_type>
00817 {
00818 typedef has_out_edges has_out_edges_tag;
00819 typedef has_in_edges has_in_edges_tag;
00820 typedef is_double_sided_edge is_double_sided_edge_tag;
00821
00822 typedef DirectedInOutEdges<Property> base;
00823
00824 typedef typename base::in_iterator in_iterator;
00825 typedef typename base::out_iterator out_iterator;
00826 typedef typename base::const_in_iterator const_in_iterator;
00827 typedef typename base::const_out_iterator const_out_iterator;
00828 typedef typename base::Edge Edge;
00829 };
00830
00831 template< class Property, class EdgeKind >
00832 class EdgeList : public edgelist_kind_traits<Property,EdgeKind>::base
00833 {
00834 typedef EdgeKind edge_kind;
00835 typedef Property property_type;
00836 };
00837
00838
00839
00840 template< class P, class EdgeKind >
00841 struct property_distribution_traits< EdgeList<P,EdgeKind> >
00842 {
00843 typedef complex_distribution distribution_type;
00844 };
00845
00846
00847
00849 template< class Map, class Graph >
00850 void
00851 copy_properties_out2in( Map m, Graph & g )
00852 {
00853 AllToAllBuffer buf;
00854
00855 typename Graph::VertexIterator v_it, v_end;
00856 boost::tie( v_it, v_end ) = g.get_local_vertices();
00857
00858 for(; v_it != v_end ; v_it++ )
00859 {
00860 typename Map::value_type::out_iterator e_it, e_end;
00861 boost::tie( e_it, e_end ) = out_edges( g, *v_it, m );
00862 for(; e_it != e_end ; e_it++ )
00863 {
00864 if( !g.is_vertex_local( (*e_it).second.get_v2() ) )
00865 {
00866 buf.set_proc( g.owning_processor( (*e_it).second.get_v2() ) );
00867 buf.put( (*e_it).second.get_v2() );
00868 buf.put( (*e_it).first );
00869 put_property_into_buffer( (*e_it).second.get_property_reference(), buf );
00870 }
00871 }
00872 }
00873 buf.communicate();
00874
00875 while( ! buf.is_empty() )
00876 {
00877 EdgeID_t eid;
00878 VertexID_t vid;
00879 buf.get( &vid, 1 );
00880 buf.get( &eid, 1 );
00881 get_property_from_buffer( (*get_in_edges( m, vid, g ).find( eid )).second.get_property_reference(), buf );
00882 }
00883 }
00884
00886 template< class EdgeMap, class EdgePropertyMap, class Graph >
00887 void
00888 copy_property_in2out( EdgeMap m1, EdgePropertyMap m2, Graph & g )
00889 {
00890 AllToAllBuffer buf;
00891 typename Graph::VertexIterator v_it, v_end;
00892 boost::tie( v_it, v_end ) = g.get_local_vertices();
00893
00894 for(; v_it != v_end ; v_it++ )
00895 {
00896 typename EdgeMap::in_iterator e_it, e_end;
00897 boost::tie( e_it, e_end ) = in_edges( g, *v_it, m1 );
00898 for(; e_it != e_end ; e_it++ )
00899 {
00900 if( !g.is_vertex_local( get_v2(*e_it) ) )
00901 {
00902 buf.set_proc( g.owning_processor( get_v2(*e_it) ) );
00903 buf.put( get_v2_id(*e_it) );
00904 buf.put( get_edge_id(*e_it) );
00905 buf.put( get( m2, *e_it ) );
00906 }
00907 }
00908 }
00909 buf.communicate();
00910
00911 while( ! buf.is_empty() )
00912 {
00913 EdgeID_t eid;
00914 VertexID_t vid;
00915 buf.get( &vid, 1 );
00916 buf.get( &eid, 1 );
00917 typename EdgePropertyMap::value_type tmp;
00918 buf.get( &tmp );
00919 put( m2, out_edge( g, vid, eid, m1 ), tmp );
00920 }
00921 }
00922
00928 template< class Map, class Graph >
00929 void
00930 add_delayed_edges( Map m, Graph & g, AllToAllBuffer & delayed_buf )
00931 {
00932 AllToAllBuffer asking_buf;
00933 typedef typename Map::edge_property_type Property;
00934
00935 delayed_buf.communicate();
00936
00937 while( ! delayed_buf.is_empty() )
00938 {
00939 EdgeID_t eid;
00940 VertexID_t v1id, v2id;
00941 typename DoubleSidedEdgePropertyWrapper< Property >::constructor_argument_type prop
00942 = DoubleSidedEdgePropertyWrapper< Property >::static_new_property();
00943 proc_t source_proc = delayed_buf.get( &eid, 1 );
00944 delayed_buf.get( &v1id, 1 );
00945 delayed_buf.get( &v2id, 1 );
00946 get_property_from_buffer( *prop, delayed_buf );
00947 if( g.is_vertex_local( v1id ) )
00948 {
00949 known_vertex_type v2;
00950 if( g.is_vertex_known( v2id ) )
00951 v2 = g.ink_known_vertex_counter( v2id );
00952 else
00953 {
00954 ask_for_position( source_proc, v2id, asking_buf );
00955 v2 = g.make_vertex_known( v2id, size() );
00956 }
00957 get_out_edges( m, v1id, g ).insert(
00958 make_pair( eid, typename Map::value_type::edge_type(v2,prop) ));
00959 }
00960 if( g.is_vertex_local( v2id ) )
00961 {
00962 known_vertex_type v1;
00963 if( g.is_vertex_known( v1id ) )
00964 v1 = g.ink_known_vertex_counter( v1id );
00965 else
00966 {
00967 ask_for_position( source_proc, v1id, asking_buf );
00968 v1 = g.make_vertex_known( v1id, size() );
00969 }
00970 get_in_edges( m, v2id, g ).insert(
00971 make_pair( eid, typename Map::value_type::edge_type(v1,prop) ));
00972 }
00973 }
00974
00975 do_asking_for_position( g, asking_buf );
00976 }
00977
00981 template< class Map, class V1, class V2, class Graph >
00982 EdgeID_t
00983 add_edge( Map m, V1 v1, V2 v2,
00984 Graph & g, AllToAllBuffer & delayed_buf )
00985 {
00986 EdgeID_t new_ID = g.get_free_edge_id();
00987 add_edge_with_id_worker( m, new_ID, g.get_known_vertex(v1), g.get_known_vertex(v2), Map::edge_property_type(), g, delayed_buf );
00988 return new_ID;
00989 }
00990
00994 template< class Map, class V1, class V2, class Property, class Graph >
00995 EdgeID_t
00996 add_edge( Map m, V1 v1, V2 v2, Property & prop,
00997 Graph & g, AllToAllBuffer & delayed_buf )
00998 {
00999 EdgeID_t new_ID = g.get_free_edge_id();
01000 add_edge_with_id_worker( m, new_ID, g.get_known_vertex(v1), g.get_known_vertex(v2), prop, g, delayed_buf );
01001 return new_ID;
01002 }
01003
01007 template< class Map, class V1, class V2, class Property, class Graph >
01008 inline void
01009 add_edge_with_id( Map m, EdgeID_t new_ID, V1 v1, V2 v2, Property & prop,
01010 Graph & g, AllToAllBuffer & delayed_buf )
01011 {
01012 add_edge_with_id_worker( m, new_ID, g.get_known_vertex(v1), g.get_known_vertex(v2), prop, g, delayed_buf );
01013 }
01014
01015 template< class Map, class Property, class Graph >
01016 void
01017 add_edge_with_id_worker( Map m, EdgeID_t new_ID, typename Graph::KnownVertex v1,
01018 typename Graph::KnownVertex v2, Property & prop,
01019 Graph & g, AllToAllBuffer & delayed_buf )
01020 {
01021 bool v1_is_local;
01022 proc_t v1_lays_on;
01023 typename DoubleSidedEdgePropertyWrapper< Property >::constructor_argument_type prop_pointer;
01024
01025 if( v1_is_local = g.is_vertex_local( v1 ) )
01026 {
01027 prop_pointer =
01028 DoubleSidedEdgePropertyWrapper< Property >::static_new_property(prop);
01029 get_out_edges( m, v1, g ).insert(
01030 make_pair( new_ID, typename Map::value_type::edge_type(v2,prop_pointer) ));
01031
01032 g.ink_known_vertex_counter( v2 );
01033 }
01034 else
01035 {
01036 delayed_buf.set_proc( v1_lays_on = g.owning_processor( v1 ) );
01037 delayed_buf.put( new_ID );
01038 delayed_buf.put( get_id(v1) );
01039 delayed_buf.put( get_id(v2) );
01040 put_property_into_buffer( prop, delayed_buf );
01041 }
01042
01043 if( g.is_vertex_local( v2 ) )
01044 {
01045 if( !v1_is_local )
01046 {
01047 prop_pointer =
01048 DoubleSidedEdgePropertyWrapper< Property >::static_new_property(prop);
01049 }
01050 get_in_edges( m, v2, g ).insert(
01051 make_pair( new_ID, typename Map::value_type::edge_type(v1,prop_pointer) ));
01052
01053 g.ink_known_vertex_counter( v1 );
01054 }
01055 else if( v1_is_local || v1_lays_on != g.owning_processor( v2 ) )
01056 {
01057
01058 delayed_buf.set_proc( g.owning_processor( v2 ) );
01059 delayed_buf.put( new_ID );
01060 delayed_buf.put( get_id(v1) );
01061 delayed_buf.put( get_id(v2) );
01062 put_property_into_buffer( prop, delayed_buf );
01063 }
01064 }
01065
01066 template< class Map, class Graph >
01067 EdgeID_t
01068 add_edge( Map m, VertexID_t v1, VertexID_t v2id, Graph & g )
01069 {
01070 EdgeID_t new_ID = g.get_free_edge_id();
01071
01072 known_vertex_type v2 = g.ink_known_vertex_counter( v2id );
01073 get( m, v1, g ).add( new_ID, v2 );
01074
01075 return new_ID;
01076 }
01077
01078 template< class Map, class V1, class V2, class Property, class Graph >
01079 EdgeID_t
01080 add_edge( Map m, V1 v1, V2 v2, Property & prop, Graph & g )
01081 {
01082 EdgeID_t new_ID = g.get_free_edge_id();
01083 add_edge_with_id( m, new_ID, v1, v2, prop, g );
01084 return new_ID;
01085 }
01086
01087 template< class Map, class V1, class V2, class Property, class Graph >
01088 inline void
01089 add_edge_with_id( Map m, EdgeID_t new_ID, V1 v1, V2 v2, Property & prop,
01090 Graph & g )
01091 {
01092 add_edge_with_id_worker( m, new_ID, g.get_known_vertex(v1), g.get_known_vertex(v2), prop, g );
01093 }
01094
01095 template< class Map, class Property, class Graph >
01096 void
01097 add_edge_with_id_worker( Map m, EdgeID_t new_ID, typename Graph::KnownVertex v1,
01098 typename Graph::KnownVertex v2, Property & prop, Graph & g )
01099 {
01100 get( m, v1, g ).add( new_ID, v2, prop );
01101 g.ink_known_vertex_counter( v2 );
01102 }
01103
01105 template< class Graph, class Vertex, class EdgeMap >
01106 inline pair<typename EdgeMap::in_iterator,
01107 typename EdgeMap::in_iterator>
01108 in_edges( Graph &g, Vertex v, EdgeMap m )
01109 {
01110 typename Graph::VertexProperty & prop = g.get_property_reference(v);
01111 return make_pair( typename EdgeMap::in_iterator( v,
01112 get_in_edges( m, prop ).begin()),
01113 typename EdgeMap::in_iterator( v,
01114 get_in_edges( m, prop ).end()) );
01115 }
01116
01117 template< class EdgeList >
01118 inline pair<typename EdgeList::const_mapiterator, typename EdgeList::const_mapiterator>
01119 in_edges( const EdgeList &edges )
01120 {
01121 return make_pair( typename EdgeList::const_mapiterator(
01122 edges.in_edges.begin()),
01123 typename EdgeList::const_mapiterator(
01124 edges.in_edges.end()) );
01125 }
01126
01128 template< class Graph, class Vertex, class EdgeMap >
01129 inline typename EdgeMap::Edge
01130 in_edge( Graph &g, Vertex v, EdgeID_t e, EdgeMap m )
01131 {
01132 typename EdgeMap::mapiterator it = get_in_edges( m, v, g ).find( e );
01133 return typename EdgeMap::Edge( it->second.get_v2(), g.get_known_vertex(v), it );
01134 }
01135
01137 template< class Graph, class Vertex, class EdgeMap >
01138 inline pair< typename EdgeMap::Edge, bool >
01139 in_edge_test( Graph &g, Vertex v, EdgeID_t e, EdgeMap m )
01140 {
01141 typename EdgeMap::mapiterator tmp = get_in_edges( m, v, g ).find( e );
01142 if( tmp != get_in_edges( m, v, g ).end() )
01143 return make_pair( typename EdgeMap::Edge( tmp->second.get_v2(), g.get_known_vertex(v), tmp ), true );
01144 else
01145 return make_pair( typename EdgeMap::Edge( g.get_known_vertex(v), g.get_known_vertex(v), tmp ), false );
01146 }
01147
01149 template< class Graph, class Vertex, class EdgeMap >
01150 inline pair<typename EdgeMap::out_iterator,
01151 typename EdgeMap::out_iterator>
01152 out_edges( Graph &g, Vertex v, EdgeMap m )
01153 {
01154 typename Graph::VertexProperty & prop = g.get_property_reference(v);
01155 return make_pair( typename EdgeMap::out_iterator( v,
01156 get_out_edges( m, prop ).begin()),
01157 typename EdgeMap::out_iterator( v,
01158 get_out_edges( m, prop ).end()) );
01159 }
01160
01161 template< class EdgeList >
01162 inline pair<typename EdgeList::const_mapiterator, typename EdgeList::const_mapiterator>
01163 out_edges( const EdgeList &edges )
01164 {
01165 return make_pair( typename EdgeList::const_mapiterator(edges.out_edges.begin()),
01166 typename EdgeList::const_mapiterator(edges.out_edges.end()) );
01167 }
01168
01170 template< class Graph, class Vertex, class EdgeMap >
01171 inline typename EdgeMap::Edge
01172 out_edge( Graph &g, Vertex v, EdgeID_t e, EdgeMap m )
01173 {
01174 typename EdgeMap::mapiterator it = get_out_edges( m, v, g ).find( e );
01175 return typename EdgeMap::Edge( g.get_known_vertex(v), it->second.get_v2(), it );
01176 }
01177
01179 template< class Graph, class Vertex, class EdgeMap >
01180 inline pair< typename EdgeMap::Edge, bool >
01181 out_edge_test( Graph &g, Vertex v, EdgeID_t e, EdgeMap m )
01182 {
01183 typename EdgeMap::mapiterator tmp = get_out_edges( m, v, g ).find( e );
01184 if( tmp != get_out_edges( m, v, g ).end() )
01185 return make_pair( typename EdgeMap::Edge( g.get_known_vertex(v), tmp->second.get_v2(), tmp ), true );
01186 else
01187 return make_pair( typename EdgeMap::Edge( g.get_known_vertex(v), g.get_known_vertex(v), tmp ), false );
01188 }
01189
01191 template< class Graph, class Vertex, class EdgeMap >
01192 inline size_t
01193 out_degree( Graph &g, Vertex v, EdgeMap m )
01194 {
01195 return get_out_edges( m, v, g ).size();
01196 }
01197
01199 template< class Graph, class Vertex, class EdgeMap >
01200 inline size_t
01201 in_degree( Graph &g, Vertex v, EdgeMap m )
01202 {
01203 return get_in_edges( m, v, g ).size();
01204 }
01205
01211 template< class Graph, class EdgeMap >
01212 void
01213 remove_delayed_edges( Graph &g, EdgeMap m, AllToAllBuffer &buf )
01214 {
01215 buf.communicate();
01216
01217 while( ! buf.is_empty() )
01218 {
01219 EdgeID_t e;
01220 VertexID_t v;
01221 buf.get( &e, 1 );
01222 buf.get( &v, 1 );
01223 get( m, v, g ).remove_edge( e );
01224 }
01225 }
01226
01230 template< class Edge, class Graph, class EdgeMap >
01231 void
01232 remove_edge( Edge &e, Graph &g, EdgeMap m )
01233 {
01234 if( is_out_edge(e) )
01235 {
01236 get( m, source(e,g), g ).remove_out_edge( e, g, m );
01237 }
01238 else
01239 {
01240 get( m, target(e,g), g ).remove_in_edge( e, g, m );
01241 };
01242 }
01243
01244 template< class Graph, class EdgeMap >
01245 void
01246 remove_edges( Graph &g, EdgeMap m )
01247 {
01248 typename Graph::VertexIterator vit, vend;
01249 boost::tie( vit, vend ) = g.get_local_vertices();
01250 for(; vit != vend ; vit++ )
01251 {
01252 get( m, *vit, g ).complete_graph_remove_edges( g );
01253 }
01254 }
01255
01256 template< class Graph, class EdgeMap, class Function >
01257 void
01258 remove_edges_if( Graph &g, EdgeMap m, Function &f )
01259 {
01260 typename Graph::VertexIterator vit, vend;
01261 boost::tie( vit, vend ) = g.get_local_vertices();
01262 for(; vit != vend ; vit++ )
01263 {
01264 get( m, *vit, g ).remove_edges_if( *vit, g, m, f );
01265 }
01266 }
01267
01268 template< class Graph, class Iterator, class EdgeMap >
01269 void
01270 remove_in_edges( Graph &g, Iterator vit, Iterator vend, EdgeMap m )
01271 {
01272 for(; vit != vend ; vit++ )
01273 {
01274 get( m, *vit, g ).remove_in_edges( g, m );
01275 }
01276 }
01277
01278 template< class Graph, class Iterator, class EdgeMap >
01279 void
01280 remove_in_edges( Graph &g, Iterator vit, Iterator vend, EdgeMap m, AllToAllBuffer &buf )
01281 {
01282 for(; vit != vend ; vit++ )
01283 {
01284 get( m, *vit, g ).remove_in_edges( g, m, buf );
01285 }
01286 }
01287
01288 template< class Graph, class Iterator, class EdgeMap >
01289 void
01290 remove_out_edges( Graph &g, Iterator vit, Iterator vend, EdgeMap m )
01291 {
01292 for(; vit != vend ; vit++ )
01293 {
01294 get( m, *vit, g ).remove_out_edges( g, m );
01295 }
01296 }
01297
01301 template< class Graph, class Iterator, class EdgeMap >
01302 void
01303 remove_out_edges( Graph &g, Iterator vit, Iterator vend, EdgeMap m, AllToAllBuffer &buf )
01304 {
01305 for(; vit != vend ; vit++ )
01306 {
01307 get( m, *vit, g ).remove_out_edges( g, m, buf );
01308 }
01309 }
01310
01311 }
01312
01313 #endif // _PG_EDGES_HPP_