gonum.org/v1/gonum@v0.15.1-0.20240517103525-f853624cb1bb/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 "gonum.org/v1/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 n := &Nodes{nodes: rv} 34 n.iter.Reset(rv) 35 return n 36 } 37 38 // Len returns the remaining number of nodes to be iterated over. 39 func (n *Nodes) Len() int { 40 return n.nodes.Len() - n.pos 41 } 42 43 // Next returns whether the next call of Node will return a valid node. 44 func (n *Nodes) Next() bool { 45 if n.pos >= n.nodes.Len() { 46 return false 47 } 48 ok := n.iter.Next() 49 if ok { 50 n.pos++ 51 n.curr = n.iter.Value().Interface().(graph.Node) 52 } 53 return ok 54 } 55 56 // Node returns the current node of the iterator. Next must have been 57 // called prior to a call to Node. 58 func (n *Nodes) Node() graph.Node { 59 return n.curr 60 } 61 62 // Reset returns the iterator to its initial state. 63 func (n *Nodes) Reset() { 64 n.curr = nil 65 n.pos = 0 66 n.iter.Reset(n.nodes) 67 } 68 69 // NodeSlice returns all the remaining nodes in the iterator and advances 70 // the iterator. The order of nodes within the returned slice is not 71 // specified. 72 func (n *Nodes) NodeSlice() []graph.Node { 73 if n.Len() == 0 { 74 return nil 75 } 76 nodes := make([]graph.Node, 0, n.Len()) 77 for n.iter.Next() { 78 nodes = append(nodes, n.iter.Value().Interface().(graph.Node)) 79 } 80 n.pos = n.nodes.Len() 81 return nodes 82 } 83 84 // NodesByEdge implements the graph.Nodes interfaces. 85 // The iteration order of Nodes is randomized. 86 type NodesByEdge struct { 87 nodes map[int64]graph.Node 88 edges reflect.Value 89 iter reflect.MapIter 90 pos int 91 curr graph.Node 92 } 93 94 // NewNodesByEdge returns a NodesByEdge initialized with the 95 // provided nodes, a map of node IDs to graph.Nodes, and the set 96 // of edges, a map of to-node IDs to graph.Edge, that can be 97 // traversed to reach the nodes that the NodesByEdge will iterate 98 // over. No check is made that the keys match the graph.Node IDs, 99 // and the map keys are not used. 100 // 101 // Behavior of the NodesByEdge is unspecified if nodes or edges 102 // is mutated after the call to NewNodes. 103 func NewNodesByEdge(nodes map[int64]graph.Node, edges map[int64]graph.Edge) *NodesByEdge { 104 rv := reflect.ValueOf(edges) 105 n := &NodesByEdge{nodes: nodes, edges: rv} 106 n.iter.Reset(rv) 107 return n 108 } 109 110 // NewNodesByWeightedEdge returns a NodesByEdge initialized with the 111 // provided nodes, a map of node IDs to graph.Nodes, and the set 112 // of edges, a map of to-node IDs to graph.WeightedEdge, that can be 113 // traversed to reach the nodes that the NodesByEdge will iterate 114 // over. No check is made that the keys match the graph.Node IDs, 115 // and the map keys are not used. 116 // 117 // Behavior of the NodesByEdge is unspecified if nodes or edges 118 // is mutated after the call to NewNodes. 119 func NewNodesByWeightedEdge(nodes map[int64]graph.Node, edges map[int64]graph.WeightedEdge) *NodesByEdge { 120 rv := reflect.ValueOf(edges) 121 n := &NodesByEdge{nodes: nodes, edges: rv} 122 n.iter.Reset(rv) 123 return n 124 } 125 126 // NewNodesByLines returns a NodesByEdge initialized with the 127 // provided nodes, a map of node IDs to graph.Nodes, and the set 128 // of lines, a map to-node IDs to map of graph.Line, that can be 129 // traversed to reach the nodes that the NodesByEdge will iterate 130 // over. No check is made that the keys match the graph.Node IDs, 131 // and the map keys are not used. 132 // 133 // Behavior of the NodesByEdge is unspecified if nodes or lines 134 // is mutated after the call to NewNodes. 135 func NewNodesByLines(nodes map[int64]graph.Node, lines map[int64]map[int64]graph.Line) *NodesByEdge { 136 rv := reflect.ValueOf(lines) 137 n := &NodesByEdge{nodes: nodes, edges: rv} 138 n.iter.Reset(rv) 139 return n 140 } 141 142 // NewNodesByWeightedLines returns a NodesByEdge initialized with the 143 // provided nodes, a map of node IDs to graph.Nodes, and the set 144 // of lines, a map to-node IDs to map of graph.WeightedLine, that can be 145 // traversed to reach the nodes that the NodesByEdge will iterate 146 // over. No check is made that the keys match the graph.Node IDs, 147 // and the map keys are not used. 148 // 149 // Behavior of the NodesByEdge is unspecified if nodes or lines 150 // is mutated after the call to NewNodes. 151 func NewNodesByWeightedLines(nodes map[int64]graph.Node, lines map[int64]map[int64]graph.WeightedLine) *NodesByEdge { 152 rv := reflect.ValueOf(lines) 153 n := &NodesByEdge{nodes: nodes, edges: rv} 154 n.iter.Reset(rv) 155 return n 156 } 157 158 // Len returns the remaining number of nodes to be iterated over. 159 func (n *NodesByEdge) Len() int { 160 return n.edges.Len() - n.pos 161 } 162 163 // Next returns whether the next call of Node will return a valid node. 164 func (n *NodesByEdge) Next() bool { 165 if n.pos >= n.edges.Len() { 166 return false 167 } 168 ok := n.iter.Next() 169 if ok { 170 n.pos++ 171 n.curr = n.nodes[n.iter.Key().Int()] 172 } 173 return ok 174 } 175 176 // Node returns the current node of the iterator. Next must have been 177 // called prior to a call to Node. 178 func (n *NodesByEdge) Node() graph.Node { 179 return n.curr 180 } 181 182 // Reset returns the iterator to its initial state. 183 func (n *NodesByEdge) Reset() { 184 n.curr = nil 185 n.pos = 0 186 n.iter.Reset(n.edges) 187 } 188 189 // NodeSlice returns all the remaining nodes in the iterator and advances 190 // the iterator. The order of nodes within the returned slice is not 191 // specified. 192 func (n *NodesByEdge) NodeSlice() []graph.Node { 193 if n.Len() == 0 { 194 return nil 195 } 196 nodes := make([]graph.Node, 0, n.Len()) 197 for n.iter.Next() { 198 nodes = append(nodes, n.nodes[n.iter.Key().Int()]) 199 } 200 n.pos = n.edges.Len() 201 return nodes 202 }