Implement Crate::transitive_reverse_dependencies

This commit is contained in:
Lukas Wirth 2021-03-15 17:43:46 +01:00
parent eec64ec01b
commit e97cd709cd
4 changed files with 71 additions and 5 deletions

View file

@ -274,6 +274,34 @@ impl CrateGraph {
deps.into_iter()
}
/// Returns an iterator over all transitive reverse dependencies of the given crate.
pub fn transitive_reverse_dependencies(
&self,
of: CrateId,
) -> impl Iterator<Item = CrateId> + '_ {
let mut worklist = vec![of];
let mut rev_deps = FxHashSet::default();
let mut inverted_graph = FxHashMap::default();
self.arena.iter().for_each(|(&krate, data)| {
data.dependencies.iter().for_each(|dep| {
inverted_graph.entry(dep.crate_id).or_insert_with(Vec::default).push(krate)
})
});
while let Some(krate) = worklist.pop() {
if !rev_deps.insert(krate) {
continue;
}
if let Some(rev_deps) = inverted_graph.get(&krate) {
worklist.extend(rev_deps);
}
}
rev_deps.remove(&of);
rev_deps.into_iter()
}
/// Returns all crates in the graph, sorted in topological order (ie. dependencies of a crate
/// come before the crate itself).
pub fn crates_in_topological_order(&self) -> Vec<CrateId> {