github.com/decred/dcrlnd@v0.7.6/autopilot/simple_graph.go (about)

     1  package autopilot
     2  
     3  // SimpleGraph stores a simplifed adj graph of a channel graph to speed
     4  // up graph processing by eliminating all unnecessary hashing and map access.
     5  type SimpleGraph struct {
     6  	// Nodes is a map from node index to NodeID.
     7  	Nodes []NodeID
     8  
     9  	// Adj stores nodes and neighbors in an adjacency list.
    10  	Adj [][]int
    11  }
    12  
    13  // NewSimpleGraph creates a simplified graph from the current channel graph.
    14  // Returns an error if the channel graph iteration fails due to underlying
    15  // failure.
    16  func NewSimpleGraph(g ChannelGraph) (*SimpleGraph, error) {
    17  	nodes := make(map[NodeID]int)
    18  	adj := make(map[int][]int)
    19  	nextIndex := 0
    20  
    21  	// getNodeIndex returns the integer index of the passed node.
    22  	// The returned index is then used to create a simplifed adjacency list
    23  	// where each node is identified by its index instead of its pubkey, and
    24  	// also to create a mapping from node index to node pubkey.
    25  	getNodeIndex := func(node Node) int {
    26  		key := NodeID(node.PubKey())
    27  		nodeIndex, ok := nodes[key]
    28  
    29  		if !ok {
    30  			nodes[key] = nextIndex
    31  			nodeIndex = nextIndex
    32  			nextIndex++
    33  		}
    34  
    35  		return nodeIndex
    36  	}
    37  
    38  	// Iterate over each node and each channel and update the adj and the node
    39  	// index.
    40  	err := g.ForEachNode(func(node Node) error {
    41  		u := getNodeIndex(node)
    42  
    43  		return node.ForEachChannel(func(edge ChannelEdge) error {
    44  			v := getNodeIndex(edge.Peer)
    45  
    46  			adj[u] = append(adj[u], v)
    47  			return nil
    48  		})
    49  	})
    50  	if err != nil {
    51  		return nil, err
    52  	}
    53  
    54  	graph := &SimpleGraph{
    55  		Nodes: make([]NodeID, len(nodes)),
    56  		Adj:   make([][]int, len(nodes)),
    57  	}
    58  
    59  	// Fill the adj and the node index to node pubkey mapping.
    60  	for nodeID, nodeIndex := range nodes {
    61  		graph.Adj[nodeIndex] = adj[nodeIndex]
    62  		graph.Nodes[nodeIndex] = nodeID
    63  	}
    64  
    65  	return graph, nil
    66  }