Merge pull request #724 from milosgajdos83/efficient-bfs-queue
Make Nodes() BFS implementation efficient
This commit is contained in:
		| @@ -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) | ||||||
| 	} | 	} | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user