From 60e20b502e4bff6aa6c54531e340706f58067079 Mon Sep 17 00:00:00 2001 From: Rusty Russell Date: Wed, 28 Feb 2018 06:29:48 +1030 Subject: [PATCH] gossipd: simplify pruning code. If we make destroy_node() remove itself from the map, then we simply need to free it. We can batch the frees (as we need) simply by reparenting all the pruned nodes onto a single temporary parent, then freeing it, relying on tal's internal datastructures. Signed-off-by: Rusty Russell --- gossipd/gossip.c | 18 +++++------------- gossipd/routing.c | 6 ++++-- 2 files changed, 9 insertions(+), 15 deletions(-) diff --git a/gossipd/gossip.c b/gossipd/gossip.c index 990507112..8d9e70847 100644 --- a/gossipd/gossip.c +++ b/gossipd/gossip.c @@ -1303,7 +1303,7 @@ static void gossip_prune_network(struct daemon *daemon) /* Anything below this highwater mark ought to be pruned */ s64 highwater = now - 2*daemon->update_channel_interval; struct node *n; - struct node **prunednodes; + const tal_t *pruned = tal_tmpctx(daemon); /* Schedule next run now */ new_reltimer(&daemon->timers, daemon, @@ -1367,24 +1367,16 @@ static void gossip_prune_network(struct daemon *daemon) } /* Finally remove all nodes that do not have any edges - * anymore. Accumulate into prunednodes, and delete in the - * second loop. */ - prunednodes = tal_arr(n, struct node*, 0); + * anymore. Reparent onto pruned, then free them all. */ for (n = node_map_first(daemon->rstate->nodes, &it); n; n = node_map_next(daemon->rstate->nodes, &it)) { if (tal_count(n->in) == 0 && tal_count(n->out) == 0) { - size_t count = tal_count(prunednodes); - tal_resize(&prunednodes, count + 1); - prunednodes[count] = n; + tal_steal(pruned, n); } } - for (size_t i=0; irstate->nodes, prunednodes[i]); - tal_free(prunednodes[i]); - } - - tal_free(prunednodes); + /* This frees all the nodes. */ + tal_free(pruned); } static struct io_plan *connection_in(struct io_conn *conn, struct daemon *daemon) diff --git a/gossipd/routing.c b/gossipd/routing.c index e5139d5c7..a80d9bf9a 100644 --- a/gossipd/routing.c +++ b/gossipd/routing.c @@ -123,8 +123,10 @@ bool node_map_node_eq(const struct node *n, const secp256k1_pubkey *key) return structeq(&n->id.pubkey, key); } -static void destroy_node(struct node *node) +static void destroy_node(struct node *node, struct routing_state *rstate) { + node_map_del(rstate->nodes, node); + /* These remove themselves from the array. */ while (tal_count(node->in)) tal_free(node->in[0]); @@ -155,7 +157,7 @@ static struct node *new_node(struct routing_state *rstate, n->last_timestamp = -1; n->addresses = tal_arr(n, struct wireaddr, 0); node_map_add(rstate->nodes, n); - tal_add_destructor(n, destroy_node); + tal_add_destructor2(n, destroy_node, rstate); return n; }