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  }