topo_sort
A "cycle-safe" topological sort for a set of nodes with dependencies in Rust.
Basically, it allows sorting a list by its dependencies while checking for
cycles in the graph. If a cycle is detected, a CycleError is returned from the
iterator (or SortResults::Partial is returned if using the to/into_vec APIs)
.
Examples
[]
= "0.2"
A basic example:
use ;
...or using iteration:
use TopoSort;
Cycle detected:
use TopoSort;
Usage
Using TopoSort is a basic two step process:
- Add in your nodes and dependencies to
TopoSort - Iterate over the results OR store them directly in a
Vec
- For step 2, there are three general ways to consume:
- Iteration - returns a
Resultso cycles can be detected every iteration to/into_vecfunctions - returns aSortResultsenum with aVecof full (no cycle) or partial (cycle) resultstry_[init]_vecfunctions - returns aVecwrapped in aResult(full or no results)
- Iteration - returns a
NOTE: The actual sorting is lazy and is only performed in step 2
Algorithm
This is implemented using Kahn's algorithm. While basic caution was taken not to do anything too egregious performance-wise, the author's use cases are not performance sensitive, and it has not been optimized. Still, the author tried to make reasonable trade offs and make it flexible for a variety of use cases, not just the author's.
Safety
The crate uses two tiny unsafe blocks which use the addresses of HashMap
keys in a new HashMap. This was necessary to avoid cloning inserted data on
owned iteration by self referencing the struct. Since there is no removal in
regular iteration (iter() or for loop using &), this should be safe as
there is no chance of the data moving during borrowed iteration. During
owned/consuming iteration (into_iter() or for without &), we remove the
entries as we go. If Rust's HashMap were to change and shrink during removals,
this iterator could break. If this makes you uncomfortable, simply don't use
consuming iteration (avoid APIs using self - use only those with &self
or &mut self). .
License
This project is licensed optionally under either:
- Apache License, Version 2.0, (LICENSE-APACHE or https://www.apache.org/licenses/LICENSE-2.0)
- MIT license (LICENSE-MIT or https://opensource.org/licenses/MIT)