X-Git-Url: http://info.iut-bm.univ-fcomte.fr/pub/gitweb/simgrid.git/blobdiff_plain/693ba4212f01cdcc236bc94bfb2a0fbcbb6a3379..05c280c2e4f419cbeeb3d3d6456d991a70f1edcc:/src/xbt/graph.c diff --git a/src/xbt/graph.c b/src/xbt/graph.c index b946ef8511..004c9fbe37 100644 --- a/src/xbt/graph.c +++ b/src/xbt/graph.c @@ -1,9 +1,7 @@ -/* $Id$ */ - /* a generic graph library. */ -/* Copyright (c) 2006 Darina Dimitrova, Arnaud Legrand. - All rights reserved. */ +/* Copyright (c) 2006-2019. The SimGrid Team. + * All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ @@ -11,182 +9,172 @@ #include "xbt/sysdep.h" #include "xbt/log.h" #include "xbt/graph.h" -#include "graph_private.h" -#include "xbt/graphxml_parse.h" +#include "xbt/dict.h" + +#include +#include +#include -XBT_LOG_NEW_DEFAULT_SUBCATEGORY(graph,xbt,"Graph"); +XBT_LOG_NEW_DEFAULT_SUBCATEGORY(xbt_graph, xbt, "Graph"); -/** Constructor - * \return a new graph +/** @brief Constructor + * @return a new graph */ xbt_graph_t xbt_graph_new_graph(unsigned short int directed, void *data) { - xbt_graph_t graph=NULL; - graph=xbt_new0(struct xbt_graph,1); - graph->directed=directed; - graph->data=data; - graph->nodes= xbt_dynar_new(sizeof(xbt_node_t), free); - graph->edges= xbt_dynar_new(sizeof(xbt_edge_t), free); + xbt_graph_t graph = xbt_new0(struct xbt_graph, 1); + graph->directed = directed; + graph->data = data; + graph->nodes = xbt_dynar_new(sizeof(xbt_node_t), NULL); + graph->edges = xbt_dynar_new(sizeof(xbt_edge_t), NULL); return graph; } +/** @brief add a node to the given graph */ 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_node_t), free); - node->out=xbt_dynar_new(sizeof(xbt_node_t), free); - xbt_dynar_push(g->nodes,node); + xbt_node_t node= xbt_new0(struct xbt_node, 1); + node->data = data; + if (g->directed) + /* only the "out" field is used */ + node->in = xbt_dynar_new(sizeof(xbt_edge_t), NULL); - return node; -} + node->out = xbt_dynar_new(sizeof(xbt_edge_t), NULL); + node->position_x = -1.0; + node->position_y = -1.0; + xbt_dynar_push(g->nodes, &node); -xbt_edge_t xbt_graph_new_edge(xbt_graph_t g, - xbt_node_t src, xbt_node_t dst, void *data) -{ - xbt_edge_t edge=NULL; - - edge=xbt_new0(struct xbt_edge,1); - xbt_dynar_push(src->out,edge); - xbt_dynar_push(dst->in,edge); - 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; + return node; } - -/** Destructor - * \param l poor victim - * - * 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)) +/** @brief add an edge to the given graph */ +xbt_edge_t xbt_graph_new_edge(xbt_graph_t g, xbt_node_t src, xbt_node_t dst, void *data) { - int cursor; - xbt_node_t node=NULL; - xbt_edge_t edge=NULL; - - xbt_dynar_foreach(g->nodes,cursor,node) - xbt_graph_remove_node(g,node,node_free_function); + xbt_edge_t edge = xbt_new0(struct xbt_edge, 1); + xbt_dynar_push(src->out, &edge); + if (g->directed) + xbt_dynar_push(dst->in, &edge); + else /* only the "out" field is used */ + xbt_dynar_push(dst->out, &edge); - xbt_assert0(!xbt_dynar_length(g->edges), - "Damnit, there are some remaining edges!"); + edge->data = data; + edge->src = src; + edge->dst = dst; - xbt_dynar_foreach(g->edges,cursor,edge) - xbt_graph_remove_edge(g,edge,edge_free_function); + xbt_dynar_push(g->edges, &edge); - xbt_dynar_free(&(g->nodes)); - xbt_dynar_free(&(g->edges)); - -/* void xbt_dynar_free(g->edges); */ - - - return; + return edge; } -void xbt_graph_remove_node(xbt_graph_t g, xbt_node_t n, void free_function(void * ptr)) +/** @brief Get the edge connecting src and dst */ +xbt_edge_t xbt_graph_get_edge(xbt_graph_t g, xbt_node_t src, xbt_node_t dst) { - int cursor; - xbt_node_t node=NULL; - - if ((free_function)&&(n->data)) - free_function(n->data); - xbt_dynar_free_container(&(n->in)); - xbt_dynar_free_container(&(n->out)); - xbt_dynar_foreach(g->nodes,cursor,node) - { - if (node==n) - xbt_dynar_cursor_rm(g->nodes,&cursor); - + xbt_edge_t edge; + unsigned int cursor; + + xbt_dynar_foreach(src->out, cursor, edge) { + XBT_DEBUG("%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) { + XBT_DEBUG("%p = %p--%p", edge, edge->src, edge->dst); + if ((edge->dst == src) && (edge->src == dst)) + return edge; } - return; - + } + return NULL; } -void xbt_graph_remove_edge(xbt_graph_t g, xbt_edge_t e, void free_function(void * ptr)) + +/** @brief Get the user data associated to a node */ +void *xbt_graph_node_get_data(xbt_node_t node) { - int cursor=0; - xbt_edge_t edge=NULL; - xbt_node_t node=NULL; - xbt_node_t temp=NULL; - - if ((free_function)&&(e->data)) - free_function(e->data); - xbt_dynar_foreach(g->nodes,cursor,node) - { - if (node==e->src) - xbt_dynar_pop(node->out,temp); - if (g->directed) - xbt_dynar_pop(node->in,temp); - - } - node=NULL; - cursor=0; - xbt_dynar_foreach(g->nodes,cursor,node) - { - if (node==e->dst) - xbt_dynar_pop(node->in,temp); - if (g->directed) - xbt_dynar_pop(node->out,temp); - - } - cursor=0; - xbt_dynar_foreach(g->edges,cursor,edge) - if (edge==e) - { - xbt_dynar_cursor_rm(g->edges,&cursor); - break; - } - + return node->data; } -static xbt_graph_t parsed_graph=NULL; - -static void __parse_graph_begin(void) { - DEBUG0(""); +/** @brief Set the user data associated to a node */ +void xbt_graph_node_set_data(xbt_node_t node, void *data) +{ + node->data = data; } -static void __parse_graph_end(void) { - DEBUG0(""); + +/** @brief Get the user data associated to a edge */ +void *xbt_graph_edge_get_data(xbt_edge_t edge) +{ + return edge->data; } -static void __parse_node(void) { - DEBUG1("",A_graphxml_node_name); + +/** @brief Set the user data associated to a edge */ +void xbt_graph_edge_set_data(xbt_edge_t edge, void *data) +{ + edge->data = data; } -static void __parse_edge(void) { - DEBUG2("",A_graphxml_edge_source, - A_graphxml_edge_target); + +/** @brief Destructor + * @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_f_pvoid_t node_free_function, void_f_pvoid_t edge_free_function, + void_f_pvoid_t graph_free_function) +{ + unsigned int cursor; + xbt_node_t node; + xbt_edge_t edge; + + xbt_dynar_foreach(g->edges, cursor, edge) { + if (edge_free_function) + edge_free_function(edge->data); + free(edge); + } + xbt_dynar_free(&(g->edges)); + + xbt_dynar_foreach(g->nodes, cursor, node) { + xbt_dynar_free(&(node->out)); + xbt_dynar_free(&(node->in)); + if (node_free_function) + node_free_function(node->data); + free(node); + } + xbt_dynar_free(&(g->nodes)); + + if (graph_free_function) + graph_free_function(g->data); + free(g); } -xbt_graph_t xbt_graph_read(const char *filename) +/** @brief Retrieve the graph's nodes as a dynar */ +xbt_dynar_t xbt_graph_get_nodes(xbt_graph_t g) { - xbt_graph_t graph = xbt_graph_new_graph(1,NULL); + return g->nodes; +} - parsed_graph = graph; +/** @brief Retrieve the graph's edges as a dynar */ +xbt_dynar_t xbt_graph_get_edges(xbt_graph_t g) +{ + return g->edges; +} - xbt_graph_parse_reset_parser(); - - STag_graphxml_graph_fun = __parse_graph_begin; - ETag_graphxml_graph_fun = __parse_graph_end; - ETag_graphxml_node_fun = __parse_node; - ETag_graphxml_edge_fun = __parse_edge; +/** @brief Retrieve the node at the source of the given edge */ +xbt_node_t xbt_graph_edge_get_source(xbt_edge_t e) +{ + return e->src; +} - xbt_graph_parse_open(filename); - xbt_assert1((!xbt_graph_parse()),"Parse error in %s",filename); - xbt_graph_parse_close(); +/** @brief Retrieve the node being the target of the given edge */ +xbt_node_t xbt_graph_edge_get_target(xbt_edge_t e) +{ + return e->dst; +} - parsed_graph = NULL; - - return graph; +/** @brief Retrieve the outgoing edges of the given node */ +xbt_dynar_t xbt_graph_node_get_outedges(xbt_node_t n) +{ + return n->out; }