Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
Fix a god damn race condition: make sure nobody changes the dynar->used value before...
[simgrid.git] / src / xbt / graph.c
index 536dcbb..464dad4 100644 (file)
@@ -20,7 +20,7 @@
 
 
 
-XBT_LOG_NEW_DEFAULT_SUBCATEGORY(graph, xbt, "Graph");
+XBT_LOG_NEW_DEFAULT_SUBCATEGORY(xbt_graph, xbt, "Graph");
 
 
 
@@ -45,7 +45,10 @@ xbt_node_t xbt_graph_new_node(xbt_graph_t g, void *data)
   xbt_node_t node = NULL;
   node = xbt_new0(struct xbt_node, 1);
   node->data = data;
-  node->in = xbt_dynar_new(sizeof(xbt_edge_t), NULL);
+  if (g->directed)
+    /* only the "out" field is used */
+    node->in = xbt_dynar_new(sizeof(xbt_edge_t), NULL);
+
   node->out = xbt_dynar_new(sizeof(xbt_edge_t), NULL);
   node->position_x = -1.0;
   node->position_y = -1.0;
@@ -61,7 +64,6 @@ xbt_edge_t xbt_graph_new_edge(xbt_graph_t g,
 {
   xbt_edge_t edge = NULL;
 
-
   edge = xbt_new0(struct xbt_edge, 1);
   xbt_dynar_push(src->out, &edge);
   if (g->directed)
@@ -72,38 +74,64 @@ xbt_edge_t xbt_graph_new_edge(xbt_graph_t g,
   edge->data = data;
   edge->src = src;
   edge->dst = dst;
-  if (!g->directed) {
-    xbt_dynar_push(src->in, &edge);
-    xbt_dynar_push(dst->out, &edge);
-  }
-
 
   xbt_dynar_push(g->edges, &edge);
 
   return edge;
 }
 
+xbt_edge_t xbt_graph_get_edge(xbt_graph_t g, xbt_node_t src, xbt_node_t dst)
+{
+  xbt_edge_t edge;
+  unsigned int cursor;
+
+  xbt_dynar_foreach(src->out, cursor, edge) {
+    DEBUG3("%p = %p--%p",edge,edge->src,edge->dst);
+    if((edge->src==src) && (edge->dst==dst)) return edge;
+  }
+  if(!g->directed) {
+    xbt_dynar_foreach(src->out, cursor, edge) {
+      DEBUG3("%p = %p--%p",edge,edge->src,edge->dst);
+      if((edge->dst==src) && (edge->src==dst)) return edge;
+    }
+  }
+  return NULL;
+}
+
 void *xbt_graph_node_get_data(xbt_node_t node)
 {
   return node->data;
 }
 
+void xbt_graph_node_set_data(xbt_node_t node, void *data)
+{
+  node->data = data;
+}
+
 void *xbt_graph_edge_get_data(xbt_edge_t edge)
 {
   return edge->data;
 }
 
+void xbt_graph_edge_set_data(xbt_edge_t edge, void *data)
+{
+  edge->data = data;
+}
+
 /** @brief Destructor
- *  @param l: poor victim
+ *  @param g: poor victim
+ *  @param node_free_function: function to use to free data associated to each node
+ *  @param edge_free_function: function to use to free data associated to each edge
+ *  @param graph_free_function: function to use to free data associated to g
  *
  * Free the graph structure. 
  */
 void xbt_graph_free_graph(xbt_graph_t g,
-                         void node_free_function(void *ptr),
-                         void edge_free_function(void *ptr),
-                         void graph_free_function(void *ptr))
+                         void_f_pvoid_t node_free_function,
+                         void_f_pvoid_t edge_free_function,
+                         void_f_pvoid_t graph_free_function)
 {
-  int cursor = 0;
+  unsigned int cursor = 0;
   xbt_node_t node = NULL;
   xbt_edge_t edge = NULL;
 
@@ -112,12 +140,12 @@ void xbt_graph_free_graph(xbt_graph_t g,
     xbt_dynar_free(&(node->out));
     xbt_dynar_free(&(node->in));
     if (node_free_function)
-      node_free_function(node->data);
+      (*node_free_function)(node->data);
   }
 
   xbt_dynar_foreach(g->edges, cursor, edge) {
     if (edge_free_function)
-      edge_free_function(edge->data);
+      (*edge_free_function)(edge->data);
   }
 
   xbt_dynar_foreach(g->nodes, cursor, node)
@@ -127,7 +155,8 @@ void xbt_graph_free_graph(xbt_graph_t g,
   xbt_dynar_foreach(g->edges, cursor, edge)
       free(edge);
   xbt_dynar_free(&(g->edges));
-
+  if(graph_free_function) 
+     (*graph_free_function)(g->data);
   free(g);
 
   return;
@@ -136,28 +165,28 @@ void xbt_graph_free_graph(xbt_graph_t g,
 
 /** @brief remove the given node from the given graph */
 void xbt_graph_free_node(xbt_graph_t g, xbt_node_t n,
-                        void_f_pvoid_t node_free_function,
-                        void_f_pvoid_t edge_free_function)
+                        void_f_pvoid_t node_free_function,
+                        void_f_pvoid_t edge_free_function)
 {
   unsigned long nbr;
-  int i;
-  int cursor = 0;
+  unsigned long i;
+  unsigned int cursor = 0;
   xbt_node_t node = NULL;
   xbt_edge_t edge = NULL;
 
   nbr = xbt_dynar_length(g->edges);
   cursor = 0;
   for (i = 0; i < nbr; i++) {
-    xbt_dynar_cursor_get(g->edges, &cursor, &edge);
+    xbt_dynar_get_cpy(g->edges, cursor, &edge);
 
     if ((edge->dst == n) || (edge->src == n)) {
       xbt_graph_free_edge(g, edge, edge_free_function);
     } else
-      xbt_dynar_cursor_step(g->edges, &cursor);
+      cursor ++;
   }
 
   if ((node_free_function) && (n->data))
-    node_free_function(n->data);
+    (*node_free_function)(n->data);
 
   cursor = 0;
   xbt_dynar_foreach(g->nodes, cursor, node)
@@ -174,14 +203,14 @@ void xbt_graph_free_node(xbt_graph_t g, xbt_node_t n,
 
 /** @brief remove the given edge from the given graph */
 void xbt_graph_free_edge(xbt_graph_t g, xbt_edge_t e,
-                        void free_function(void *ptr))
+                        void_f_pvoid_t free_function)
 {
   int idx;
-  int cursor = 0;
+  unsigned int cursor = 0;
   xbt_edge_t edge = NULL;
 
   if ((free_function) && (e->data))
-    free_function(e->data);
+    (*free_function)(e->data);
 
   xbt_dynar_foreach(g->edges, cursor, edge) {
     if (edge == e) {
@@ -206,7 +235,7 @@ void xbt_graph_free_edge(xbt_graph_t g, xbt_edge_t e,
 int __xbt_find_in_dynar(xbt_dynar_t dynar, void *p)
 {
 
-  int cursor = 0;
+  unsigned int cursor = 0;
   void *tmp = NULL;
 
   xbt_dynar_foreach(dynar, cursor, tmp) {
@@ -261,9 +290,9 @@ double xbt_graph_edge_get_length(xbt_edge_t e)
  */
 double *xbt_graph_get_length_matrix(xbt_graph_t g)
 {
-  int cursor = 0;
-  int in_cursor = 0;
-  int idx, i;
+  unsigned int cursor = 0;
+  unsigned int in_cursor = 0;
+  unsigned long idx, i;
   unsigned long n;
   xbt_edge_t edge = NULL;
   xbt_node_t node = NULL;
@@ -311,7 +340,7 @@ double *xbt_graph_get_length_matrix(xbt_graph_t g)
 void xbt_floyd_algorithm(xbt_graph_t g, double *adj, double *d,
                         xbt_node_t * p)
 {
-  int i, j, k;
+  unsigned long i, j, k;
   unsigned long n;
   n = xbt_dynar_length(g->nodes);
 
@@ -355,7 +384,7 @@ xbt_node_t *xbt_graph_shortest_paths(xbt_graph_t g)
 {
   xbt_node_t *p;
   xbt_node_t *r;
-  int i, j, k;
+  unsigned long i, j, k;
   unsigned long n;
 
   double *adj = NULL;
@@ -404,7 +433,7 @@ xbt_edge_t *xbt_graph_spanning_tree_prim(xbt_graph_t g)
   xbt_node_t node = NULL;
   xbt_dynar_t edge_list = NULL;
   xbt_heap_t heap = xbt_heap_new(10, NULL);
-  int cursor;
+  unsigned int cursor;
 
   xbt_assert0(!(g->directed),
              "Spanning trees do not make sense on directed graphs");
@@ -460,7 +489,8 @@ xbt_node_t *xbt_graph_topo_sort(xbt_graph_t g)
 {
 
   xbt_node_t *sorted;
-  int cursor, idx;
+  unsigned int cursor;
+  int idx;
   xbt_node_t node;
   unsigned long n;
 
@@ -487,7 +517,7 @@ xbt_node_t *xbt_graph_topo_sort(xbt_graph_t g)
 void xbt_graph_depth_visit(xbt_graph_t g, xbt_node_t n,
                           xbt_node_t * sorted, int *idx)
 {
-  int cursor;
+  unsigned int cursor;
   xbt_edge_t edge;
 
   if (*((int *) (n->xbtdata)) == ALREADY_EXPLORED)
@@ -570,10 +600,10 @@ static void __parse_edge(void)
 
 /** @brief Import a graph from a file following the GraphXML format */
 xbt_graph_t xbt_graph_read(const char *filename,
-                          void *(node_label_and_data) (xbt_node_t,
+                          void *(*node_label_and_data) (xbt_node_t,
                                                        const char *,
                                                        const char *),
-                          void *(edge_label_and_data) (xbt_edge_t,
+                          void *(*edge_label_and_data) (xbt_edge_t,
                                                        const char *,
                                                        const char *))
 {
@@ -591,7 +621,7 @@ xbt_graph_t xbt_graph_read(const char *filename,
   ETag_graphxml_edge_fun = __parse_edge;
 
   xbt_graph_parse_open(filename);
-  xbt_assert1((!xbt_graph_parse()), "Parse error in %s", filename);
+  xbt_assert1((!(*xbt_graph_parse)()), "Parse error in %s", filename);
   xbt_graph_parse_close();
 
   graph = parsed_graph;
@@ -605,7 +635,7 @@ void xbt_graph_export_graphviz(xbt_graph_t g, const char *filename,
                               const char *(node_name) (xbt_node_t),
                               const char *(edge_name) (xbt_edge_t))
 {
-  int cursor = 0;
+  unsigned int cursor = 0;
   xbt_node_t node = NULL;
   xbt_edge_t edge = NULL;
   FILE *file = NULL;
@@ -651,7 +681,7 @@ void xbt_graph_export_graphxml(xbt_graph_t g, const char *filename,
                               const char *(node_data_print) (void *),
                               const char *(edge_data_print) (void *))
 {
-  int cursor = 0;
+  unsigned int cursor = 0;
   xbt_node_t node = NULL;
   xbt_edge_t edge = NULL;
   FILE *file = NULL;