From fb138779049beb9e3a27d8e3e69afe70b0101342 Mon Sep 17 00:00:00 2001 From: Milos Gajdos Date: Tue, 3 Sep 2019 02:58:17 +0100 Subject: [PATCH] Make Nodes() BFS implementation efficient --- network/default.go | 32 +++++++++++++------------------- 1 file changed, 13 insertions(+), 19 deletions(-) diff --git a/network/default.go b/network/default.go index 7be7a68a..b0c77f62 100644 --- a/network/default.go +++ b/network/default.go @@ -1,6 +1,7 @@ package network import ( + "container/list" "sync" "time" @@ -731,38 +732,31 @@ func (n *network) Connect() error { } // Nodes returns a list of all network nodes -// NOTE: this is a naive i.e. inefficient BFS implementation func (n *network) Nodes() []Node { - // map to track visited nodes + //track the visited nodes visited := make(map[string]*node) // queue of the nodes to visit - queue := make([]*node, 1) - queue[0] = n.node - // add the root node to the map of the visited nodes + queue := list.New() + // push network node to the back of queue + queue.PushBack(n.node) + // mark the node as visited visited[n.node.id] = n.node - for { - // pop a node from the queue - qnode := queue[0] - // pop is done by reslicing of the queue - // https://github.com/golang/go/wiki/SliceTricks - queue = queue[1:] + // keep iterating over the queue until its empty + for qnode := queue.Front(); qnode != nil; qnode = qnode.Next() { + queue.Remove(qnode) // iterate through all of its neighbours // mark the visited nodes; enqueue the non-visted - for id, node := range qnode.neighbours { + for id, node := range qnode.Value.(*node).neighbours { if _, ok := visited[id]; !ok { visited[id] = node - queue = append(queue, node) + queue.PushBack(node) } } - // if no nodes are in the queue break - if len(queue) == 0 { - break - } } - nodes := make([]Node, 0) - // collecte all the nodes into slice + nodes := make([]Node, len(visited)) + // collect all the nodes and return them for _, node := range visited { nodes = append(nodes, node) }