2021-12-04 12:23:56 +01:00
|
|
|
#include "config.h"
|
2020-08-26 02:40:48 +02:00
|
|
|
#include <common/gossmap.h>
|
|
|
|
#include <devtools/clean_topo.h>
|
|
|
|
|
|
|
|
static void visit(struct gossmap *map,
|
|
|
|
struct gossmap_node *n,
|
|
|
|
bool *visited)
|
|
|
|
{
|
|
|
|
visited[gossmap_node_idx(map, n)] = true;
|
|
|
|
|
|
|
|
for (size_t i = 0; i < n->num_chans; i++) {
|
|
|
|
int dir;
|
|
|
|
struct gossmap_chan *c = gossmap_nth_chan(map, n, i, &dir);
|
|
|
|
struct gossmap_node *peer;
|
|
|
|
|
|
|
|
peer = gossmap_nth_node(map, c, !dir);
|
|
|
|
if (!visited[gossmap_node_idx(map, peer)])
|
|
|
|
visit(map, peer, visited);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void clean_topo(struct gossmap *map, bool remove_singles)
|
|
|
|
{
|
|
|
|
struct gossmap_node *n, *next;
|
|
|
|
bool *visited;
|
|
|
|
|
|
|
|
/* Remove channels which are not enabled in both dirs. */
|
|
|
|
for (struct gossmap_chan *c = gossmap_first_chan(map);
|
|
|
|
c;
|
|
|
|
c = gossmap_next_chan(map, c)) {
|
|
|
|
if (!c->half[0].enabled || !c->half[1].enabled) {
|
|
|
|
gossmap_remove_chan(map, c);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (remove_singles) {
|
|
|
|
for (n = gossmap_first_node(map); n; n = next) {
|
|
|
|
next = gossmap_next_node(map, n);
|
|
|
|
if (n->num_chans == 1)
|
|
|
|
gossmap_remove_node(map, n);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Remove isolated nodes (we assume first isn't isolated!) */
|
|
|
|
visited = tal_arrz(NULL, bool, gossmap_max_node_idx(map));
|
|
|
|
visit(map, gossmap_first_node(map), visited);
|
|
|
|
|
|
|
|
for (n = gossmap_first_node(map); n; n = next) {
|
|
|
|
next = gossmap_next_node(map, n);
|
|
|
|
if (!visited[gossmap_node_idx(map, n)])
|
|
|
|
gossmap_remove_node(map, n);
|
|
|
|
}
|
|
|
|
tal_free(visited);
|
|
|
|
}
|