Make Nodes() BFS implementation efficient

This commit is contained in:
Milos Gajdos 2019-09-03 02:58:17 +01:00
parent 2f5e3c66b9
commit fb13877904
No known key found for this signature in database
GPG Key ID: 8B31058CC55DFD4F

View File

@ -1,6 +1,7 @@
package network package network
import ( import (
"container/list"
"sync" "sync"
"time" "time"
@ -731,38 +732,31 @@ func (n *network) Connect() error {
} }
// Nodes returns a list of all network nodes // Nodes returns a list of all network nodes
// NOTE: this is a naive i.e. inefficient BFS implementation
func (n *network) Nodes() []Node { func (n *network) Nodes() []Node {
// map to track visited nodes //track the visited nodes
visited := make(map[string]*node) visited := make(map[string]*node)
// queue of the nodes to visit // queue of the nodes to visit
queue := make([]*node, 1) queue := list.New()
queue[0] = n.node // push network node to the back of queue
// add the root node to the map of the visited nodes queue.PushBack(n.node)
// mark the node as visited
visited[n.node.id] = n.node visited[n.node.id] = n.node
for { // keep iterating over the queue until its empty
// pop a node from the queue for qnode := queue.Front(); qnode != nil; qnode = qnode.Next() {
qnode := queue[0] queue.Remove(qnode)
// pop is done by reslicing of the queue
// https://github.com/golang/go/wiki/SliceTricks
queue = queue[1:]
// iterate through all of its neighbours // iterate through all of its neighbours
// mark the visited nodes; enqueue the non-visted // 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 { if _, ok := visited[id]; !ok {
visited[id] = node 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) nodes := make([]Node, len(visited))
// collecte all the nodes into slice // collect all the nodes and return them
for _, node := range visited { for _, node := range visited {
nodes = append(nodes, node) nodes = append(nodes, node)
} }