github.com/gopherd/gonum@v0.0.4/graph/iterator/nodes_map_safe.go (about) 1 // Copyright ©2018 The Gonum Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 4 5 //go:build safe 6 // +build safe 7 8 package iterator 9 10 import ( 11 "reflect" 12 13 "github.com/gopherd/gonum/graph" 14 ) 15 16 // Nodes implements the graph.Nodes interfaces. 17 // The iteration order of Nodes is randomized. 18 type Nodes struct { 19 nodes reflect.Value 20 iter *reflect.MapIter 21 pos int 22 curr graph.Node 23 } 24 25 // NewNodes returns a Nodes initialized with the provided nodes, a 26 // map of node IDs to graph.Nodes. No check is made that the keys 27 // match the graph.Node IDs, and the map keys are not used. 28 // 29 // Behavior of the Nodes is unspecified if nodes is mutated after 30 // the call to NewNodes. 31 func NewNodes(nodes map[int64]graph.Node) *Nodes { 32 rv := reflect.ValueOf(nodes) 33 return &Nodes{nodes: rv, iter: rv.MapRange()} 34 } 35 36 // Len returns the remaining number of nodes to be iterated over. 37 func (n *Nodes) Len() int { 38 return n.nodes.Len() - n.pos 39 } 40 41 // Next returns whether the next call of Node will return a valid node. 42 func (n *Nodes) Next() bool { 43 if n.pos >= n.nodes.Len() { 44 return false 45 } 46 ok := n.iter.Next() 47 if ok { 48 n.pos++ 49 n.curr = n.iter.Value().Interface().(graph.Node) 50 } 51 return ok 52 } 53 54 // Node returns the current node of the iterator. Next must have been 55 // called prior to a call to Node. 56 func (n *Nodes) Node() graph.Node { 57 return n.curr 58 } 59 60 // Reset returns the iterator to its initial state. 61 func (n *Nodes) Reset() { 62 n.curr = nil 63 n.pos = 0 64 // TODO(kortschak): Use n.iter.Reset(n.nodes) when it is available and Go1.17 is no longer supported. 65 n.iter = n.nodes.MapRange() 66 } 67 68 // NodeSlice returns all the remaining nodes in the iterator and advances 69 // the iterator. The order of nodes within the returned slice is not 70 // specified. 71 func (n *Nodes) NodeSlice() []graph.Node { 72 if n.Len() == 0 { 73 return nil 74 } 75 nodes := make([]graph.Node, 0, n.Len()) 76 for n.iter.Next() { 77 nodes = append(nodes, n.iter.Value().Interface().(graph.Node)) 78 } 79 n.pos = n.nodes.Len() 80 return nodes 81 } 82 83 // NodesByEdge implements the graph.Nodes interfaces. 84 // The iteration order of Nodes is randomized. 85 type NodesByEdge struct { 86 nodes map[int64]graph.Node 87 edges reflect.Value 88 iter *reflect.MapIter 89 pos int 90 curr graph.Node 91 } 92 93 // NewNodesByEdge returns a NodesByEdge initialized with the 94 // provided nodes, a map of node IDs to graph.Nodes, and the set 95 // of edges, a map of to-node IDs to graph.Edge, that can be 96 // traversed to reach the nodes that the NodesByEdge will iterate 97 // over. No check is made that the keys match the graph.Node IDs, 98 // and the map keys are not used. 99 // 100 // Behavior of the NodesByEdge is unspecified if nodes or edges 101 // is mutated after the call to NewNodes. 102 func NewNodesByEdge(nodes map[int64]graph.Node, edges map[int64]graph.Edge) *NodesByEdge { 103 rv := reflect.ValueOf(edges) 104 return &NodesByEdge{nodes: nodes, edges: rv, iter: rv.MapRange()} 105 } 106 107 // NewNodesByWeightedEdge returns a NodesByEdge initialized with the 108 // provided nodes, a map of node IDs to graph.Nodes, and the set 109 // of edges, a map of to-node IDs to graph.WeightedEdge, that can be 110 // traversed to reach the nodes that the NodesByEdge will iterate 111 // over. No check is made that the keys match the graph.Node IDs, 112 // and the map keys are not used. 113 // 114 // Behavior of the NodesByEdge is unspecified if nodes or edges 115 // is mutated after the call to NewNodes. 116 func NewNodesByWeightedEdge(nodes map[int64]graph.Node, edges map[int64]graph.WeightedEdge) *NodesByEdge { 117 rv := reflect.ValueOf(edges) 118 return &NodesByEdge{nodes: nodes, edges: rv, iter: rv.MapRange()} 119 } 120 121 // NewNodesByLines returns a NodesByEdge initialized with the 122 // provided nodes, a map of node IDs to graph.Nodes, and the set 123 // of lines, a map to-node IDs to map of graph.Line, that can be 124 // traversed to reach the nodes that the NodesByEdge will iterate 125 // over. No check is made that the keys match the graph.Node IDs, 126 // and the map keys are not used. 127 // 128 // Behavior of the NodesByEdge is unspecified if nodes or lines 129 // is mutated after the call to NewNodes. 130 func NewNodesByLines(nodes map[int64]graph.Node, lines map[int64]map[int64]graph.Line) *NodesByEdge { 131 rv := reflect.ValueOf(lines) 132 return &NodesByEdge{nodes: nodes, edges: rv, iter: rv.MapRange()} 133 } 134 135 // NewNodesByWeightedLines returns a NodesByEdge initialized with the 136 // provided nodes, a map of node IDs to graph.Nodes, and the set 137 // of lines, a map to-node IDs to map of graph.WeightedLine, that can be 138 // traversed to reach the nodes that the NodesByEdge will iterate 139 // over. No check is made that the keys match the graph.Node IDs, 140 // and the map keys are not used. 141 // 142 // Behavior of the NodesByEdge is unspecified if nodes or lines 143 // is mutated after the call to NewNodes. 144 func NewNodesByWeightedLines(nodes map[int64]graph.Node, lines map[int64]map[int64]graph.WeightedLine) *NodesByEdge { 145 rv := reflect.ValueOf(lines) 146 return &NodesByEdge{nodes: nodes, edges: rv, iter: rv.MapRange()} 147 } 148 149 // Len returns the remaining number of nodes to be iterated over. 150 func (n *NodesByEdge) Len() int { 151 return n.edges.Len() - n.pos 152 } 153 154 // Next returns whether the next call of Node will return a valid node. 155 func (n *NodesByEdge) Next() bool { 156 if n.pos >= n.edges.Len() { 157 return false 158 } 159 ok := n.iter.Next() 160 if ok { 161 n.pos++ 162 n.curr = n.nodes[n.iter.Key().Int()] 163 } 164 return ok 165 } 166 167 // Node returns the current node of the iterator. Next must have been 168 // called prior to a call to Node. 169 func (n *NodesByEdge) Node() graph.Node { 170 return n.curr 171 } 172 173 // Reset returns the iterator to its initial state. 174 func (n *NodesByEdge) Reset() { 175 n.curr = nil 176 n.pos = 0 177 n.iter = n.edges.MapRange() 178 } 179 180 // NodeSlice returns all the remaining nodes in the iterator and advances 181 // the iterator. The order of nodes within the returned slice is not 182 // specified. 183 func (n *NodesByEdge) NodeSlice() []graph.Node { 184 if n.Len() == 0 { 185 return nil 186 } 187 nodes := make([]graph.Node, 0, n.Len()) 188 for n.iter.Next() { 189 nodes = append(nodes, n.nodes[n.iter.Key().Int()]) 190 } 191 n.pos = n.edges.Len() 192 return nodes 193 }