diff options
Diffstat (limited to 'vendor/petgraph-0.6.5/src/graphmap.rs')
| -rw-r--r-- | vendor/petgraph-0.6.5/src/graphmap.rs | 1504 |
1 files changed, 0 insertions, 1504 deletions
diff --git a/vendor/petgraph-0.6.5/src/graphmap.rs b/vendor/petgraph-0.6.5/src/graphmap.rs deleted file mode 100644 index 9e1bdd36..00000000 --- a/vendor/petgraph-0.6.5/src/graphmap.rs +++ /dev/null @@ -1,1504 +0,0 @@ -//! `GraphMap<N, E, Ty>` is a graph datastructure where node values are mapping -//! keys. - -use indexmap::map::Keys; -use indexmap::map::{Iter as IndexMapIter, IterMut as IndexMapIterMut}; -use indexmap::IndexMap; -use std::cmp::Ordering; -use std::collections::hash_map::RandomState; -use std::collections::HashSet; -use std::fmt; -use std::hash::{self, BuildHasher, Hash}; -use std::iter::Copied; -use std::iter::FromIterator; -use std::marker::PhantomData; -use std::mem; -use std::ops::{Deref, Index, IndexMut}; -use std::slice::Iter; - -use crate::{Directed, Direction, EdgeType, Incoming, Outgoing, Undirected}; - -use crate::graph::node_index; -use crate::graph::Graph; -use crate::visit; -use crate::IntoWeightedEdge; - -#[cfg(feature = "rayon")] -use indexmap::map::rayon::{ParIter, ParIterMut, ParKeys}; -#[cfg(feature = "rayon")] -use rayon::prelude::*; - -/// A `GraphMap` with undirected edges. -/// -/// For example, an edge between *1* and *2* is equivalent to an edge between -/// *2* and *1*. -pub type UnGraphMap<N, E> = GraphMap<N, E, Undirected>; -/// A `GraphMap` with directed edges. -/// -/// For example, an edge from *1* to *2* is distinct from an edge from *2* to -/// *1*. -pub type DiGraphMap<N, E> = GraphMap<N, E, Directed>; - -/// `GraphMap<N, E, Ty>` is a graph datastructure using an associative array -/// of its node weights `N`. -/// -/// It uses an combined adjacency list and sparse adjacency matrix -/// representation, using **O(|V| + |E|)** space, and allows testing for edge -/// existence in constant time. -/// -/// `GraphMap` is parameterized over: -/// -/// - Associated data `N` for nodes and `E` for edges, called *weights*. -/// - The node weight `N` must implement `Copy` and will be used as node -/// identifier, duplicated into several places in the data structure. -/// It must be suitable as a hash table key (implementing `Eq + Hash`). -/// The node type must also implement `Ord` so that the implementation can -/// order the pair (`a`, `b`) for an edge connecting any two nodes `a` and `b`. -/// - `E` can be of arbitrary type. -/// - Edge type `Ty` that determines whether the graph edges are directed or -/// undirected. -/// -/// You can use the type aliases `UnGraphMap` and `DiGraphMap` for convenience. -/// -/// `GraphMap` does not allow parallel edges, but self loops are allowed. -/// -/// Depends on crate feature `graphmap` (default). -#[derive(Clone)] -pub struct GraphMap<N, E, Ty, S = RandomState> -where - S: BuildHasher, -{ - nodes: IndexMap<N, Vec<(N, CompactDirection)>, S>, - edges: IndexMap<(N, N), E, S>, - ty: PhantomData<Ty>, -} - -impl<N: Eq + Hash + fmt::Debug, E: fmt::Debug, Ty: EdgeType, S: BuildHasher> fmt::Debug - for GraphMap<N, E, Ty, S> -{ - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - self.nodes.fmt(f) - } -} - -/// A trait group for `GraphMap`'s node identifier. -pub trait NodeTrait: Copy + Ord + Hash {} -impl<N> NodeTrait for N where N: Copy + Ord + Hash {} - -// non-repr(usize) version of Direction -#[derive(Copy, Clone, Debug, PartialEq)] -enum CompactDirection { - Outgoing, - Incoming, -} - -impl CompactDirection { - /// Return the opposite `CompactDirection`. - #[inline] - pub fn opposite(self) -> CompactDirection { - match self { - CompactDirection::Outgoing => CompactDirection::Incoming, - CompactDirection::Incoming => CompactDirection::Outgoing, - } - } -} - -impl From<Direction> for CompactDirection { - fn from(d: Direction) -> Self { - match d { - Outgoing => CompactDirection::Outgoing, - Incoming => CompactDirection::Incoming, - } - } -} - -impl From<CompactDirection> for Direction { - fn from(d: CompactDirection) -> Self { - match d { - CompactDirection::Outgoing => Outgoing, - CompactDirection::Incoming => Incoming, - } - } -} - -impl PartialEq<Direction> for CompactDirection { - fn eq(&self, rhs: &Direction) -> bool { - (*self as usize) == (*rhs as usize) - } -} - -#[cfg(feature = "serde-1")] -impl<N, E, Ty, S> serde::Serialize for GraphMap<N, E, Ty, S> -where - Ty: EdgeType, - N: NodeTrait + serde::Serialize, - E: serde::Serialize, - S: BuildHasher, - Self: Clone, -{ - /// Serializes the given `GraphMap` into the same format as the standard - /// `Graph`. Needs feature `serde-1`. - /// - /// Note: the graph has to be `Clone` for this to work. - fn serialize<Ser>(&self, serializer: Ser) -> Result<Ser::Ok, Ser::Error> - where - Ser: serde::Serializer, - { - let cloned_graph: GraphMap<N, E, Ty, S> = GraphMap::clone(self); - let equivalent_graph: Graph<N, E, Ty, u32> = cloned_graph.into_graph(); - equivalent_graph.serialize(serializer) - } -} - -#[cfg(feature = "serde-1")] -impl<'de, N, E, Ty, S> serde::Deserialize<'de> for GraphMap<N, E, Ty, S> -where - Ty: EdgeType, - N: NodeTrait + serde::Deserialize<'de>, - E: Clone + serde::Deserialize<'de>, - S: BuildHasher + Default, -{ - /// Deserializes into a new `GraphMap` from the same format as the standard - /// `Graph`. Needs feature `serde-1`. - /// - /// **Warning**: When deseralizing a graph that was not originally a `GraphMap`, - /// the restrictions from [`from_graph`](#method.from_graph) apply. - /// - /// Note: The edge weights have to be `Clone` for this to work. - fn deserialize<D>(deserializer: D) -> Result<Self, D::Error> - where - D: serde::Deserializer<'de>, - { - let equivalent_graph: Graph<N, E, Ty, u32> = Graph::deserialize(deserializer)?; - Ok(GraphMap::from_graph(equivalent_graph)) - } -} - -impl<N, E, Ty, S> GraphMap<N, E, Ty, S> -where - N: NodeTrait, - Ty: EdgeType, - S: BuildHasher, -{ - /// Create a new `GraphMap` - pub fn new() -> Self - where - S: Default, - { - Self::default() - } - - /// Create a new `GraphMap` with estimated capacity. - pub fn with_capacity(nodes: usize, edges: usize) -> Self - where - S: Default, - { - Self { - nodes: IndexMap::with_capacity_and_hasher(nodes, S::default()), - edges: IndexMap::with_capacity_and_hasher(edges, S::default()), - ty: PhantomData, - } - } - - /// Create a new `GraphMap` with estimated capacity, and specified hasher. - pub fn with_capacity_and_hasher(nodes: usize, edges: usize, hasher: S) -> Self - where - S: Clone, - { - Self { - nodes: IndexMap::with_capacity_and_hasher(nodes, hasher.clone()), - edges: IndexMap::with_capacity_and_hasher(edges, hasher), - ty: PhantomData, - } - } - - /// Return the current node and edge capacity of the graph. - pub fn capacity(&self) -> (usize, usize) { - (self.nodes.capacity(), self.edges.capacity()) - } - - /// Use their natural order to map the node pair (a, b) to a canonical edge id. - #[inline] - fn edge_key(a: N, b: N) -> (N, N) { - if Ty::is_directed() || a <= b { - (a, b) - } else { - (b, a) - } - } - - /// Whether the graph has directed edges. - pub fn is_directed(&self) -> bool { - Ty::is_directed() - } - - /// Create a new `GraphMap` from an iterable of edges. - /// - /// Node values are taken directly from the list. - /// Edge weights `E` may either be specified in the list, - /// or they are filled with default values. - /// - /// Nodes are inserted automatically to match the edges. - /// - /// ``` - /// use petgraph::graphmap::UnGraphMap; - /// - /// // Create a new undirected GraphMap. - /// // Use a type hint to have `()` be the edge weight type. - /// let gr = UnGraphMap::<_, ()>::from_edges(&[ - /// (0, 1), (0, 2), (0, 3), - /// (1, 2), (1, 3), - /// (2, 3), - /// ]); - /// ``` - pub fn from_edges<I>(iterable: I) -> Self - where - I: IntoIterator, - I::Item: IntoWeightedEdge<E, NodeId = N>, - S: Default, - { - Self::from_iter(iterable) - } - - /// Return the number of nodes in the graph. - pub fn node_count(&self) -> usize { - self.nodes.len() - } - - /// Return the number of edges in the graph. - pub fn edge_count(&self) -> usize { - self.edges.len() - } - - /// Remove all nodes and edges - pub fn clear(&mut self) { - self.nodes.clear(); - self.edges.clear(); - } - - /// Add node `n` to the graph. - pub fn add_node(&mut self, n: N) -> N { - self.nodes.entry(n).or_default(); - n - } - - /// Return `true` if node `n` was removed. - /// - /// Computes in **O(V)** time, due to the removal of edges with other nodes. - pub fn remove_node(&mut self, n: N) -> bool { - let links = match self.nodes.swap_remove(&n) { - None => return false, - Some(sus) => sus, - }; - for (succ, dir) in links { - let edge = if dir == CompactDirection::Outgoing { - Self::edge_key(n, succ) - } else { - Self::edge_key(succ, n) - }; - // remove all successor links - self.remove_single_edge(&succ, &n, dir.opposite()); - // Remove all edge values - self.edges.swap_remove(&edge); - } - true - } - - /// Return `true` if the node is contained in the graph. - pub fn contains_node(&self, n: N) -> bool { - self.nodes.contains_key(&n) - } - - /// Add an edge connecting `a` and `b` to the graph, with associated - /// data `weight`. For a directed graph, the edge is directed from `a` - /// to `b`. - /// - /// Inserts nodes `a` and/or `b` if they aren't already part of the graph. - /// - /// Return `None` if the edge did not previously exist, otherwise, - /// the associated data is updated and the old value is returned - /// as `Some(old_weight)`. - /// - /// ``` - /// // Create a GraphMap with directed edges, and add one edge to it - /// use petgraph::graphmap::DiGraphMap; - /// - /// let mut g = DiGraphMap::new(); - /// g.add_edge("x", "y", -1); - /// assert_eq!(g.node_count(), 2); - /// assert_eq!(g.edge_count(), 1); - /// assert!(g.contains_edge("x", "y")); - /// assert!(!g.contains_edge("y", "x")); - /// ``` - pub fn add_edge(&mut self, a: N, b: N, weight: E) -> Option<E> { - if let old @ Some(_) = self.edges.insert(Self::edge_key(a, b), weight) { - old - } else { - // insert in the adjacency list if it's a new edge - self.nodes - .entry(a) - .or_insert_with(|| Vec::with_capacity(1)) - .push((b, CompactDirection::Outgoing)); - if a != b { - // self loops don't have the Incoming entry - self.nodes - .entry(b) - .or_insert_with(|| Vec::with_capacity(1)) - .push((a, CompactDirection::Incoming)); - } - None - } - } - - /// Remove edge relation from a to b - /// - /// Return `true` if it did exist. - fn remove_single_edge(&mut self, a: &N, b: &N, dir: CompactDirection) -> bool { - match self.nodes.get_mut(a) { - None => false, - Some(sus) => { - if Ty::is_directed() { - match sus.iter().position(|elt| elt == &(*b, dir)) { - Some(index) => { - sus.swap_remove(index); - true - } - None => false, - } - } else { - match sus.iter().position(|elt| &elt.0 == b) { - Some(index) => { - sus.swap_remove(index); - true - } - None => false, - } - } - } - } - } - - /// Remove edge from `a` to `b` from the graph and return the edge weight. - /// - /// Return `None` if the edge didn't exist. - /// - /// ``` - /// // Create a GraphMap with undirected edges, and add and remove an edge. - /// use petgraph::graphmap::UnGraphMap; - /// - /// let mut g = UnGraphMap::new(); - /// g.add_edge("x", "y", -1); - /// - /// let edge_data = g.remove_edge("y", "x"); - /// assert_eq!(edge_data, Some(-1)); - /// assert_eq!(g.edge_count(), 0); - /// ``` - pub fn remove_edge(&mut self, a: N, b: N) -> Option<E> { - let exist1 = self.remove_single_edge(&a, &b, CompactDirection::Outgoing); - let exist2 = if a != b { - self.remove_single_edge(&b, &a, CompactDirection::Incoming) - } else { - exist1 - }; - let weight = self.edges.swap_remove(&Self::edge_key(a, b)); - debug_assert!(exist1 == exist2 && exist1 == weight.is_some()); - weight - } - - /// Return `true` if the edge connecting `a` with `b` is contained in the graph. - pub fn contains_edge(&self, a: N, b: N) -> bool { - self.edges.contains_key(&Self::edge_key(a, b)) - } - - /// Return an iterator over the nodes of the graph. - /// - /// Iterator element type is `N`. - pub fn nodes(&self) -> Nodes<'_, N> { - Nodes { - iter: self.nodes.keys().copied(), - } - } - - /// Return a parallel iterator over the nodes of the graph. - /// - /// Iterator element type is `N`. - #[cfg(feature = "rayon")] - pub fn par_nodes(&self) -> ParNodes<'_, N> - where - N: Send + Sync, - { - ParNodes { - iter: self.nodes.par_keys(), - } - } - - /// Return an iterator of all nodes with an edge starting from `a`. - /// - /// - `Directed`: Outgoing edges from `a`. - /// - `Undirected`: All edges from or to `a`. - /// - /// Produces an empty iterator if the node doesn't exist.<br> - /// Iterator element type is `N`. - pub fn neighbors(&self, a: N) -> Neighbors<N, Ty> { - Neighbors { - iter: match self.nodes.get(&a) { - Some(neigh) => neigh.iter(), - None => [].iter(), - }, - ty: self.ty, - } - } - - /// Return an iterator of all neighbors that have an edge between them and - /// `a`, in the specified direction. - /// If the graph's edges are undirected, this is equivalent to *.neighbors(a)*. - /// - /// - `Directed`, `Outgoing`: All edges from `a`. - /// - `Directed`, `Incoming`: All edges to `a`. - /// - `Undirected`: All edges from or to `a`. - /// - /// Produces an empty iterator if the node doesn't exist.<br> - /// Iterator element type is `N`. - pub fn neighbors_directed(&self, a: N, dir: Direction) -> NeighborsDirected<N, Ty> { - NeighborsDirected { - iter: match self.nodes.get(&a) { - Some(neigh) => neigh.iter(), - None => [].iter(), - }, - start_node: a, - dir, - ty: self.ty, - } - } - - /// Return an iterator of target nodes with an edge starting from `a`, - /// paired with their respective edge weights. - /// - /// - `Directed`: Outgoing edges from `a`. - /// - `Undirected`: All edges from or to `a`. - /// - /// Produces an empty iterator if the node doesn't exist.<br> - /// Iterator element type is `(N, N, &E)`. - pub fn edges(&self, a: N) -> Edges<N, E, Ty, S> { - Edges { - from: a, - iter: self.neighbors(a), - edges: &self.edges, - } - } - - /// Return an iterator of target nodes with an edge starting from `a`, - /// paired with their respective edge weights. - /// - /// - `Directed`, `Outgoing`: All edges from `a`. - /// - `Directed`, `Incoming`: All edges to `a`. - /// - `Undirected`, `Outgoing`: All edges connected to `a`, with `a` being the source of each - /// edge. - /// - `Undirected`, `Incoming`: All edges connected to `a`, with `a` being the target of each - /// edge. - /// - /// Produces an empty iterator if the node doesn't exist.<br> - /// Iterator element type is `(N, N, &E)`. - pub fn edges_directed(&self, a: N, dir: Direction) -> EdgesDirected<N, E, Ty, S> { - EdgesDirected { - from: a, - iter: self.neighbors_directed(a, dir), - dir, - edges: &self.edges, - } - } - - /// Return a reference to the edge weight connecting `a` with `b`, or - /// `None` if the edge does not exist in the graph. - pub fn edge_weight(&self, a: N, b: N) -> Option<&E> { - self.edges.get(&Self::edge_key(a, b)) - } - - /// Return a mutable reference to the edge weight connecting `a` with `b`, or - /// `None` if the edge does not exist in the graph. - pub fn edge_weight_mut(&mut self, a: N, b: N) -> Option<&mut E> { - self.edges.get_mut(&Self::edge_key(a, b)) - } - - /// Return an iterator over all edges of the graph with their weight in arbitrary order. - /// - /// Iterator element type is `(N, N, &E)` - pub fn all_edges(&self) -> AllEdges<N, E, Ty> { - AllEdges { - inner: self.edges.iter(), - ty: self.ty, - } - } - - /// Return an iterator over all edges of the graph in arbitrary order, with a mutable reference - /// to their weight. - /// - /// Iterator element type is `(N, N, &mut E)` - pub fn all_edges_mut(&mut self) -> AllEdgesMut<N, E, Ty> { - AllEdgesMut { - inner: self.edges.iter_mut(), - ty: self.ty, - } - } - - /// Return a parallel iterator over all edges of the graph with their weight in arbitrary - /// order. - /// - /// Iterator element type is `(N, N, &E)` - #[cfg(feature = "rayon")] - pub fn par_all_edges(&self) -> ParAllEdges<N, E, Ty> - where - N: Send + Sync, - E: Sync, - { - ParAllEdges { - inner: self.edges.par_iter(), - ty: PhantomData, - } - } - - /// Return a parallel iterator over all edges of the graph in arbitrary order, with a mutable - /// reference to their weight. - /// - /// Iterator element type is `(N, N, &mut E)` - #[cfg(feature = "rayon")] - pub fn par_all_edges_mut(&mut self) -> ParAllEdgesMut<N, E, Ty> - where - N: Send + Sync, - E: Send, - { - ParAllEdgesMut { - inner: self.edges.par_iter_mut(), - ty: PhantomData, - } - } - - /// Return a `Graph` that corresponds to this `GraphMap`. - /// - /// 1. Note that node and edge indices in the `Graph` have nothing in common - /// with the `GraphMap`s node weights `N`. The node weights `N` are used as - /// node weights in the resulting `Graph`, too. - /// 2. Note that the index type is user-chosen. - /// - /// Computes in **O(|V| + |E|)** time (average). - /// - /// **Panics** if the number of nodes or edges does not fit with - /// the resulting graph's index type. - pub fn into_graph<Ix>(self) -> Graph<N, E, Ty, Ix> - where - Ix: crate::graph::IndexType, - { - // assuming two successive iterations of the same hashmap produce the same order - let mut gr = Graph::with_capacity(self.node_count(), self.edge_count()); - for (&node, _) in &self.nodes { - gr.add_node(node); - } - for ((a, b), edge_weight) in self.edges { - let ai = self.nodes.get_index_of(&a).unwrap(); - let bi = self.nodes.get_index_of(&b).unwrap(); - gr.add_edge(node_index(ai), node_index(bi), edge_weight); - } - gr - } - - /// Creates a `GraphMap` that corresponds to the given `Graph`. - /// - /// **Warning**: Nodes with the same weight are merged and only the last parallel edge - /// is kept. Node and edge indices of the `Graph` are lost. Only use this function - /// if the node weights are distinct and there are no parallel edges. - /// - /// Computes in **O(|V| + |E|)** time (average). - pub fn from_graph<Ix>(graph: Graph<N, E, Ty, Ix>) -> Self - where - Ix: crate::graph::IndexType, - E: Clone, - S: Default, - { - let mut new_graph: GraphMap<N, E, Ty, S> = - GraphMap::with_capacity(graph.node_count(), graph.edge_count()); - - for node in graph.raw_nodes() { - new_graph.add_node(node.weight); - } - - for edge in graph.edge_indices() { - let (a, b) = graph.edge_endpoints(edge).unwrap(); - new_graph.add_edge( - *graph.node_weight(a).unwrap(), - *graph.node_weight(b).unwrap(), - graph.edge_weight(edge).unwrap().clone(), - ); - } - - new_graph - } -} - -/// Create a new `GraphMap` from an iterable of edges. -impl<N, E, Ty, Item, S> FromIterator<Item> for GraphMap<N, E, Ty, S> -where - Item: IntoWeightedEdge<E, NodeId = N>, - N: NodeTrait, - Ty: EdgeType, - S: BuildHasher + Default, -{ - fn from_iter<I>(iterable: I) -> Self - where - I: IntoIterator<Item = Item>, - { - let iter = iterable.into_iter(); - let (low, _) = iter.size_hint(); - let mut g = Self::with_capacity(0, low); - g.extend(iter); - g - } -} - -/// Extend the graph from an iterable of edges. -/// -/// Nodes are inserted automatically to match the edges. -impl<N, E, Ty, Item, S> Extend<Item> for GraphMap<N, E, Ty, S> -where - Item: IntoWeightedEdge<E, NodeId = N>, - N: NodeTrait, - Ty: EdgeType, - S: BuildHasher, -{ - fn extend<I>(&mut self, iterable: I) - where - I: IntoIterator<Item = Item>, - { - let iter = iterable.into_iter(); - let (low, _) = iter.size_hint(); - self.edges.reserve(low); - - for elt in iter { - let (source, target, weight) = elt.into_weighted_edge(); - self.add_edge(source, target, weight); - } - } -} - -iterator_wrap! { - impl (Iterator DoubleEndedIterator ExactSizeIterator) for - #[derive(Debug, Clone)] - struct Nodes <'a, N> where { N: 'a + NodeTrait } - item: N, - iter: Copied<Keys<'a, N, Vec<(N, CompactDirection)>>>, -} - -#[derive(Debug, Clone)] -pub struct Neighbors<'a, N, Ty = Undirected> -where - N: 'a, - Ty: EdgeType, -{ - iter: Iter<'a, (N, CompactDirection)>, - ty: PhantomData<Ty>, -} - -impl<'a, N, Ty> Iterator for Neighbors<'a, N, Ty> -where - N: NodeTrait, - Ty: EdgeType, -{ - type Item = N; - fn next(&mut self) -> Option<N> { - if Ty::is_directed() { - (&mut self.iter) - .filter_map(|&(n, dir)| if dir == Outgoing { Some(n) } else { None }) - .next() - } else { - self.iter.next().map(|&(n, _)| n) - } - } - fn size_hint(&self) -> (usize, Option<usize>) { - let (lower, upper) = self.iter.size_hint(); - if Ty::is_directed() { - (0, upper) - } else { - (lower, upper) - } - } -} - -#[derive(Debug, Clone)] -pub struct NeighborsDirected<'a, N, Ty> -where - N: 'a, - Ty: EdgeType, -{ - iter: Iter<'a, (N, CompactDirection)>, - start_node: N, - dir: Direction, - ty: PhantomData<Ty>, -} - -impl<'a, N, Ty> Iterator for NeighborsDirected<'a, N, Ty> -where - N: NodeTrait, - Ty: EdgeType, -{ - type Item = N; - fn next(&mut self) -> Option<N> { - if Ty::is_directed() { - let self_dir = self.dir; - let start_node = self.start_node; - (&mut self.iter) - .filter_map(move |&(n, dir)| { - if dir == self_dir || n == start_node { - Some(n) - } else { - None - } - }) - .next() - } else { - self.iter.next().map(|&(n, _)| n) - } - } - fn size_hint(&self) -> (usize, Option<usize>) { - let (lower, upper) = self.iter.size_hint(); - if Ty::is_directed() { - (0, upper) - } else { - (lower, upper) - } - } -} - -#[derive(Debug, Clone)] -pub struct Edges<'a, N, E: 'a, Ty, S = RandomState> -where - N: 'a + NodeTrait, - Ty: EdgeType, - S: BuildHasher, -{ - from: N, - edges: &'a IndexMap<(N, N), E, S>, - iter: Neighbors<'a, N, Ty>, -} - -impl<'a, N, E, Ty, S> Iterator for Edges<'a, N, E, Ty, S> -where - N: 'a + NodeTrait, - E: 'a, - Ty: EdgeType, - S: BuildHasher, -{ - type Item = (N, N, &'a E); - fn next(&mut self) -> Option<Self::Item> { - self.iter.next().map(|b| { - let a = self.from; - match self.edges.get(&GraphMap::<N, E, Ty>::edge_key(a, b)) { - None => unreachable!(), - Some(edge) => (a, b, edge), - } - }) - } - fn size_hint(&self) -> (usize, Option<usize>) { - self.iter.size_hint() - } -} - -#[derive(Debug, Clone)] -pub struct EdgesDirected<'a, N, E: 'a, Ty, S = RandomState> -where - N: 'a + NodeTrait, - Ty: EdgeType, - S: BuildHasher, -{ - from: N, - dir: Direction, - edges: &'a IndexMap<(N, N), E, S>, - iter: NeighborsDirected<'a, N, Ty>, -} - -impl<'a, N, E, Ty, S> Iterator for EdgesDirected<'a, N, E, Ty, S> -where - N: 'a + NodeTrait, - E: 'a, - Ty: EdgeType, - S: BuildHasher, -{ - type Item = (N, N, &'a E); - fn next(&mut self) -> Option<Self::Item> { - self.iter.next().map(|mut b| { - let mut a = self.from; - if self.dir == Direction::Incoming { - mem::swap(&mut a, &mut b); - } - match self.edges.get(&GraphMap::<N, E, Ty>::edge_key(a, b)) { - None => unreachable!(), - Some(edge) => (a, b, edge), - } - }) - } - fn size_hint(&self) -> (usize, Option<usize>) { - self.iter.size_hint() - } -} - -#[derive(Debug, Clone)] -pub struct AllEdges<'a, N, E: 'a, Ty> -where - N: 'a + NodeTrait, -{ - inner: IndexMapIter<'a, (N, N), E>, - ty: PhantomData<Ty>, -} - -impl<'a, N, E, Ty> Iterator for AllEdges<'a, N, E, Ty> -where - N: 'a + NodeTrait, - E: 'a, - Ty: EdgeType, -{ - type Item = (N, N, &'a E); - fn next(&mut self) -> Option<Self::Item> { - self.inner.next().map(|(&(a, b), v)| (a, b, v)) - } - - fn size_hint(&self) -> (usize, Option<usize>) { - self.inner.size_hint() - } - - fn count(self) -> usize { - self.inner.count() - } - - fn nth(&mut self, n: usize) -> Option<Self::Item> { - self.inner - .nth(n) - .map(|(&(n1, n2), weight)| (n1, n2, weight)) - } - - fn last(self) -> Option<Self::Item> { - self.inner - .last() - .map(|(&(n1, n2), weight)| (n1, n2, weight)) - } -} - -impl<'a, N, E, Ty> DoubleEndedIterator for AllEdges<'a, N, E, Ty> -where - N: 'a + NodeTrait, - E: 'a, - Ty: EdgeType, -{ - fn next_back(&mut self) -> Option<Self::Item> { - self.inner - .next_back() - .map(|(&(n1, n2), weight)| (n1, n2, weight)) - } -} - -pub struct AllEdgesMut<'a, N, E: 'a, Ty> -where - N: 'a + NodeTrait, -{ - inner: IndexMapIterMut<'a, (N, N), E>, // TODO: change to something that implements Debug + Clone? - ty: PhantomData<Ty>, -} - -impl<'a, N, E, Ty> Iterator for AllEdgesMut<'a, N, E, Ty> -where - N: 'a + NodeTrait, - E: 'a, - Ty: EdgeType, -{ - type Item = (N, N, &'a mut E); - fn next(&mut self) -> Option<Self::Item> { - self.inner - .next() - .map(|(&(n1, n2), weight)| (n1, n2, weight)) - } - - fn size_hint(&self) -> (usize, Option<usize>) { - self.inner.size_hint() - } - - fn count(self) -> usize { - self.inner.count() - } - - fn nth(&mut self, n: usize) -> Option<Self::Item> { - self.inner - .nth(n) - .map(|(&(n1, n2), weight)| (n1, n2, weight)) - } - - fn last(self) -> Option<Self::Item> { - self.inner - .last() - .map(|(&(n1, n2), weight)| (n1, n2, weight)) - } -} - -impl<'a, N, E, Ty> DoubleEndedIterator for AllEdgesMut<'a, N, E, Ty> -where - N: 'a + NodeTrait, - E: 'a, - Ty: EdgeType, -{ - fn next_back(&mut self) -> Option<Self::Item> { - self.inner - .next_back() - .map(|(&(n1, n2), weight)| (n1, n2, weight)) - } -} - -/// Index `GraphMap` by node pairs to access edge weights. -impl<N, E, Ty, S> Index<(N, N)> for GraphMap<N, E, Ty, S> -where - N: NodeTrait, - Ty: EdgeType, - S: BuildHasher, -{ - type Output = E; - fn index(&self, index: (N, N)) -> &E { - let index = Self::edge_key(index.0, index.1); - self.edge_weight(index.0, index.1) - .expect("GraphMap::index: no such edge") - } -} - -/// Index `GraphMap` by node pairs to access edge weights. -impl<N, E, Ty, S> IndexMut<(N, N)> for GraphMap<N, E, Ty, S> -where - N: NodeTrait, - Ty: EdgeType, - S: BuildHasher, -{ - fn index_mut(&mut self, index: (N, N)) -> &mut E { - let index = Self::edge_key(index.0, index.1); - self.edge_weight_mut(index.0, index.1) - .expect("GraphMap::index: no such edge") - } -} - -/// Create a new empty `GraphMap`. -impl<N, E, Ty, S> Default for GraphMap<N, E, Ty, S> -where - N: NodeTrait, - Ty: EdgeType, - S: BuildHasher + Default, -{ - fn default() -> Self { - GraphMap::with_capacity(0, 0) - } -} - -/// A reference that is hashed and compared by its pointer value. -/// -/// `Ptr` is used for certain configurations of `GraphMap`, -/// in particular in the combination where the node type for -/// `GraphMap` is something of type for example `Ptr(&Cell<T>)`, -/// with the `Cell<T>` being `TypedArena` allocated. -pub struct Ptr<'b, T: 'b>(pub &'b T); - -impl<'b, T> Copy for Ptr<'b, T> {} -impl<'b, T> Clone for Ptr<'b, T> { - fn clone(&self) -> Self { - *self - } -} - -fn ptr_eq<T>(a: *const T, b: *const T) -> bool { - a == b -} - -impl<'b, T> PartialEq for Ptr<'b, T> { - /// Ptr compares by pointer equality, i.e if they point to the same value - fn eq(&self, other: &Ptr<'b, T>) -> bool { - ptr_eq(self.0, other.0) - } -} - -impl<'b, T> PartialOrd for Ptr<'b, T> { - fn partial_cmp(&self, other: &Ptr<'b, T>) -> Option<Ordering> { - Some(self.cmp(other)) - } -} - -impl<'b, T> Ord for Ptr<'b, T> { - /// Ptr is ordered by pointer value, i.e. an arbitrary but stable and total order. - fn cmp(&self, other: &Ptr<'b, T>) -> Ordering { - let a: *const T = self.0; - let b: *const T = other.0; - a.cmp(&b) - } -} - -impl<'b, T> Deref for Ptr<'b, T> { - type Target = T; - fn deref(&self) -> &T { - self.0 - } -} - -impl<'b, T> Eq for Ptr<'b, T> {} - -impl<'b, T> Hash for Ptr<'b, T> { - fn hash<H: hash::Hasher>(&self, st: &mut H) { - let ptr = (self.0) as *const T; - ptr.hash(st) - } -} - -impl<'b, T: fmt::Debug> fmt::Debug for Ptr<'b, T> { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - self.0.fmt(f) - } -} - -#[derive(Debug, Clone)] -pub struct NodeIdentifiers<'a, N, E: 'a, Ty> -where - N: 'a + NodeTrait, -{ - iter: IndexMapIter<'a, N, Vec<(N, CompactDirection)>>, - ty: PhantomData<Ty>, - edge_ty: PhantomData<E>, -} - -impl<'a, N, E, Ty> Iterator for NodeIdentifiers<'a, N, E, Ty> -where - N: 'a + NodeTrait, - E: 'a, - Ty: EdgeType, -{ - type Item = N; - fn next(&mut self) -> Option<Self::Item> { - self.iter.next().map(|(&n, _)| n) - } - fn size_hint(&self) -> (usize, Option<usize>) { - self.iter.size_hint() - } -} - -#[derive(Debug, Clone)] -pub struct NodeReferences<'a, N, E: 'a, Ty> -where - N: 'a + NodeTrait, -{ - iter: IndexMapIter<'a, N, Vec<(N, CompactDirection)>>, - ty: PhantomData<Ty>, - edge_ty: PhantomData<E>, -} - -impl<'a, N, E, Ty> Iterator for NodeReferences<'a, N, E, Ty> -where - N: 'a + NodeTrait, - E: 'a, - Ty: EdgeType, -{ - type Item = (N, &'a N); - fn next(&mut self) -> Option<Self::Item> { - self.iter.next().map(|(n, _)| (*n, n)) - } - fn size_hint(&self) -> (usize, Option<usize>) { - self.iter.size_hint() - } -} - -impl<N, E, Ty, S> visit::GraphBase for GraphMap<N, E, Ty, S> -where - N: Copy + PartialEq, - S: BuildHasher, -{ - type NodeId = N; - type EdgeId = (N, N); -} - -impl<N, E, Ty, S> visit::Data for GraphMap<N, E, Ty, S> -where - N: Copy + PartialEq, - Ty: EdgeType, - S: BuildHasher, -{ - type NodeWeight = N; - type EdgeWeight = E; -} - -impl<N, E, Ty, S> visit::Visitable for GraphMap<N, E, Ty, S> -where - N: Copy + Ord + Hash, - Ty: EdgeType, - S: BuildHasher, -{ - type Map = HashSet<N>; - fn visit_map(&self) -> HashSet<N> { - HashSet::with_capacity(self.node_count()) - } - fn reset_map(&self, map: &mut Self::Map) { - map.clear(); - } -} - -impl<N, E, Ty, S> visit::GraphProp for GraphMap<N, E, Ty, S> -where - N: NodeTrait, - Ty: EdgeType, - S: BuildHasher, -{ - type EdgeType = Ty; -} - -impl<'a, N, E, Ty, S> visit::IntoNodeReferences for &'a GraphMap<N, E, Ty, S> -where - N: NodeTrait, - Ty: EdgeType, - S: BuildHasher, -{ - type NodeRef = (N, &'a N); - type NodeReferences = NodeReferences<'a, N, E, Ty>; - fn node_references(self) -> Self::NodeReferences { - NodeReferences { - iter: self.nodes.iter(), - ty: self.ty, - edge_ty: PhantomData, - } - } -} - -impl<'a, N, E: 'a, Ty, S> visit::IntoNodeIdentifiers for &'a GraphMap<N, E, Ty, S> -where - N: NodeTrait, - Ty: EdgeType, - S: BuildHasher, -{ - type NodeIdentifiers = NodeIdentifiers<'a, N, E, Ty>; - - fn node_identifiers(self) -> Self::NodeIdentifiers { - NodeIdentifiers { - iter: self.nodes.iter(), - ty: self.ty, - edge_ty: PhantomData, - } - } -} - -impl<N, E, Ty, S> visit::NodeCount for GraphMap<N, E, Ty, S> -where - N: NodeTrait, - Ty: EdgeType, - S: BuildHasher, -{ - fn node_count(&self) -> usize { - (*self).node_count() - } -} - -impl<N, E, Ty, S> visit::NodeIndexable for GraphMap<N, E, Ty, S> -where - N: NodeTrait, - Ty: EdgeType, - S: BuildHasher, -{ - fn node_bound(&self) -> usize { - self.node_count() - } - fn to_index(&self, ix: Self::NodeId) -> usize { - self.nodes.get_index_of(&ix).unwrap() - } - fn from_index(&self, ix: usize) -> Self::NodeId { - assert!( - ix < self.nodes.len(), - "The requested index {} is out-of-bounds.", - ix - ); - let (&key, _) = self.nodes.get_index(ix).unwrap(); - key - } -} - -impl<N, E, Ty, S> visit::NodeCompactIndexable for GraphMap<N, E, Ty, S> -where - N: NodeTrait, - Ty: EdgeType, - S: BuildHasher, -{ -} - -impl<'a, N: 'a, E, Ty, S> visit::IntoNeighbors for &'a GraphMap<N, E, Ty, S> -where - N: Copy + Ord + Hash, - Ty: EdgeType, - S: BuildHasher, -{ - type Neighbors = Neighbors<'a, N, Ty>; - fn neighbors(self, n: Self::NodeId) -> Self::Neighbors { - self.neighbors(n) - } -} - -impl<'a, N: 'a, E, Ty, S> visit::IntoNeighborsDirected for &'a GraphMap<N, E, Ty, S> -where - N: Copy + Ord + Hash, - Ty: EdgeType, - S: BuildHasher, -{ - type NeighborsDirected = NeighborsDirected<'a, N, Ty>; - fn neighbors_directed(self, n: N, dir: Direction) -> Self::NeighborsDirected { - self.neighbors_directed(n, dir) - } -} - -impl<N, E, Ty, S> visit::EdgeIndexable for GraphMap<N, E, Ty, S> -where - N: NodeTrait, - Ty: EdgeType, - S: BuildHasher, -{ - fn edge_bound(&self) -> usize { - self.edge_count() - } - - fn to_index(&self, ix: Self::EdgeId) -> usize { - self.edges.get_index_of(&ix).unwrap() - } - - fn from_index(&self, ix: usize) -> Self::EdgeId { - assert!( - ix < self.edges.len(), - "The requested index {} is out-of-bounds.", - ix - ); - let (&key, _) = self.edges.get_index(ix).unwrap(); - key - } -} - -impl<'a, N: 'a, E: 'a, Ty, S> visit::IntoEdges for &'a GraphMap<N, E, Ty, S> -where - N: NodeTrait, - Ty: EdgeType, - S: BuildHasher, -{ - type Edges = Edges<'a, N, E, Ty, S>; - fn edges(self, a: Self::NodeId) -> Self::Edges { - self.edges(a) - } -} - -impl<'a, N: 'a, E: 'a, Ty, S> visit::IntoEdgesDirected for &'a GraphMap<N, E, Ty, S> -where - N: NodeTrait, - Ty: EdgeType, - S: BuildHasher, -{ - type EdgesDirected = EdgesDirected<'a, N, E, Ty, S>; - fn edges_directed(self, a: Self::NodeId, dir: Direction) -> Self::EdgesDirected { - self.edges_directed(a, dir) - } -} - -impl<'a, N: 'a, E: 'a, Ty, S> visit::IntoEdgeReferences for &'a GraphMap<N, E, Ty, S> -where - N: NodeTrait, - Ty: EdgeType, - S: BuildHasher, -{ - type EdgeRef = (N, N, &'a E); - type EdgeReferences = AllEdges<'a, N, E, Ty>; - fn edge_references(self) -> Self::EdgeReferences { - self.all_edges() - } -} - -impl<N, E, Ty, S> visit::EdgeCount for GraphMap<N, E, Ty, S> -where - N: NodeTrait, - Ty: EdgeType, - S: BuildHasher, -{ - #[inline] - fn edge_count(&self) -> usize { - self.edge_count() - } -} - -/// The `GraphMap` keeps an adjacency matrix internally. -impl<N, E, Ty, S> visit::GetAdjacencyMatrix for GraphMap<N, E, Ty, S> -where - N: Copy + Ord + Hash, - Ty: EdgeType, - S: BuildHasher, -{ - type AdjMatrix = (); - #[inline] - fn adjacency_matrix(&self) {} - #[inline] - fn is_adjacent(&self, _: &(), a: N, b: N) -> bool { - self.contains_edge(a, b) - } -} - -/// A [ParallelIterator] over this graph's nodes. -#[cfg(feature = "rayon")] -pub struct ParNodes<'a, N> -where - N: NodeTrait + Send + Sync, -{ - iter: ParKeys<'a, N, Vec<(N, CompactDirection)>>, -} - -#[cfg(feature = "rayon")] -impl<'a, N> ParallelIterator for ParNodes<'a, N> -where - N: NodeTrait + Send + Sync, -{ - type Item = N; - - fn drive_unindexed<C>(self, consumer: C) -> C::Result - where - C: rayon::iter::plumbing::UnindexedConsumer<Self::Item>, - { - self.iter.copied().drive_unindexed(consumer) - } - - fn opt_len(&self) -> Option<usize> { - self.iter.opt_len() - } -} - -#[cfg(feature = "rayon")] -impl<'a, N> IndexedParallelIterator for ParNodes<'a, N> -where - N: NodeTrait + Send + Sync, -{ - fn drive<C>(self, consumer: C) -> C::Result - where - C: rayon::iter::plumbing::Consumer<Self::Item>, - { - self.iter.copied().drive(consumer) - } - - fn len(&self) -> usize { - self.iter.len() - } - - fn with_producer<CB>(self, callback: CB) -> CB::Output - where - CB: rayon::iter::plumbing::ProducerCallback<Self::Item>, - { - self.iter.copied().with_producer(callback) - } -} - -/// A [ParallelIterator] over this graph's edges. -#[cfg(feature = "rayon")] -pub struct ParAllEdges<'a, N, E, Ty> -where - N: NodeTrait + Send + Sync, - E: Sync, -{ - inner: ParIter<'a, (N, N), E>, - ty: PhantomData<fn(Ty)>, -} - -#[cfg(feature = "rayon")] -impl<'a, N, E, Ty> ParallelIterator for ParAllEdges<'a, N, E, Ty> -where - N: NodeTrait + Send + Sync, - E: Sync, -{ - type Item = (N, N, &'a E); - - fn drive_unindexed<C>(self, c: C) -> C::Result - where - C: rayon::iter::plumbing::UnindexedConsumer<Self::Item>, - { - self.inner.map(|(&(a, b), v)| (a, b, v)).drive_unindexed(c) - } - - fn opt_len(&self) -> Option<usize> { - self.inner.opt_len() - } -} - -#[cfg(feature = "rayon")] -impl<'a, N, E, Ty> IndexedParallelIterator for ParAllEdges<'a, N, E, Ty> -where - N: NodeTrait + Send + Sync, - E: Sync, -{ - fn drive<C>(self, consumer: C) -> C::Result - where - C: rayon::iter::plumbing::Consumer<Self::Item>, - { - self.inner.map(|(&(a, b), v)| (a, b, v)).drive(consumer) - } - - fn len(&self) -> usize { - self.inner.len() - } - - fn with_producer<CB>(self, callback: CB) -> CB::Output - where - CB: rayon::iter::plumbing::ProducerCallback<Self::Item>, - { - self.inner - .map(|(&(a, b), v)| (a, b, v)) - .with_producer(callback) - } -} - -/// A [ParallelIterator] over this graph's edges by mutable reference. -#[cfg(feature = "rayon")] -pub struct ParAllEdgesMut<'a, N, E: 'a, Ty> -where - N: NodeTrait + Send + Sync, - E: Send, -{ - inner: ParIterMut<'a, (N, N), E>, - ty: PhantomData<fn(Ty)>, -} - -#[cfg(feature = "rayon")] -impl<'a, N, E, Ty> ParallelIterator for ParAllEdgesMut<'a, N, E, Ty> -where - N: NodeTrait + Send + Sync, - E: Send, -{ - type Item = (N, N, &'a mut E); - - fn drive_unindexed<C>(self, c: C) -> C::Result - where - C: rayon::iter::plumbing::UnindexedConsumer<Self::Item>, - { - self.inner.map(|(&(a, b), v)| (a, b, v)).drive_unindexed(c) - } - - fn opt_len(&self) -> Option<usize> { - self.inner.opt_len() - } -} - -#[cfg(feature = "rayon")] -impl<'a, N, E, Ty> IndexedParallelIterator for ParAllEdgesMut<'a, N, E, Ty> -where - N: NodeTrait + Send + Sync, - E: Send, -{ - fn drive<C>(self, consumer: C) -> C::Result - where - C: rayon::iter::plumbing::Consumer<Self::Item>, - { - self.inner.map(|(&(a, b), v)| (a, b, v)).drive(consumer) - } - - fn len(&self) -> usize { - self.inner.len() - } - - fn with_producer<CB>(self, callback: CB) -> CB::Output - where - CB: rayon::iter::plumbing::ProducerCallback<Self::Item>, - { - self.inner - .map(|(&(a, b), v)| (a, b, v)) - .with_producer(callback) - } -} |
