diff options
author | David Lamparter <equinox@opensourcerouting.org> | 2017-01-26 06:56:48 +0100 |
---|---|---|
committer | David Lamparter <equinox@opensourcerouting.org> | 2017-01-26 07:05:56 +0100 |
commit | 5bf313994d01bc05f0fe90fdb69322812c399440 (patch) | |
tree | 36ba2fb8c91fdf8f1b6a4fa7ad16993f1879a891 /lib/graph.c | |
parent | lib: graph: fix deletions (diff) | |
download | frr-5bf313994d01bc05f0fe90fdb69322812c399440.tar.xz frr-5bf313994d01bc05f0fe90fdb69322812c399440.zip |
lib: graph: speed up node deletion
We don't need to copy the from/to arrays, we can just iterate backwards.
NB: this makes graph_remove_edge delete only one edge (which is more
consistent with graph_add_edge allowing parallel edges).
Iterating graph->nodes backwards also makes graph_delete_graph faster
since that also iterates backwards.
Signed-off-by: David Lamparter <equinox@opensourcerouting.org>
Diffstat (limited to 'lib/graph.c')
-rw-r--r-- | lib/graph.c | 29 |
1 files changed, 17 insertions, 12 deletions
diff --git a/lib/graph.c b/lib/graph.c index 035e552d0..9ca0a3152 100644 --- a/lib/graph.c +++ b/lib/graph.c @@ -71,22 +71,18 @@ graph_delete_node (struct graph *graph, struct graph_node *node) struct graph_node *adj; // remove all edges from other nodes to us - vector edges = vector_copy (node->from); - for (unsigned int i = 0; i < vector_active (edges); i++) + for (unsigned int i = vector_active (node->from); i--; /**/) { - adj = vector_slot (edges, i); + adj = vector_slot (node->from, i); graph_remove_edge (adj, node); } - vector_free (edges); // remove all edges from us to other nodes - edges = vector_copy (node->to); - for (unsigned int i = 0; i < vector_active (edges); i++) + for (unsigned int i = vector_active (node->to); i--; /**/) { - adj = vector_slot (edges, i); + adj = vector_slot (node->to, i); graph_remove_edge (node, adj); } - vector_free (edges); // if there is a deletion callback, call it if (node->del && node->data) @@ -97,9 +93,12 @@ graph_delete_node (struct graph *graph, struct graph_node *node) vector_free (node->from); // remove node from graph->nodes - for (unsigned int i = 0; i < vector_active (graph->nodes); i++) + for (unsigned int i = vector_active (graph->nodes); i--; /**/) if (vector_slot (graph->nodes, i) == node) - vector_remove (graph->nodes, i); + { + vector_remove (graph->nodes, i); + break; + } // free the node itself XFREE (MTYPE_GRAPH_NODE, node); @@ -119,11 +118,17 @@ graph_remove_edge (struct graph_node *from, struct graph_node *to) // remove from from to->from for (unsigned int i = vector_active (to->from); i--; /**/) if (vector_slot (to->from, i) == from) - vector_remove (to->from, i); + { + vector_remove (to->from, i); + break; + } // remove to from from->to for (unsigned int i = vector_active (from->to); i--; /**/) if (vector_slot (from->to, i) == to) - vector_remove (from->to, i); + { + vector_remove (from->to, i); + break; + } } void |