Merge pull request #724 from milosgajdos83/efficient-bfs-queue

Make Nodes() BFS implementation efficient
This commit is contained in:
Asim Aslam 2019-09-03 07:43:37 +01:00 committed by GitHub
commit 5440325a18
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

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