tpl_concurrent_graph.H

00001 
00002 /*
00003   This file is part of Aleph system
00004 
00005   Copyright (c) 2002, 2003, 2004, 2005, 2006
00006   UNIVERSITY LOS ANDES (ULA) Merida - REPÚBLICA BOLIVARIANA DE VENEZUELA  
00007 
00008   - Center of Studies in Microelectronics & Distributed Systems (CEMISID) 
00009   - ULA Computer Science Department
00010   - FUNDACITE Mérida - Ministerio de Ciencia y Tecnología
00011 
00012   PERMISSION TO USE, COPY, MODIFY AND DISTRIBUTE THIS SOFTWARE AND ITS
00013   DOCUMENTATION IS HEREBY GRANTED, PROVIDED THAT BOTH THE COPYRIGHT
00014   NOTICE AND THIS PERMISSION NOTICE APPEAR IN ALL COPIES OF THE
00015   SOFTWARE, DERIVATIVE WORKS OR MODIFIED VERSIONS, AND ANY PORTIONS
00016   THEREOF, AND THAT BOTH NOTICES APPEAR IN SUPPORTING DOCUMENTATION.
00017 
00018   Aleph is distributed in the hope that it will be useful, but WITHOUT
00019   ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
00020   or FITNESS FOR A PARTICULAR PURPOSE.
00021 
00022   UNIVERSIDAD DE LOS ANDES requests users of this software to return to 
00023 
00024   Leandro Leon
00025   CEMISID 
00026   Ed La Hechicera 
00027   3er piso, ala sur
00028   Facultad de Ingenieria 
00029   Universidad de Los Andes 
00030   Merida - REPÚBLICA BOLIVARIANA DE VENEZUELA    or
00031 
00032   lrleon@ula.ve
00033 
00034   any improvements or extensions that they make and grant Universidad 
00035   de Los Andes (ULA) the rights to redistribute these changes. 
00036 
00037   Aleph is (or was) granted by: 
00038   - Consejo de Desarrollo Cientifico, Humanistico, Tecnico de la ULA 
00039     (CDCHT)
00040   - Fundacite Mérida
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; // protege toda la data asociada al nodo
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       /* empty */ 
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) { /* empty */ }
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       // empty
00277     }
00278 
00280     Node_Iterator(Concurrent_Graph & _g) : cg(_g), base_iterator(_g)
00281     {
00282       // empty
00283     }
00284 
00286     Node_Iterator(const Node_Iterator & it) 
00287       : cg(it.cg), base_iterator(it.base_iterator)
00288     {
00289       // empty
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       // empty
00356     }
00357 
00359     Arc_Iterator(Concurrent_Graph & _g) : cg(_g), base_iterator(_g)
00360     {
00361       // empty
00362     }
00363 
00364     Arc_Iterator(const Arc_Iterator & it) 
00365       : cg(it.cg), base_iterator(it.base_iterator)
00366     {
00367       // empty
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       // Hace visible get_num_arcs(Node*) heredada de List_Graph
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

Leandro R. León