[−][src]Struct incremental_topo::IncrementalTopo
Data structure for maintaining a topological ordering over a collection of elements, in an incremental fashion.
See the module-level documentation for more information.
Methods
impl<T: Hash + Eq> IncrementalTopo<T>
[src]
pub fn new() -> Self
[src]
Create a new IncrementalTopo graph.
Examples
use incremental_topo::IncrementalTopo; let dag = IncrementalTopo::<usize>::new(); assert!(dag.is_empty());
pub fn add_node(&mut self, node: T) -> bool
[src]
Add a new node to the graph.
Initially this node will not have any order relative to the values
that are already in the graph. Only when relations are added
with add_dependency
will the order begin to matter.
Returns false if the graph already contains the node.
Examples
use incremental_topo::IncrementalTopo; let mut dag = IncrementalTopo::new(); assert!(dag.add_node("cat")); assert!(dag.add_node("dog")); assert!(dag.add_node("mouse")); assert!(dag.add_node("human")); assert!(!dag.add_node("cat"));
pub fn contains_node<Q: ?Sized>(&self, node: &Q) -> bool where
T: Borrow<Q>,
Q: Hash + Eq,
[src]
T: Borrow<Q>,
Q: Hash + Eq,
Returns true if the graph contains the specified node.
The passed node may be any borrowed form of the graph's node type, but Hash and Eq on the borrowed form must match those for the node type.
Examples
use incremental_topo::IncrementalTopo; let mut dag = IncrementalTopo::new(); assert!(dag.add_node("cat")); assert!(dag.add_node("dog")); assert!(dag.contains_node("cat")); assert!(dag.contains_node("dog")); assert!(!dag.contains_node("horse")); assert!(!dag.contains_node("orc"));
pub fn delete_node<Q: ?Sized>(&mut self, node: &Q) -> bool where
T: Borrow<Q>,
Q: Hash + Eq,
[src]
T: Borrow<Q>,
Q: Hash + Eq,
Attempt to remove node from graph, returning true if the node was contained and removed.
The passed node may be any borrowed form of the graph's node type, but Hash and Eq on the borrowed form must match those for the node type.
Examples
use incremental_topo::IncrementalTopo; let mut dag = IncrementalTopo::new(); assert!(dag.add_node("cat")); assert!(dag.add_node("dog")); assert!(dag.delete_node("cat")); assert!(dag.delete_node(&"dog")); assert!(!dag.delete_node("horse")); assert!(!dag.delete_node(&"orc"));
pub fn add_dependency<Q: ?Sized, R: ?Sized>(
&mut self,
prec: &Q,
succ: &R
) -> Result<bool> where
T: Borrow<Q> + Borrow<R>,
Q: Hash + Eq,
R: Hash + Eq,
[src]
&mut self,
prec: &Q,
succ: &R
) -> Result<bool> where
T: Borrow<Q> + Borrow<R>,
Q: Hash + Eq,
R: Hash + Eq,
Add a directed link between two nodes already present in the graph.
This link indicates an ordering constraint on the two nodes, now prec
must always come before succ
in the ordering.
The values of prec
and succ
may be any borrowed form of the graph's
node type, but Hash and Eq on the borrowed form must match those for
the node type.
Returns Ok(true)
if the graph did not previously contain this
dependency. Returns Ok(false)
if the graph did have a previous
dependency between these two nodes.
Errors
This function will return an Err
if the dependency introduces a cycle
into the graph or if either of the nodes passed is not found in the
graph.
Examples
use incremental_topo::IncrementalTopo; let mut dag = IncrementalTopo::new(); assert!(dag.add_node("cat")); assert!(dag.add_node("dog")); assert!(dag.add_node("mouse")); assert!(dag.add_node("human")); assert!(dag.add_dependency("human", "dog").unwrap()); assert!(dag.add_dependency("human", "cat").unwrap()); assert!(dag.add_dependency("cat", "mouse").unwrap());
pub fn contains_dependency<Q: ?Sized, R: ?Sized>(
&self,
prec: &Q,
succ: &R
) -> bool where
T: Borrow<Q> + Borrow<R>,
Q: Hash + Eq,
R: Hash + Eq,
[src]
&self,
prec: &Q,
succ: &R
) -> bool where
T: Borrow<Q> + Borrow<R>,
Q: Hash + Eq,
R: Hash + Eq,
Returns true if the graph contains a dependency from prec
to succ
.
Returns false if either node is not found, or if there is no dependency.
The values of prec
and succ
may be any borrowed form of the graph's
node type, but Hash and Eq on the borrowed form must match those for
the node type.
Examples
use incremental_topo::IncrementalTopo; let mut dag = IncrementalTopo::new(); assert!(dag.add_node("cat")); assert!(dag.add_node("mouse")); assert!(dag.add_node("human")); assert!(dag.add_dependency("human", "cat").unwrap()); assert!(dag.add_dependency("cat", "mouse").unwrap()); assert!(dag.contains_dependency("cat", "mouse")); assert!(!dag.contains_dependency("human", "mouse")); assert!(!dag.contains_dependency("cat", "horse"));
pub fn contains_transitive_dependency<Q: ?Sized, R: ?Sized>(
&self,
prec: &Q,
succ: &R
) -> bool where
T: Borrow<Q> + Borrow<R>,
Q: Hash + Eq,
R: Hash + Eq,
[src]
&self,
prec: &Q,
succ: &R
) -> bool where
T: Borrow<Q> + Borrow<R>,
Q: Hash + Eq,
R: Hash + Eq,
Returns true if the graph contains a transitive dependency from prec
to succ
.
In this context a transitive dependency means that succ
exists as a
descendant of prec
, with some chain of other nodes in between.
Returns false if either node is not found in the graph, or there is no transitive dependency.
The values of prec
and succ
may be any borrowed form of the graph's
node type, but Hash and Eq on the borrowed form must match those for
the node type.
Examples
use incremental_topo::IncrementalTopo; let mut dag = IncrementalTopo::new(); assert!(dag.add_node("cat")); assert!(dag.add_node("mouse")); assert!(dag.add_node("human")); assert!(dag.add_node("dog")); assert!(dag.add_dependency("human", "cat").unwrap()); assert!(dag.add_dependency("human", "dog").unwrap()); assert!(dag.add_dependency("cat", "mouse").unwrap()); assert!(dag.contains_transitive_dependency("human", "mouse")); assert!(!dag.contains_transitive_dependency("dog", "mouse"));
pub fn delete_dependency<Q: ?Sized, R: ?Sized>(
&mut self,
prec: &Q,
succ: &R
) -> bool where
T: Borrow<Q> + Borrow<R>,
Q: Hash + Eq,
R: Hash + Eq,
[src]
&mut self,
prec: &Q,
succ: &R
) -> bool where
T: Borrow<Q> + Borrow<R>,
Q: Hash + Eq,
R: Hash + Eq,
Attempt to remove a dependency from the graph, returning true if the dependency was removed.
Returns false is either node is not found in the graph.
The values of prec
and succ
may be any borrowed form of the graph's
node type, but Hash and Eq on the borrowed form must match those for
the node type.
Removing a dependency from the graph is an extremely simple operation, which requires no recalculation of the topological order. The ordering before and after a removal is exactly the same.
Examples
use incremental_topo::IncrementalTopo; let mut dag = IncrementalTopo::new(); assert!(dag.add_node("cat")); assert!(dag.add_node("mouse")); assert!(dag.add_node("human")); assert!(dag.add_node("dog")); assert!(dag.add_dependency("human", "cat").unwrap()); assert!(dag.add_dependency("human", "dog").unwrap()); assert!(dag.add_dependency("cat", "mouse").unwrap()); assert!(dag.delete_dependency("cat", "mouse")); assert!(dag.delete_dependency("human", "dog")); assert!(!dag.delete_dependency("human", "mouse"));
pub fn size(&self) -> usize
[src]
Return the number of nodes within the graph.
Examples
use incremental_topo::IncrementalTopo; let mut dag = IncrementalTopo::new(); assert!(dag.add_node("cat")); assert!(dag.add_node("mouse")); assert!(dag.add_node("human")); assert!(dag.add_node("dog")); assert_eq!(dag.size(), 4);
pub fn is_empty(&self) -> bool
[src]
Return true if there are no nodes in the graph.
Examples
use incremental_topo::IncrementalTopo; let mut dag = IncrementalTopo::new(); assert!(dag.is_empty()); assert!(dag.add_node("cat")); assert!(dag.add_node("mouse")); assert!(dag.add_node("human")); assert!(dag.add_node("dog")); assert!(!dag.is_empty());
pub fn iter_unsorted(&self) -> impl Iterator<Item = (u32, &T)>
[src]
Return an iterator over the nodes of the graph
Examples
use incremental_topo::IncrementalTopo; use std::collections::HashSet; let mut dag = IncrementalTopo::new(); assert!(dag.add_node("cat")); assert!(dag.add_node("mouse")); assert!(dag.add_node("human")); assert!(dag.add_node("dog")); assert!(dag.add_dependency("human", "cat").unwrap()); assert!(dag.add_dependency("human", "dog").unwrap()); assert!(dag.add_dependency("cat", "mouse").unwrap()); let pairs = dag.iter_unsorted().collect::<HashSet<_>>(); let mut expected_pairs = HashSet::new(); expected_pairs.extend(vec![(1, &"human"), (2, &"cat"), (3, &"mouse"), (4, &"dog")]); assert_eq!(pairs, expected_pairs);
pub fn descendants_unsorted<Q: ?Sized>(
&self,
node: &Q
) -> Result<DescendantsUnsorted<T>> where
T: Borrow<Q>,
Q: Hash + Eq,
[src]
&self,
node: &Q
) -> Result<DescendantsUnsorted<T>> where
T: Borrow<Q>,
Q: Hash + Eq,
Return an iterator over the descendants of a node in the graph, in an unosrted order.
The passed node may be any borrowed form of the graph's node type, but Hash and Eq on the borrowed form must match those for the node type.
Accessing the nodes in an unsorted order allows for faster access using a iterative DFS search. This is opposed to the order descendants iterator which requires the use of a binary heap to order the values.
Examples
use incremental_topo::IncrementalTopo; use std::collections::HashSet; let mut dag = IncrementalTopo::new(); assert!(dag.add_node("cat")); assert!(dag.add_node("mouse")); assert!(dag.add_node("dog")); assert!(dag.add_node("human")); assert!(dag.add_dependency("human", "cat").unwrap()); assert!(dag.add_dependency("human", "dog").unwrap()); assert!(dag.add_dependency("dog", "cat").unwrap()); assert!(dag.add_dependency("cat", "mouse").unwrap()); let pairs = dag .descendants_unsorted("human") .unwrap() .collect::<HashSet<_>>(); let mut expected_pairs = HashSet::new(); expected_pairs.extend(vec![(2, &"dog"), (3, &"cat"), (4, &"mouse")]); assert_eq!(pairs, expected_pairs);
pub fn descendants<Q: ?Sized>(&self, node: &Q) -> Result<Descendants<T>> where
T: Borrow<Q>,
Q: Hash + Eq,
[src]
T: Borrow<Q>,
Q: Hash + Eq,
Return an iterator over descendants of a node in the graph, in a topologically sorted order.
The passed node may be any borrowed form of the graph's node type, but Hash and Eq on the borrowed form must match those for the node type.
Accessing the nodes in a sorted order requires the use of a BinaryHeap,
so some performance penalty is paid there. If all is required is access
to the descendants of a node, use descendants_unsorted
.
Examples
use incremental_topo::IncrementalTopo; let mut dag = IncrementalTopo::new(); assert!(dag.add_node("cat")); assert!(dag.add_node("mouse")); assert!(dag.add_node("dog")); assert!(dag.add_node("human")); assert!(dag.add_dependency("human", "cat").unwrap()); assert!(dag.add_dependency("human", "dog").unwrap()); assert!(dag.add_dependency("dog", "cat").unwrap()); assert!(dag.add_dependency("cat", "mouse").unwrap()); let ordered_nodes = dag.descendants("human").unwrap().collect::<Vec<_>>(); assert_eq!(ordered_nodes, vec![&"dog", &"cat", &"mouse"]);
pub fn topo_cmp<Q: ?Sized, R: ?Sized>(
&self,
node_a: &Q,
node_b: &R
) -> Result<Ordering> where
T: Borrow<Q> + Borrow<R>,
Q: Hash + Eq,
R: Hash + Eq,
[src]
&self,
node_a: &Q,
node_b: &R
) -> Result<Ordering> where
T: Borrow<Q> + Borrow<R>,
Q: Hash + Eq,
R: Hash + Eq,
Compare two nodes present in the graph, topographically. Returns Err(...) if either node is missing from the graph.
The values of prec
and succ
may be any borrowed form of the graph's
node type, but Hash and Eq on the borrowed form must match those for
the node type.
Examples
use incremental_topo::IncrementalTopo; use std::cmp::Ordering::*; let mut dag = IncrementalTopo::new(); assert!(dag.add_node("cat")); assert!(dag.add_node("mouse")); assert!(dag.add_node("dog")); assert!(dag.add_node("human")); assert!(dag.add_dependency("human", "cat").unwrap()); assert!(dag.add_dependency("human", "dog").unwrap()); assert!(dag.add_dependency("dog", "cat").unwrap()); assert!(dag.add_dependency("cat", "mouse").unwrap()); assert_eq!(dag.topo_cmp("human", "mouse").unwrap(), Less); assert_eq!(dag.topo_cmp("cat", "dog").unwrap(), Greater); assert!(dag.topo_cmp("cat", "horse").is_err());
Trait Implementations
impl<T: Clone + Hash + Eq, NodeId: Clone + Hash + Eq + Copy> Clone for IncrementalTopo<T, NodeId>
[src]
fn clone(&self) -> IncrementalTopo<T, NodeId>
[src]
fn clone_from(&mut self, source: &Self)
1.0.0[src]
Performs copy-assignment from source
. Read more
impl<T: Default + Hash + Eq, NodeId: Default + Hash + Eq + Copy> Default for IncrementalTopo<T, NodeId>
[src]
fn default() -> IncrementalTopo<T, NodeId>
[src]
impl<T: Debug + Hash + Eq, NodeId: Debug + Hash + Eq + Copy> Debug for IncrementalTopo<T, NodeId>
[src]
Auto Trait Implementations
impl<T, NodeId> Sync for IncrementalTopo<T, NodeId> where
NodeId: Sync,
T: Sync,
NodeId: Sync,
T: Sync,
impl<T, NodeId> Send for IncrementalTopo<T, NodeId> where
NodeId: Send,
T: Send,
NodeId: Send,
T: Send,
impl<T, NodeId> Unpin for IncrementalTopo<T, NodeId> where
NodeId: Unpin,
T: Unpin,
NodeId: Unpin,
T: Unpin,
impl<T, NodeId> RefUnwindSafe for IncrementalTopo<T, NodeId> where
NodeId: RefUnwindSafe,
T: RefUnwindSafe,
NodeId: RefUnwindSafe,
T: RefUnwindSafe,
impl<T, NodeId> UnwindSafe for IncrementalTopo<T, NodeId> where
NodeId: UnwindSafe,
T: UnwindSafe,
NodeId: UnwindSafe,
T: UnwindSafe,
Blanket Implementations
impl<T> ToOwned for T where
T: Clone,
[src]
T: Clone,
type Owned = T
The resulting type after obtaining ownership.
fn to_owned(&self) -> T
[src]
fn clone_into(&self, target: &mut T)
[src]
impl<T> From<T> for T
[src]
impl<T, U> Into<U> for T where
U: From<T>,
[src]
U: From<T>,
impl<T, U> TryFrom<U> for T where
U: Into<T>,
[src]
U: Into<T>,
type Error = Infallible
The type returned in the event of a conversion error.
fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>
[src]
impl<T, U> TryInto<U> for T where
U: TryFrom<T>,
[src]
U: TryFrom<T>,
type Error = <U as TryFrom<T>>::Error
The type returned in the event of a conversion error.
fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>
[src]
impl<T> BorrowMut<T> for T where
T: ?Sized,
[src]
T: ?Sized,
fn borrow_mut(&mut self) -> &mut T
[src]
impl<T> Borrow<T> for T where
T: ?Sized,
[src]
T: ?Sized,
impl<T> Any for T where
T: 'static + ?Sized,
[src]
T: 'static + ?Sized,