00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043 # ifndef TPL_CONCURRENT_GRAPH_H
00044 # define TPL_CONCURRENT_GRAPH_H
00045
00046 # include <pthread.h>
00047 # include <tpl_graph.H>
00048 # include <useMutex.H>
00049
00050 using namespace Aleph;
00051
00052
00053 namespace Aleph
00054 {
00055
00056 template <typename Node_Info, typename Arc_Info>
00057 class Concurrent_Graph;
00058
00069 template <typename Node_Info>
00070 struct Concurrent_Node : public Graph_Node<Node_Info>
00071 {
00072 typedef Graph_Node<Node_Info> Base_Node;
00073
00074 typedef Node_Info Node_Type;
00075
00076 pthread_mutex_t mutex;
00077
00078 Concurrent_Node() : Base_Node()
00079 {
00080 init_mutex(mutex);
00081 }
00082
00083 Concurrent_Node(const Node_Info & node_info) : Base_Node(node_info)
00084 {
00085 init_mutex(mutex);
00086 }
00087
00088 Concurrent_Node(Base_Node * node) : Base_Node(node)
00089 {
00090 init_mutex(mutex);
00091 }
00092
00093 ~Concurrent_Node()
00094 {
00095 destroy_mutex(mutex);
00096 }
00097
00102 class Critical_Section : public UseMutex
00103 {
00104 public:
00105
00107 Critical_Section(Concurrent_Node * node)
00108 : UseMutex(node->mutex)
00109 {
00110
00111 }
00112 };
00113 };
00114
00125 template <typename Arc_Info>
00126 struct Concurrent_Arc : public Graph_Arc<Arc_Info>
00127 {
00128 typedef Graph_Arc<Arc_Info> Base_Arc;
00129
00130 typedef Arc_Info Arc_Type;
00131
00132 pthread_mutex_t mutex;
00133
00134 Concurrent_Arc(Base_Arc * arc) : Base_Arc(arc)
00135 {
00136 init_mutex(mutex);
00137 }
00138
00139 Concurrent_Arc() : Base_Arc()
00140 {
00141 init_mutex(mutex);
00142 }
00143
00144 Concurrent_Arc(void * src, void * tgt, const Arc_Info & data)
00145 : Base_Arc(src, tgt, data)
00146 {
00147 init_mutex(mutex);
00148 }
00149
00150 ~Concurrent_Arc()
00151 {
00152 destroy_mutex(mutex);
00153 }
00154
00159 class Critical_Section : public UseMutex
00160 {
00161 public:
00162
00164 Critical_Section(Concurrent_Arc * arc)
00165 : UseMutex(arc->mutex) { }
00166 };
00167 };
00168
00215 template <typename Node, typename Arc>
00216 class Concurrent_Graph : public List_Graph<Node, Arc>
00217 {
00218 protected:
00219
00220 pthread_mutex_t mutex;
00221
00222 public:
00223
00224 typedef List_Graph< Node, Arc > Base_Graph;
00225
00227 typedef typename Node::Node_Type Node_Type;
00228
00230 typedef typename Arc::Arc_Type Arc_Type;
00231
00233 Concurrent_Graph() : Base_Graph()
00234 {
00235 init_mutex(mutex);
00236 }
00237
00239 Concurrent_Graph(const Concurrent_Graph & g) : Base_Graph(g)
00240 {
00241 init_mutex(mutex);
00242 }
00243
00245 Concurrent_Graph & operator = (const Concurrent_Graph & g)
00246 {
00247 CRITICAL_SECTION(mutex);
00248
00249 if (this == &g)
00250 return *this;
00251
00252 copy_graph(*this, g);
00253
00254 return *this;
00255 }
00256
00257 virtual ~Concurrent_Graph()
00258 {
00259 destroy_mutex(mutex);
00260 }
00261
00266 class Node_Iterator
00267 {
00268 Concurrent_Graph<Node, Arc> & cg;
00269
00270 typename Base_Graph::Node_Iterator base_iterator;
00271
00272 public:
00273
00274 Node_Iterator() : base_iterator()
00275 {
00276
00277 }
00278
00280 Node_Iterator(Concurrent_Graph & _g) : cg(_g), base_iterator(_g)
00281 {
00282
00283 }
00284
00286 Node_Iterator(const Node_Iterator & it)
00287 : cg(it.cg), base_iterator(it.base_iterator)
00288 {
00289
00290 }
00291
00293 Node_Iterator & operator = (const Node_Iterator & it)
00294 {
00295 CRITICAL_SECTION(cg.mutex);
00296
00297 if (&it == this)
00298 return *this;
00299
00300 base_iterator = it.base_iterator;
00301
00302 return *this;
00303 }
00304
00306 Node * get_current_node()
00307 {
00308 CRITICAL_SECTION(cg.mutex);
00309
00310 Node * node = base_iterator.get_current_node();
00311
00312 return node;
00313 }
00314
00316 bool has_current()
00317 {
00318 CRITICAL_SECTION(cg.mutex);
00319
00320 return base_iterator.has_current();
00321 }
00322
00324 void next()
00325 {
00326 CRITICAL_SECTION(cg.mutex);
00327
00328 base_iterator.next();
00329 }
00330
00332 void prev()
00333 {
00334 CRITICAL_SECTION(cg.mutex);
00335
00336 base_iterator.prev();
00337 }
00338 };
00339
00344 class Arc_Iterator
00345 {
00346 Concurrent_Graph<Node, Arc> & cg;
00347
00348 typename Base_Graph::Arc_Iterator base_iterator;
00349
00350 public:
00351
00353 Arc_Iterator() : base_iterator()
00354 {
00355
00356 }
00357
00359 Arc_Iterator(Concurrent_Graph & _g) : cg(_g), base_iterator(_g)
00360 {
00361
00362 }
00363
00364 Arc_Iterator(const Arc_Iterator & it)
00365 : cg(it.cg), base_iterator(it.base_iterator)
00366 {
00367
00368 }
00369
00371 Arc_Iterator & operator = (const Arc_Iterator & it)
00372 {
00373 CRITICAL_SECTION(cg.mutex);
00374
00375 base_iterator = it.base_iterator;
00376
00377 return *this;
00378 }
00379
00381 Arc * get_current_arc()
00382 {
00383 CRITICAL_SECTION(cg.mutex);
00384
00385 Arc * arc = base_iterator.get_current_arc();
00386
00387 return arc;
00388 }
00389
00391 bool has_current()
00392 {
00393 CRITICAL_SECTION(cg.mutex);
00394
00395 return base_iterator.has_current();
00396 }
00397
00399 void next()
00400 {
00401 CRITICAL_SECTION(cg.mutex);
00402
00403 base_iterator.next();
00404 }
00405
00407 void prev()
00408 {
00409 CRITICAL_SECTION(cg.mutex);
00410
00411 base_iterator.prev();
00412 }
00413 };
00414
00416 size_t get_num_nodes()
00417 {
00418 CRITICAL_SECTION(mutex);
00419
00420 return Base_Graph::get_num_nodes();
00421 }
00422
00423
00424 using List_Graph<Node, Arc>::get_num_arcs;
00425
00427 size_t get_num_arcs()
00428 {
00429 CRITICAL_SECTION(mutex);
00430
00431 return Base_Graph::get_num_arcs();
00432 }
00433
00435 Node * search_node(const Node_Type & node_info)
00436 {
00437 CRITICAL_SECTION(mutex);
00438
00439 return Base_Graph::search_node(node_info);
00440 }
00441
00443 Node * insert_node(Node * node)
00444 {
00445 CRITICAL_SECTION(mutex);
00446
00447 return Base_Graph::insert_node(node);
00448 }
00449
00451 Node * insert_node(const Node_Type & node_info)
00452 {
00453 Node * ret_val = new Node(node_info);
00454
00455 return insert_node(ret_val);
00456 }
00457
00459 Node * get_first_node()
00460 {
00461 CRITICAL_SECTION(mutex);
00462
00463 return Base_Graph::get_first_node();
00464 }
00465
00467 Arc * get_first_arc()
00468 {
00469 CRITICAL_SECTION(mutex);
00470
00471 return Base_Graph::get_first_arc();
00472 }
00473
00474 void verify_graphs(Concurrent_Graph& g)
00475 {
00476 CRITICAL_SECTION(mutex);
00477
00478 Base_Graph::verify_graphs(g);
00479 }
00480
00482 void remove_node(Node * node)
00483 {
00484 CRITICAL_SECTION(mutex);
00485
00486 Base_Graph::remove_node(node);
00487 }
00488
00490 template <class Operation> void operate_on_nodes()
00491 {
00492 CRITICAL_SECTION(mutex);
00493
00494 for (typename Base_Graph::Node_Iterator itor(*this);
00495 itor.has_current(); itor.next())
00496 Operation () (*this, itor.get_current_node());
00497 }
00498
00500 template <class Operation> void operate_on_arcs()
00501 {
00502 CRITICAL_SECTION(mutex);
00503
00504 for (typename Base_Graph::Arc_Iterator itor(*this);
00505 itor.has_current(); itor.next())
00506 Operation () (*this, itor.get_current_arc());
00507 }
00508
00510 template <class Operation> void operate_on_nodes(void * ptr)
00511 {
00512 CRITICAL_SECTION(mutex);
00513
00514 for (typename Base_Graph::Node_Iterator itor(*this);
00515 itor.has_current(); itor.next())
00516 Operation () (*this, itor.get_current_node(), ptr);
00517 }
00518
00520 template <class Operation> void operate_on_arcs(void * ptr)
00521 {
00522 CRITICAL_SECTION(mutex);
00523
00524 for (typename Base_Graph::Arc_Iterator itor(*this);
00525 itor.has_current(); itor.next())
00526 Operation () (*this, itor.get_current_arc(), ptr);
00527 }
00528
00530 template <class Compare> void sort_arcs()
00531 {
00532 CRITICAL_SECTION(mutex);
00533
00534 Base_Graph::template sort_arcs<Compare> ();
00535 }
00536
00538 Arc * insert_arc(Node * src_node,
00539 Node * tgt_node,
00540 const Arc_Type & arc_info)
00541 {
00542 CRITICAL_SECTION(mutex);
00543
00544 return Base_Graph::insert_arc(src_node, tgt_node, arc_info);
00545 }
00546
00548 void remove_arc(Arc * arc)
00549 {
00550 CRITICAL_SECTION(mutex);
00551
00552 Base_Graph::remove_arc(arc);
00553 }
00554
00556 Arc * search_arc(Node * src_node, Node * tgt_node)
00557 {
00558 CRITICAL_SECTION(mutex);
00559
00560 return Base_Graph::search_arc(src_node, tgt_node);
00561 }
00562
00564 Arc * search_arc(const Arc_Type & arc_info)
00565 {
00566 CRITICAL_SECTION(mutex);
00567
00568 return Base_Graph::search_arc(arc_info);
00569 }
00570
00572 bool arc_belong_to_graph(Arc * arc)
00573 {
00574 CRITICAL_SECTION(mutex);
00575
00576 return Base_Graph::arc_belong_to_graph(arc);
00577 }
00578 };
00579
00580 }
00581
00582 # endif // TPL_CONCURRENT_GRAPH_H