| // Copyright ©2018 The Gonum Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style |
| // license that can be found in the LICENSE file. |
| |
| package iterator |
| |
| import "gonum.org/v1/gonum/graph" |
| |
| // OrderedNodes implements the graph.Nodes and graph.NodeSlicer interfaces. |
| // The iteration order of OrderedNodes is the order of nodes passed to |
| // NewNodeIterator. |
| type OrderedNodes struct { |
| idx int |
| nodes []graph.Node |
| } |
| |
| // NewOrderedNodes returns a OrderedNodes initialized with the provided nodes. |
| func NewOrderedNodes(nodes []graph.Node) *OrderedNodes { |
| return &OrderedNodes{idx: -1, nodes: nodes} |
| } |
| |
| // Len returns the remaining number of nodes to be iterated over. |
| func (n *OrderedNodes) Len() int { |
| if n.idx >= len(n.nodes) { |
| return 0 |
| } |
| return len(n.nodes[n.idx+1:]) |
| } |
| |
| // Next returns whether the next call of Node will return a valid node. |
| func (n *OrderedNodes) Next() bool { |
| if uint(n.idx)+1 < uint(len(n.nodes)) { |
| n.idx++ |
| return true |
| } |
| n.idx = len(n.nodes) |
| return false |
| } |
| |
| // Node returns the current node of the iterator. Next must have been |
| // called prior to a call to Node. |
| func (n *OrderedNodes) Node() graph.Node { |
| if n.idx >= len(n.nodes) || n.idx < 0 { |
| return nil |
| } |
| return n.nodes[n.idx] |
| } |
| |
| // NodeSlice returns all the remaining nodes in the iterator and advances |
| // the iterator. |
| func (n *OrderedNodes) NodeSlice() []graph.Node { |
| if n.idx >= len(n.nodes) { |
| return nil |
| } |
| idx := n.idx + 1 |
| n.idx = len(n.nodes) |
| return n.nodes[idx:] |
| } |
| |
| // Reset returns the iterator to its initial state. |
| func (n *OrderedNodes) Reset() { |
| n.idx = -1 |
| } |
| |
| // LazyOrderedNodes implements the graph.Nodes and graph.NodeSlicer interfaces. |
| // The iteration order of LazyOrderedNodes is not determined until the first |
| // call to Next or NodeSlice. After that, the iteration order is fixed. |
| type LazyOrderedNodes struct { |
| iter OrderedNodes |
| nodes map[int64]graph.Node |
| } |
| |
| // NewLazyOrderedNodes returns a LazyOrderedNodes initialized with the provided nodes. |
| func NewLazyOrderedNodes(nodes map[int64]graph.Node) *LazyOrderedNodes { |
| return &LazyOrderedNodes{nodes: nodes} |
| } |
| |
| // Len returns the remaining number of nodes to be iterated over. |
| func (n *LazyOrderedNodes) Len() int { |
| if n.iter.nodes == nil { |
| return len(n.nodes) |
| } |
| return n.iter.Len() |
| } |
| |
| // Next returns whether the next call of Node will return a valid node. |
| func (n *LazyOrderedNodes) Next() bool { |
| if n.iter.nodes == nil { |
| n.fillSlice() |
| } |
| return n.iter.Next() |
| } |
| |
| // Node returns the current node of the iterator. Next must have been |
| // called prior to a call to Node. |
| func (n *LazyOrderedNodes) Node() graph.Node { |
| return n.iter.Node() |
| } |
| |
| // NodeSlice returns all the remaining nodes in the iterator and advances |
| // the iterator. |
| func (n *LazyOrderedNodes) NodeSlice() []graph.Node { |
| if n.iter.nodes == nil { |
| n.fillSlice() |
| } |
| return n.iter.NodeSlice() |
| } |
| |
| // Reset returns the iterator to its initial state. |
| func (n *LazyOrderedNodes) Reset() { |
| n.iter.Reset() |
| } |
| |
| func (n *LazyOrderedNodes) fillSlice() { |
| n.iter = OrderedNodes{idx: -1, nodes: make([]graph.Node, len(n.nodes))} |
| i := 0 |
| for _, u := range n.nodes { |
| n.iter.nodes[i] = u |
| i++ |
| } |
| n.nodes = nil |
| } |
| |
| // LazyOrderedNodesByEdge implements the graph.Nodes and graph.NodeSlicer interfaces. |
| // The iteration order of LazyOrderedNodesByEdge is not determined until the first |
| // call to Next or NodeSlice. After that, the iteration order is fixed. |
| type LazyOrderedNodesByEdge struct { |
| iter OrderedNodes |
| nodes map[int64]graph.Node |
| edges map[int64]graph.Edge |
| } |
| |
| // NewLazyOrderedNodesByEdge returns a LazyOrderedNodesByEdge initialized with the |
| // provided nodes. |
| func NewLazyOrderedNodesByEdge(nodes map[int64]graph.Node, edges map[int64]graph.Edge) *LazyOrderedNodesByEdge { |
| return &LazyOrderedNodesByEdge{nodes: nodes, edges: edges} |
| } |
| |
| // Len returns the remaining number of nodes to be iterated over. |
| func (n *LazyOrderedNodesByEdge) Len() int { |
| if n.iter.nodes == nil { |
| return len(n.edges) |
| } |
| return n.iter.Len() |
| } |
| |
| // Next returns whether the next call of Node will return a valid node. |
| func (n *LazyOrderedNodesByEdge) Next() bool { |
| if n.iter.nodes == nil { |
| n.fillSlice() |
| } |
| return n.iter.Next() |
| } |
| |
| // Node returns the current node of the iterator. Next must have been |
| // called prior to a call to Node. |
| func (n *LazyOrderedNodesByEdge) Node() graph.Node { |
| return n.iter.Node() |
| } |
| |
| // NodeSlice returns all the remaining nodes in the iterator and advances |
| // the iterator. |
| func (n *LazyOrderedNodesByEdge) NodeSlice() []graph.Node { |
| if n.iter.nodes == nil { |
| n.fillSlice() |
| } |
| return n.iter.NodeSlice() |
| } |
| |
| // Reset returns the iterator to its initial state. |
| func (n *LazyOrderedNodesByEdge) Reset() { |
| n.iter.Reset() |
| } |
| |
| func (n *LazyOrderedNodesByEdge) fillSlice() { |
| n.iter = OrderedNodes{idx: -1, nodes: make([]graph.Node, len(n.edges))} |
| i := 0 |
| for id := range n.edges { |
| n.iter.nodes[i] = n.nodes[id] |
| i++ |
| } |
| n.nodes = nil |
| n.edges = nil |
| } |
| |
| // LazyOrderedNodesByWeightedEdge implements the graph.Nodes and graph.NodeSlicer interfaces. |
| // The iteration order of LazyOrderedNodesByEeightedEdge is not determined until the first |
| // call to Next or NodeSlice. After that, the iteration order is fixed. |
| type LazyOrderedNodesByWeightedEdge struct { |
| iter OrderedNodes |
| nodes map[int64]graph.Node |
| edges map[int64]graph.WeightedEdge |
| } |
| |
| // NewLazyOrderedNodesByWeightedEdge returns a LazyOrderedNodesByEdge initialized with the |
| // provided nodes. |
| func NewLazyOrderedNodesByWeightedEdge(nodes map[int64]graph.Node, edges map[int64]graph.WeightedEdge) *LazyOrderedNodesByWeightedEdge { |
| return &LazyOrderedNodesByWeightedEdge{nodes: nodes, edges: edges} |
| } |
| |
| // Len returns the remaining number of nodes to be iterated over. |
| func (n *LazyOrderedNodesByWeightedEdge) Len() int { |
| if n.iter.nodes == nil { |
| return len(n.edges) |
| } |
| return n.iter.Len() |
| } |
| |
| // Next returns whether the next call of Node will return a valid node. |
| func (n *LazyOrderedNodesByWeightedEdge) Next() bool { |
| if n.iter.nodes == nil { |
| n.fillSlice() |
| } |
| return n.iter.Next() |
| } |
| |
| // Node returns the current node of the iterator. Next must have been |
| // called prior to a call to Node. |
| func (n *LazyOrderedNodesByWeightedEdge) Node() graph.Node { |
| return n.iter.Node() |
| } |
| |
| // NodeSlice returns all the remaining nodes in the iterator and advances |
| // the iterator. |
| func (n *LazyOrderedNodesByWeightedEdge) NodeSlice() []graph.Node { |
| if n.iter.nodes == nil { |
| n.fillSlice() |
| } |
| return n.iter.NodeSlice() |
| } |
| |
| // Reset returns the iterator to its initial state. |
| func (n *LazyOrderedNodesByWeightedEdge) Reset() { |
| n.iter.Reset() |
| } |
| |
| func (n *LazyOrderedNodesByWeightedEdge) fillSlice() { |
| n.iter = OrderedNodes{idx: -1, nodes: make([]graph.Node, len(n.edges))} |
| i := 0 |
| for id := range n.edges { |
| n.iter.nodes[i] = n.nodes[id] |
| i++ |
| } |
| n.nodes = nil |
| n.edges = nil |
| } |
| |
| // LazyOrderedNodesByLines implements the graph.Nodes and graph.NodeSlicer interfaces. |
| // The iteration order of LazyOrderedNodesByLines is not determined until the first |
| // call to Next or NodeSlice. After that, the iteration order is fixed. |
| type LazyOrderedNodesByLines struct { |
| iter OrderedNodes |
| nodes map[int64]graph.Node |
| edges map[int64]map[int64]graph.Line |
| } |
| |
| // NewLazyOrderedNodesByLine returns a LazyOrderedNodesByLines initialized with the |
| // provided nodes. |
| func NewLazyOrderedNodesByLines(nodes map[int64]graph.Node, edges map[int64]map[int64]graph.Line) *LazyOrderedNodesByLines { |
| return &LazyOrderedNodesByLines{nodes: nodes, edges: edges} |
| } |
| |
| // Len returns the remaining number of nodes to be iterated over. |
| func (n *LazyOrderedNodesByLines) Len() int { |
| if n.iter.nodes == nil { |
| return len(n.edges) |
| } |
| return n.iter.Len() |
| } |
| |
| // Next returns whether the next call of Node will return a valid node. |
| func (n *LazyOrderedNodesByLines) Next() bool { |
| if n.iter.nodes == nil { |
| n.fillSlice() |
| } |
| return n.iter.Next() |
| } |
| |
| // Node returns the current node of the iterator. Next must have been |
| // called prior to a call to Node. |
| func (n *LazyOrderedNodesByLines) Node() graph.Node { |
| return n.iter.Node() |
| } |
| |
| // NodeSlice returns all the remaining nodes in the iterator and advances |
| // the iterator. |
| func (n *LazyOrderedNodesByLines) NodeSlice() []graph.Node { |
| if n.iter.nodes == nil { |
| n.fillSlice() |
| } |
| return n.iter.NodeSlice() |
| } |
| |
| // Reset returns the iterator to its initial state. |
| func (n *LazyOrderedNodesByLines) Reset() { |
| n.iter.Reset() |
| } |
| |
| func (n *LazyOrderedNodesByLines) fillSlice() { |
| n.iter = OrderedNodes{idx: -1, nodes: make([]graph.Node, len(n.edges))} |
| i := 0 |
| for id := range n.edges { |
| n.iter.nodes[i] = n.nodes[id] |
| i++ |
| } |
| n.nodes = nil |
| n.edges = nil |
| } |
| |
| // LazyOrderedNodesByWeightedLines implements the graph.Nodes and graph.NodeSlicer interfaces. |
| // The iteration order of LazyOrderedNodesByEeightedLine is not determined until the first |
| // call to Next or NodeSlice. After that, the iteration order is fixed. |
| type LazyOrderedNodesByWeightedLines struct { |
| iter OrderedNodes |
| nodes map[int64]graph.Node |
| edges map[int64]map[int64]graph.WeightedLine |
| } |
| |
| // NewLazyOrderedNodesByWeightedLines returns a LazyOrderedNodesByLines initialized with the |
| // provided nodes. |
| func NewLazyOrderedNodesByWeightedLines(nodes map[int64]graph.Node, edges map[int64]map[int64]graph.WeightedLine) *LazyOrderedNodesByWeightedLines { |
| return &LazyOrderedNodesByWeightedLines{nodes: nodes, edges: edges} |
| } |
| |
| // Len returns the remaining number of nodes to be iterated over. |
| func (n *LazyOrderedNodesByWeightedLines) Len() int { |
| if n.iter.nodes == nil { |
| return len(n.edges) |
| } |
| return n.iter.Len() |
| } |
| |
| // Next returns whether the next call of Node will return a valid node. |
| func (n *LazyOrderedNodesByWeightedLines) Next() bool { |
| if n.iter.nodes == nil { |
| n.fillSlice() |
| } |
| return n.iter.Next() |
| } |
| |
| // Node returns the current node of the iterator. Next must have been |
| // called prior to a call to Node. |
| func (n *LazyOrderedNodesByWeightedLines) Node() graph.Node { |
| return n.iter.Node() |
| } |
| |
| // NodeSlice returns all the remaining nodes in the iterator and advances |
| // the iterator. |
| func (n *LazyOrderedNodesByWeightedLines) NodeSlice() []graph.Node { |
| if n.iter.nodes == nil { |
| n.fillSlice() |
| } |
| return n.iter.NodeSlice() |
| } |
| |
| // Reset returns the iterator to its initial state. |
| func (n *LazyOrderedNodesByWeightedLines) Reset() { |
| n.iter.Reset() |
| } |
| |
| func (n *LazyOrderedNodesByWeightedLines) fillSlice() { |
| n.iter = OrderedNodes{idx: -1, nodes: make([]graph.Node, len(n.edges))} |
| i := 0 |
| for id := range n.edges { |
| n.iter.nodes[i] = n.nodes[id] |
| i++ |
| } |
| n.nodes = nil |
| n.edges = nil |
| } |
| |
| // ImplicitNodes implements the graph.Nodes interface for a set of nodes over |
| // a contiguous ID range. |
| type ImplicitNodes struct { |
| beg, end int |
| curr int |
| newNode func(id int) graph.Node |
| } |
| |
| // NewImplicitNodes returns a new implicit node iterator spanning nodes in [beg,end). |
| // The provided new func maps the id to a graph.Node. NewImplicitNodes will panic |
| // if beg is greater than end. |
| func NewImplicitNodes(beg, end int, new func(id int) graph.Node) *ImplicitNodes { |
| if beg > end { |
| panic("iterator: invalid range") |
| } |
| return &ImplicitNodes{beg: beg, end: end, curr: beg - 1, newNode: new} |
| } |
| |
| // Len returns the remaining number of nodes to be iterated over. |
| func (n *ImplicitNodes) Len() int { |
| return n.end - n.curr - 1 |
| } |
| |
| // Next returns whether the next call of Node will return a valid node. |
| func (n *ImplicitNodes) Next() bool { |
| if n.curr == n.end { |
| return false |
| } |
| n.curr++ |
| return n.curr < n.end |
| } |
| |
| // Node returns the current node of the iterator. Next must have been |
| // called prior to a call to Node. |
| func (n *ImplicitNodes) Node() graph.Node { |
| if n.Len() == -1 || n.curr < n.beg { |
| return nil |
| } |
| return n.newNode(n.curr) |
| } |
| |
| // Reset returns the iterator to its initial state. |
| func (n *ImplicitNodes) Reset() { |
| n.curr = n.beg - 1 |
| } |
| |
| // NodeSlice returns all the remaining nodes in the iterator and advances |
| // the iterator. |
| func (n *ImplicitNodes) NodeSlice() []graph.Node { |
| if n.Len() == 0 { |
| return nil |
| } |
| nodes := make([]graph.Node, 0, n.Len()) |
| for n.curr++; n.curr < n.end; n.curr++ { |
| nodes = append(nodes, n.newNode(n.curr)) |
| } |
| return nodes |
| } |