1 # ifndef TPL_CONCURRENT_GRAPH_H
2 # define TPL_CONCURRENT_GRAPH_H
6 # include <autosprintf.h>
8 # include <gsl/gsl_rng.h>
9 # include <gsl/gsl_randist.h>
11 # include <tpl_graph.H>
12 # include <useMutex.H>
14 using namespace Aleph;
21 template <
template <
class,
class>
class GT,
class __Node,
class __Arc>
34 template <
class Base_Object>
39 pthread_mutex_t * mutex;
41 typedef typename Base_Object::Item_Type Object_Type;
44 : Base_Object(c_obj) , mutex(c_obj.mutex)
46 I(not c_obj.delete_mutex);
50 : Base_Object(), mutex(__mutex)
55 Lock_Object(
const Object_Type & obj_info, pthread_mutex_t * __mutex = NULL)
56 : Base_Object(obj_info), mutex(__mutex)
61 Lock_Object(Base_Object * pobj, pthread_mutex_t * __mutex = NULL)
62 : Base_Object(pobj) , mutex(__mutex)
67 void set_mutex( pthread_mutex_t * ptrm)
72 void set_mutex(pthread_mutex_t & m)
138 template <
template <
class,
class>
class __GT,
class __Node,
class __Arc>
139 class Concurrent_Graph :
public __GT<Lock_Object<__Node>, Lock_Object<__Arc> >
145 typedef typename GT::Node Node;
147 typedef typename GT::Arc Arc;
151 pthread_mutex_t mutex;
160 for (
int i = 0; i < num_mutexes; ++i)
161 init_mutex(&mutexes.
access(i));
164 void uninit_mutexes()
166 for (
int i = 0; i < num_mutexes; ++i)
167 destroy_mutex(&mutexes.
access(i));
172 pthread_mutex_t * get_mutex(
int i)
174 if (i >= num_mutexes)
175 throw std::out_of_range(gnu::autosprintf(
"mutex index %d out of range", i));
180 pthread_mutex_t * allocate_mutex()
182 init_mutex(&mutexes.
append());
184 return mutexes.
access(num_mutexes++);
207 void set_num_mutexes(
const size_t & n)
209 CRITICAL_SECTION(mutex);
212 throw std::out_of_range(
"n is equal to zero");
215 throw std::out_of_range(
"n is smaller than current number of mutexes");
219 for (
int i = num_mutexes; i < n; ++i)
220 init_mutex(&mutexes.
access(i));
225 void distribute_mutexes_randomly()
227 gsl_rng * r = gsl_rng_alloc (gsl_rng_mt19937);
228 gsl_rng_set(r, time(NULL) % gsl_rng_max(r));
233 int i = gsl_rng_uniform_int(r, num_mutexes);
234 it.get_current()->set_mutex(mutexes.
access(i));
240 int i = gsl_rng_uniform_int(r, num_mutexes);
241 it.get_current()->set_mutex(mutexes.
access(i));
247 void distribute_mutexes_uniformly()
251 const size_t num_nodes_by_mutex = num_nodes / num_mutexes;
253 typename GT::Node_Iterator it(*
this);
254 for (
int k = 0; k < num_nodes_by_mutex; ++k)
256 pthread_mutex_t & m = mutexes.
access(k);
258 for (
int i = 0; it.has_current() and i < num_nodes; ++i, it.next())
259 it.get_current()->set_mutex(m);
265 const size_t num_arcs_by_mutex = num_arcs / num_mutexes;
267 typename GT::Arc_Iterator it(*
this);
268 for (
int k = 0; k < num_arcs_by_mutex; ++k)
270 pthread_mutex_t & m = mutexes.
access(k);
272 for (
int i = 0; it.has_current() and i < num_arcs; ++i, it.next())
273 it.get_current()->set_mutex(m);
281 destroy_mutex(mutex);
292 typename GT::Node_Iterator base_iterator;
296 typedef typename GT::Node_Iterator::Item_Type Item_Type;
311 : cg(it.cg), base_iterator(it.base_iterator)
319 CRITICAL_SECTION(cg.mutex);
324 base_iterator = it.base_iterator;
332 CRITICAL_SECTION(cg.mutex);
334 Node * node = base_iterator.get_current_node();
345 CRITICAL_SECTION(cg.mutex);
346 return base_iterator.has_current();
352 CRITICAL_SECTION(cg.mutex);
353 base_iterator.next();
359 CRITICAL_SECTION(cg.mutex);
360 base_iterator.prev();
366 CRITICAL_SECTION(cg.mutex);
367 base_iterator.reset_first();
373 CRITICAL_SECTION(cg.mutex);
374 base_iterator.reset_last();
386 typename GT::Arc_Iterator base_iterator;
390 typedef typename GT::Node_Iterator::Item_Type Item_Type;
405 : cg(it.cg), base_iterator(it.base_iterator)
413 CRITICAL_SECTION(cg.mutex);
415 base_iterator = it.base_iterator;
423 CRITICAL_SECTION(cg.mutex);
425 Arc * arc = base_iterator.get_current_arc();
436 CRITICAL_SECTION(cg.mutex);
437 return base_iterator.has_current();
443 CRITICAL_SECTION(cg.mutex);
444 base_iterator.next();
450 CRITICAL_SECTION(cg.mutex);
451 base_iterator.prev();
457 CRITICAL_SECTION(cg.mutex);
458 base_iterator.reset_first();
464 CRITICAL_SECTION(cg.mutex);
465 base_iterator.reset_last();
472 CRITICAL_SECTION(mutex);
473 return GT::get_num_nodes();
482 CRITICAL_SECTION(mutex);
483 return GT::get_num_arcs();
486 size_t get_num_mutexes()
488 CRITICAL_SECTION(mutex);
495 CRITICAL_SECTION(mutex);
496 return GT::search_node(node_info);
502 CRITICAL_SECTION(mutex);
503 return GT::insert_node(node);
515 CRITICAL_SECTION(mutex);
516 return GT::get_first_node();
522 CRITICAL_SECTION(mutex);
523 return GT::get_first_arc();
528 CRITICAL_SECTION(mutex);
529 GT::verify_graphs(g);
535 CRITICAL_SECTION(mutex);
536 GT::remove_node(node);
542 CRITICAL_SECTION(mutex);
543 GT::template sort_arcs<Compare> ();
551 CRITICAL_SECTION(mutex);
552 return GT::insert_arc(src_node, tgt_node, arc_info);
559 CRITICAL_SECTION(mutex);
560 return GT::insert_arc(src_node, tgt_node);
566 CRITICAL_SECTION(mutex);
573 CRITICAL_SECTION(mutex);
580 CRITICAL_SECTION(mutex);
587 CRITICAL_SECTION(mutex);
588 return GT::arc_belong_to_graph(arc);
594 # endif // TPL_CONCURRENT_GRAPH_H
bool has_current()
Retorna true si el iterador tiene elemento actual.
Definition: tpl_concurrent_graph.H:343
void reset_first()
Reinicia el iterador al primer nodo.
Definition: tpl_concurrent_graph.H:364
void reserve(const size_t l, const size_t r)
Definition: tpl_dynArray.H:960
Node * insert_node(const Node_Type &node_info)
Crea e inserta un nuevo nodo con información node_info.
Definition: tpl_concurrent_graph.H:507
Node * insert_node(Node *node)
Inserta un nodo ya creado en un grafo.
Definition: tpl_concurrent_graph.H:500
Definition: tpl_concurrent_graph.H:22
Definition: tpl_graph.H:29
GT::Node_Type Node_Type
El tipo de nodo concurrente.
Definition: tpl_concurrent_graph.H:188
Arc * get_current_arc()
Obtiene el arco actual del iterador.
Definition: tpl_concurrent_graph.H:421
void prev()
Retrocede el iterador en una posición.
Definition: tpl_concurrent_graph.H:448
Arc_Iterator()
Instancia un iterador vacío.
Definition: tpl_concurrent_graph.H:393
Concurrent_Graph(const Concurrent_Graph &g)
Instancia un grafo concurrente copia de otro grafo concurrente.
Definition: tpl_concurrent_graph.H:201
Node * get_current()
Retorna el nodo actual.
Definition: tpl_concurrent_graph.H:340
Arc * search_arc(Node *src_node, Node *tgt_node)
Busca un arco que conecte a dos nodos.
Definition: tpl_concurrent_graph.H:571
Node * get_first_node()
Retorna el primer nodo de un grafo; no hay un orden determinado.
Definition: tpl_concurrent_graph.H:513
void remove_node(Node *node)
Elimina un nodo de un grafo (junto con todos sus arcos adyacentes).
Definition: tpl_concurrent_graph.H:533
void reset_first()
Reincia el iterador al primer arco.
Definition: tpl_concurrent_graph.H:455
Arc * insert_arc(Node *src_node, Node *tgt_node, const Arc_Type &arc_info)
Crea un arco en un grafo concurrente.
Definition: tpl_concurrent_graph.H:547
Arc_Iterator & operator=(const Arc_Iterator &it)
Instancia un iterador copia del iterador it.
Definition: tpl_concurrent_graph.H:411
Definition: tpl_concurrent_graph.H:35
void next()
Avanza el iterador en una posición.
Definition: tpl_concurrent_graph.H:441
size_t get_num_nodes()
Retorna el número de nodos que tiene el grafo concurrente.
Definition: tpl_concurrent_graph.H:470
Node * get_current_node()
Retorna el nodo actual.
Definition: tpl_concurrent_graph.H:330
void remove_arc(Arc *arc)
Elimina un arco en un grafo concurrente.
Definition: tpl_concurrent_graph.H:564
Arc_Iterator(Concurrent_Graph &_g)
Instancia un iterador sobre los arcos del grafo concurrente _g.
Definition: tpl_concurrent_graph.H:399
void reset_last()
Reincia el iterador al último arco.
Definition: tpl_concurrent_graph.H:462
bool has_current()
Retorna true si el iterador tiene arco actual.
Definition: tpl_concurrent_graph.H:434
Definition: useMutex.H:20
GT::Arc_Type Arc_Type
El tipo de arco concurrente.
Definition: tpl_concurrent_graph.H:191
Arc * search_arc(const Arc_Type &arc_info)
Busca un arco con información arc_info.
Definition: tpl_concurrent_graph.H:578
T & append()
Definition: tpl_dynArray.H:1115
Definition: tpl_concurrent_graph.H:382
bool arc_belong_to_graph(Arc *arc)
Retorna true si el arco arc pertenece al grafo.
Definition: tpl_concurrent_graph.H:585
void sort_arcs()
ordena los arcos de un grafo concurrente según criterio Compare.
Definition: tpl_concurrent_graph.H:540
Critical_Section(Lock_Object *node)
Toma sección crítica del nodo node. Se libera en destrucción.
Definition: tpl_concurrent_graph.H:86
Arc * get_first_arc()
Retorna el primer arco de un grafo.
Definition: tpl_concurrent_graph.H:520
size_t get_num_arcs()
Retorna el número de arcos que tiene el grafo concurrente.
Definition: tpl_concurrent_graph.H:480
Definition: tpl_concurrent_graph.H:81
void prev()
Retrocede el iterador en una posición.
Definition: tpl_concurrent_graph.H:357
GT::Arc * search_arc(GT &g, typename GT::Node *src_node, typename GT::Node *tgt_node)
Definition: tpl_graph.H:2461
Definition: tpl_concurrent_graph.H:288
T & access(const size_t i)
Definition: tpl_dynArray.H:793
Concurrent_Graph(const size_t &n_mut=1)
Instancia un grafo concurrente vacío.
Definition: tpl_concurrent_graph.H:194
Arc * insert_arc(Node *src_node, Node *tgt_node)
Crea un arco en un grafo concurrente.
Definition: tpl_concurrent_graph.H:556
Node_Iterator & operator=(const Node_Iterator &it)
Asigna iterador.
Definition: tpl_concurrent_graph.H:317
Arc * get_current()
Obtiene el arco actual del iterador.
Definition: tpl_concurrent_graph.H:431
Node_Iterator(const Node_Iterator &it)
Instancia un iterador copia del iterador it.
Definition: tpl_concurrent_graph.H:310
Node_Iterator(Concurrent_Graph &_g)
instancia un iterador sobre el grafo _g.
Definition: tpl_concurrent_graph.H:304
void reset_last()
Reinicia el iterador al último nodo.
Definition: tpl_concurrent_graph.H:371
Node * search_node(const Node_Type &node_info)
Busca un nodo según su información contenida.
Definition: tpl_concurrent_graph.H:493
void next()
Avanza el iterador en una posición.
Definition: tpl_concurrent_graph.H:350