gonum.org/v1/gonum@v0.14.0/graph/iterator/nodes.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 package iterator 6 7 import "gonum.org/v1/gonum/graph" 8 9 // OrderedNodes implements the graph.Nodes and graph.NodeSlicer interfaces. 10 // The iteration order of OrderedNodes is the order of nodes passed to 11 // NewNodeIterator. 12 type OrderedNodes struct { 13 idx int 14 nodes []graph.Node 15 } 16 17 // NewOrderedNodes returns a OrderedNodes initialized with the provided nodes. 18 func NewOrderedNodes(nodes []graph.Node) *OrderedNodes { 19 return &OrderedNodes{idx: -1, nodes: nodes} 20 } 21 22 // Len returns the remaining number of nodes to be iterated over. 23 func (n *OrderedNodes) Len() int { 24 if n.idx >= len(n.nodes) { 25 return 0 26 } 27 return len(n.nodes[n.idx+1:]) 28 } 29 30 // Next returns whether the next call of Node will return a valid node. 31 func (n *OrderedNodes) Next() bool { 32 if uint(n.idx)+1 < uint(len(n.nodes)) { 33 n.idx++ 34 return true 35 } 36 n.idx = len(n.nodes) 37 return false 38 } 39 40 // Node returns the current node of the iterator. Next must have been 41 // called prior to a call to Node. 42 func (n *OrderedNodes) Node() graph.Node { 43 if n.idx >= len(n.nodes) || n.idx < 0 { 44 return nil 45 } 46 return n.nodes[n.idx] 47 } 48 49 // NodeSlice returns all the remaining nodes in the iterator and advances 50 // the iterator. 51 func (n *OrderedNodes) NodeSlice() []graph.Node { 52 if n.idx >= len(n.nodes) { 53 return nil 54 } 55 idx := n.idx + 1 56 n.idx = len(n.nodes) 57 return n.nodes[idx:] 58 } 59 60 // Reset returns the iterator to its initial state. 61 func (n *OrderedNodes) Reset() { 62 n.idx = -1 63 } 64 65 // LazyOrderedNodes implements the graph.Nodes and graph.NodeSlicer interfaces. 66 // The iteration order of LazyOrderedNodes is not determined until the first 67 // call to Next or NodeSlice. After that, the iteration order is fixed. 68 type LazyOrderedNodes struct { 69 iter OrderedNodes 70 nodes map[int64]graph.Node 71 } 72 73 // NewLazyOrderedNodes returns a LazyOrderedNodes initialized with the provided nodes. 74 func NewLazyOrderedNodes(nodes map[int64]graph.Node) *LazyOrderedNodes { 75 return &LazyOrderedNodes{nodes: nodes} 76 } 77 78 // Len returns the remaining number of nodes to be iterated over. 79 func (n *LazyOrderedNodes) Len() int { 80 if n.iter.nodes == nil { 81 return len(n.nodes) 82 } 83 return n.iter.Len() 84 } 85 86 // Next returns whether the next call of Node will return a valid node. 87 func (n *LazyOrderedNodes) Next() bool { 88 if n.iter.nodes == nil { 89 n.fillSlice() 90 } 91 return n.iter.Next() 92 } 93 94 // Node returns the current node of the iterator. Next must have been 95 // called prior to a call to Node. 96 func (n *LazyOrderedNodes) Node() graph.Node { 97 return n.iter.Node() 98 } 99 100 // NodeSlice returns all the remaining nodes in the iterator and advances 101 // the iterator. 102 func (n *LazyOrderedNodes) NodeSlice() []graph.Node { 103 if n.iter.nodes == nil { 104 n.fillSlice() 105 } 106 return n.iter.NodeSlice() 107 } 108 109 // Reset returns the iterator to its initial state. 110 func (n *LazyOrderedNodes) Reset() { 111 n.iter.Reset() 112 } 113 114 func (n *LazyOrderedNodes) fillSlice() { 115 n.iter = OrderedNodes{idx: -1, nodes: make([]graph.Node, len(n.nodes))} 116 i := 0 117 for _, u := range n.nodes { 118 n.iter.nodes[i] = u 119 i++ 120 } 121 n.nodes = nil 122 } 123 124 // LazyOrderedNodesByEdge implements the graph.Nodes and graph.NodeSlicer interfaces. 125 // The iteration order of LazyOrderedNodesByEdge is not determined until the first 126 // call to Next or NodeSlice. After that, the iteration order is fixed. 127 type LazyOrderedNodesByEdge struct { 128 iter OrderedNodes 129 nodes map[int64]graph.Node 130 edges map[int64]graph.Edge 131 } 132 133 // NewLazyOrderedNodesByEdge returns a LazyOrderedNodesByEdge initialized with the 134 // provided nodes. 135 func NewLazyOrderedNodesByEdge(nodes map[int64]graph.Node, edges map[int64]graph.Edge) *LazyOrderedNodesByEdge { 136 return &LazyOrderedNodesByEdge{nodes: nodes, edges: edges} 137 } 138 139 // Len returns the remaining number of nodes to be iterated over. 140 func (n *LazyOrderedNodesByEdge) Len() int { 141 if n.iter.nodes == nil { 142 return len(n.edges) 143 } 144 return n.iter.Len() 145 } 146 147 // Next returns whether the next call of Node will return a valid node. 148 func (n *LazyOrderedNodesByEdge) Next() bool { 149 if n.iter.nodes == nil { 150 n.fillSlice() 151 } 152 return n.iter.Next() 153 } 154 155 // Node returns the current node of the iterator. Next must have been 156 // called prior to a call to Node. 157 func (n *LazyOrderedNodesByEdge) Node() graph.Node { 158 return n.iter.Node() 159 } 160 161 // NodeSlice returns all the remaining nodes in the iterator and advances 162 // the iterator. 163 func (n *LazyOrderedNodesByEdge) NodeSlice() []graph.Node { 164 if n.iter.nodes == nil { 165 n.fillSlice() 166 } 167 return n.iter.NodeSlice() 168 } 169 170 // Reset returns the iterator to its initial state. 171 func (n *LazyOrderedNodesByEdge) Reset() { 172 n.iter.Reset() 173 } 174 175 func (n *LazyOrderedNodesByEdge) fillSlice() { 176 n.iter = OrderedNodes{idx: -1, nodes: make([]graph.Node, len(n.edges))} 177 i := 0 178 for id := range n.edges { 179 n.iter.nodes[i] = n.nodes[id] 180 i++ 181 } 182 n.nodes = nil 183 n.edges = nil 184 } 185 186 // LazyOrderedNodesByWeightedEdge implements the graph.Nodes and graph.NodeSlicer interfaces. 187 // The iteration order of LazyOrderedNodesByEeightedEdge is not determined until the first 188 // call to Next or NodeSlice. After that, the iteration order is fixed. 189 type LazyOrderedNodesByWeightedEdge struct { 190 iter OrderedNodes 191 nodes map[int64]graph.Node 192 edges map[int64]graph.WeightedEdge 193 } 194 195 // NewLazyOrderedNodesByWeightedEdge returns a LazyOrderedNodesByEdge initialized with the 196 // provided nodes. 197 func NewLazyOrderedNodesByWeightedEdge(nodes map[int64]graph.Node, edges map[int64]graph.WeightedEdge) *LazyOrderedNodesByWeightedEdge { 198 return &LazyOrderedNodesByWeightedEdge{nodes: nodes, edges: edges} 199 } 200 201 // Len returns the remaining number of nodes to be iterated over. 202 func (n *LazyOrderedNodesByWeightedEdge) Len() int { 203 if n.iter.nodes == nil { 204 return len(n.edges) 205 } 206 return n.iter.Len() 207 } 208 209 // Next returns whether the next call of Node will return a valid node. 210 func (n *LazyOrderedNodesByWeightedEdge) Next() bool { 211 if n.iter.nodes == nil { 212 n.fillSlice() 213 } 214 return n.iter.Next() 215 } 216 217 // Node returns the current node of the iterator. Next must have been 218 // called prior to a call to Node. 219 func (n *LazyOrderedNodesByWeightedEdge) Node() graph.Node { 220 return n.iter.Node() 221 } 222 223 // NodeSlice returns all the remaining nodes in the iterator and advances 224 // the iterator. 225 func (n *LazyOrderedNodesByWeightedEdge) NodeSlice() []graph.Node { 226 if n.iter.nodes == nil { 227 n.fillSlice() 228 } 229 return n.iter.NodeSlice() 230 } 231 232 // Reset returns the iterator to its initial state. 233 func (n *LazyOrderedNodesByWeightedEdge) Reset() { 234 n.iter.Reset() 235 } 236 237 func (n *LazyOrderedNodesByWeightedEdge) fillSlice() { 238 n.iter = OrderedNodes{idx: -1, nodes: make([]graph.Node, len(n.edges))} 239 i := 0 240 for id := range n.edges { 241 n.iter.nodes[i] = n.nodes[id] 242 i++ 243 } 244 n.nodes = nil 245 n.edges = nil 246 } 247 248 // LazyOrderedNodesByLines implements the graph.Nodes and graph.NodeSlicer interfaces. 249 // The iteration order of LazyOrderedNodesByLines is not determined until the first 250 // call to Next or NodeSlice. After that, the iteration order is fixed. 251 type LazyOrderedNodesByLines struct { 252 iter OrderedNodes 253 nodes map[int64]graph.Node 254 edges map[int64]map[int64]graph.Line 255 } 256 257 // NewLazyOrderedNodesByLine returns a LazyOrderedNodesByLines initialized with the 258 // provided nodes. 259 func NewLazyOrderedNodesByLines(nodes map[int64]graph.Node, edges map[int64]map[int64]graph.Line) *LazyOrderedNodesByLines { 260 return &LazyOrderedNodesByLines{nodes: nodes, edges: edges} 261 } 262 263 // Len returns the remaining number of nodes to be iterated over. 264 func (n *LazyOrderedNodesByLines) Len() int { 265 if n.iter.nodes == nil { 266 return len(n.edges) 267 } 268 return n.iter.Len() 269 } 270 271 // Next returns whether the next call of Node will return a valid node. 272 func (n *LazyOrderedNodesByLines) Next() bool { 273 if n.iter.nodes == nil { 274 n.fillSlice() 275 } 276 return n.iter.Next() 277 } 278 279 // Node returns the current node of the iterator. Next must have been 280 // called prior to a call to Node. 281 func (n *LazyOrderedNodesByLines) Node() graph.Node { 282 return n.iter.Node() 283 } 284 285 // NodeSlice returns all the remaining nodes in the iterator and advances 286 // the iterator. 287 func (n *LazyOrderedNodesByLines) NodeSlice() []graph.Node { 288 if n.iter.nodes == nil { 289 n.fillSlice() 290 } 291 return n.iter.NodeSlice() 292 } 293 294 // Reset returns the iterator to its initial state. 295 func (n *LazyOrderedNodesByLines) Reset() { 296 n.iter.Reset() 297 } 298 299 func (n *LazyOrderedNodesByLines) fillSlice() { 300 n.iter = OrderedNodes{idx: -1, nodes: make([]graph.Node, len(n.edges))} 301 i := 0 302 for id := range n.edges { 303 n.iter.nodes[i] = n.nodes[id] 304 i++ 305 } 306 n.nodes = nil 307 n.edges = nil 308 } 309 310 // LazyOrderedNodesByWeightedLines implements the graph.Nodes and graph.NodeSlicer interfaces. 311 // The iteration order of LazyOrderedNodesByEeightedLine is not determined until the first 312 // call to Next or NodeSlice. After that, the iteration order is fixed. 313 type LazyOrderedNodesByWeightedLines struct { 314 iter OrderedNodes 315 nodes map[int64]graph.Node 316 edges map[int64]map[int64]graph.WeightedLine 317 } 318 319 // NewLazyOrderedNodesByWeightedLines returns a LazyOrderedNodesByLines initialized with the 320 // provided nodes. 321 func NewLazyOrderedNodesByWeightedLines(nodes map[int64]graph.Node, edges map[int64]map[int64]graph.WeightedLine) *LazyOrderedNodesByWeightedLines { 322 return &LazyOrderedNodesByWeightedLines{nodes: nodes, edges: edges} 323 } 324 325 // Len returns the remaining number of nodes to be iterated over. 326 func (n *LazyOrderedNodesByWeightedLines) Len() int { 327 if n.iter.nodes == nil { 328 return len(n.edges) 329 } 330 return n.iter.Len() 331 } 332 333 // Next returns whether the next call of Node will return a valid node. 334 func (n *LazyOrderedNodesByWeightedLines) Next() bool { 335 if n.iter.nodes == nil { 336 n.fillSlice() 337 } 338 return n.iter.Next() 339 } 340 341 // Node returns the current node of the iterator. Next must have been 342 // called prior to a call to Node. 343 func (n *LazyOrderedNodesByWeightedLines) Node() graph.Node { 344 return n.iter.Node() 345 } 346 347 // NodeSlice returns all the remaining nodes in the iterator and advances 348 // the iterator. 349 func (n *LazyOrderedNodesByWeightedLines) NodeSlice() []graph.Node { 350 if n.iter.nodes == nil { 351 n.fillSlice() 352 } 353 return n.iter.NodeSlice() 354 } 355 356 // Reset returns the iterator to its initial state. 357 func (n *LazyOrderedNodesByWeightedLines) Reset() { 358 n.iter.Reset() 359 } 360 361 func (n *LazyOrderedNodesByWeightedLines) fillSlice() { 362 n.iter = OrderedNodes{idx: -1, nodes: make([]graph.Node, len(n.edges))} 363 i := 0 364 for id := range n.edges { 365 n.iter.nodes[i] = n.nodes[id] 366 i++ 367 } 368 n.nodes = nil 369 n.edges = nil 370 } 371 372 // ImplicitNodes implements the graph.Nodes interface for a set of nodes over 373 // a contiguous ID range. 374 type ImplicitNodes struct { 375 beg, end int 376 curr int 377 newNode func(id int) graph.Node 378 } 379 380 // NewImplicitNodes returns a new implicit node iterator spanning nodes in [beg,end). 381 // The provided new func maps the id to a graph.Node. NewImplicitNodes will panic 382 // if beg is greater than end. 383 func NewImplicitNodes(beg, end int, new func(id int) graph.Node) *ImplicitNodes { 384 if beg > end { 385 panic("iterator: invalid range") 386 } 387 return &ImplicitNodes{beg: beg, end: end, curr: beg - 1, newNode: new} 388 } 389 390 // Len returns the remaining number of nodes to be iterated over. 391 func (n *ImplicitNodes) Len() int { 392 if n.end <= n.curr { 393 return 0 394 } 395 return n.end - n.curr - 1 396 } 397 398 // Next returns whether the next call of Node will return a valid node. 399 func (n *ImplicitNodes) Next() bool { 400 if n.curr == n.end { 401 return false 402 } 403 n.curr++ 404 return n.curr < n.end 405 } 406 407 // Node returns the current node of the iterator. Next must have been 408 // called prior to a call to Node. 409 func (n *ImplicitNodes) Node() graph.Node { 410 if n.Len() == -1 || n.curr < n.beg { 411 return nil 412 } 413 return n.newNode(n.curr) 414 } 415 416 // Reset returns the iterator to its initial state. 417 func (n *ImplicitNodes) Reset() { 418 n.curr = n.beg - 1 419 } 420 421 // NodeSlice returns all the remaining nodes in the iterator and advances 422 // the iterator. 423 func (n *ImplicitNodes) NodeSlice() []graph.Node { 424 if n.Len() == 0 { 425 return nil 426 } 427 nodes := make([]graph.Node, 0, n.Len()) 428 for n.curr++; n.curr < n.end; n.curr++ { 429 nodes = append(nodes, n.newNode(n.curr)) 430 } 431 return nodes 432 }