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 <rusty@rustcorp.com.au>
This commit is contained in:
Rusty Russell 2018-02-28 06:29:48 +10:30 committed by Christian Decker
parent 792feb8532
commit 60e20b502e
2 changed files with 9 additions and 15 deletions

View File

@ -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; i<tal_count(prunednodes); i++) {
node_map_del(daemon->rstate->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)

View File

@ -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;
}