Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
Adding a XML graph parser
[simgrid.git] / src / xbt / graph.c
1 /*      $Id$     */
2
3 /* a generic graph library.                                                 */
4
5 /* Copyright (c) 2006 Darina Dimitrova, Arnaud Legrand. 
6    All rights reserved.                  */
7
8 /* This program is free software; you can redistribute it and/or modify it
9  * under the terms of the license (GNU LGPL) which comes with this package. */
10
11 #include "xbt/sysdep.h"
12 #include "xbt/log.h"
13 #include "xbt/graph.h"
14 #include "graph_private.h"
15
16 /* XBT_LOG_NEW_DEFAULT_SUBCATEGORY(graph,xbt,"Graph"); */
17
18 /** Constructor
19  * \return a new graph
20  */
21 xbt_graph_t xbt_graph_new_graph(const char *name, unsigned short int directed,
22                                void *data)
23 {
24   xbt_graph_t graph=NULL;
25   graph=xbt_new0(struct xbt_graph,1);
26   graph->directed=directed;
27   graph->data=data;
28   graph->nodes= xbt_dynar_new(sizeof(xbt_node_t), free);
29   graph->edges= xbt_dynar_new(sizeof(xbt_edge_t), free);
30
31   return graph;
32 }
33
34 xbt_node_t xbt_graph_new_node(xbt_graph_t g,const char *name, void *data)
35 {
36   xbt_node_t node=NULL;
37   node=xbt_new0(struct xbt_node,1);
38   node->data=data;
39   node->in=xbt_dynar_new(sizeof(xbt_node_t), free);
40   node->out=xbt_dynar_new(sizeof(xbt_node_t), free);
41   xbt_dynar_push(g->nodes,node);  
42
43   return node;
44 }
45
46
47 xbt_edge_t xbt_graph_new_edge(xbt_graph_t g,const char *name,
48                              xbt_node_t src, xbt_node_t dst, void *data)
49 {
50   xbt_edge_t edge=NULL;
51
52   edge=xbt_new0(struct xbt_edge,1);
53   xbt_dynar_push(src->out,edge); 
54   xbt_dynar_push(dst->in,edge); 
55   edge->data=data;
56   edge->src=src;
57   edge->dst=dst;
58   if(!g->directed) 
59    {
60      xbt_dynar_push(src->in,edge); 
61      xbt_dynar_push(dst->out,edge); 
62    }
63  xbt_dynar_push(g->edges,edge);
64
65  return edge; 
66 }
67
68
69 /** Destructor
70  * \param l poor victim
71  *
72  * Free the graph structure. 
73  */
74 void xbt_graph_free_graph(xbt_graph_t g,
75                           void node_free_function(void * ptr),
76                           void edge_free_function(void * ptr),
77                           void graph_free_function(void * ptr))
78 {
79   int cursor; 
80   xbt_node_t node=NULL;
81   xbt_edge_t edge=NULL; 
82
83   xbt_dynar_foreach(g->nodes,cursor,node)
84     xbt_graph_remove_node(g,node,node_free_function);
85
86   xbt_assert0(!xbt_dynar_length(g->edges),
87               "Damnit, there are some remaining edges!");
88
89   xbt_dynar_foreach(g->edges,cursor,edge)
90       xbt_graph_remove_edge(g,edge,edge_free_function); 
91
92   xbt_dynar_free(&(g->nodes));
93   xbt_dynar_free(&(g->edges));
94       
95 /*  void xbt_dynar_free(g->edges); */
96
97
98   return;
99 }
100
101 void xbt_graph_remove_node(xbt_graph_t g, xbt_node_t n, void free_function(void * ptr))
102 {
103   int cursor; 
104   xbt_node_t node=NULL;
105
106   if ((free_function)&&(n->data))
107    free_function(n->data);
108   xbt_dynar_free_container(&(n->in));
109   xbt_dynar_free_container(&(n->out));
110   xbt_dynar_foreach(g->nodes,cursor,node)
111     {
112       if (node==n)
113         xbt_dynar_cursor_rm(g->nodes,&cursor);   
114       
115     }
116   return;
117    
118 }
119 void xbt_graph_remove_edge(xbt_graph_t g, xbt_edge_t e, void free_function(void * ptr))
120 {
121    int cursor=0; 
122    xbt_edge_t edge=NULL;
123    xbt_node_t node=NULL;
124    xbt_node_t temp=NULL;
125    
126    if ((free_function)&&(e->data))
127      free_function(e->data);
128    xbt_dynar_foreach(g->nodes,cursor,node)
129      {
130        if (node==e->src)
131          xbt_dynar_pop(node->out,temp);
132        if (g->directed)
133          xbt_dynar_pop(node->in,temp);
134         
135      }
136    node=NULL;
137    cursor=0;
138    xbt_dynar_foreach(g->nodes,cursor,node)
139      {
140         if (node==e->dst)
141           xbt_dynar_pop(node->in,temp);
142         if (g->directed)
143           xbt_dynar_pop(node->out,temp);
144         
145      }
146    cursor=0;
147    xbt_dynar_foreach(g->edges,cursor,edge)
148      if (edge==e) 
149        {
150          xbt_dynar_cursor_rm(g->edges,&cursor);
151          break;
152        }
153    
154 }