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  }