38 lines
1.1 KiB
Rust
38 lines
1.1 KiB
Rust
use hashbrown::HashMap;
|
|
use petgraph::graph::{DiGraph, NodeIndex};
|
|
use petgraph::algo::{condensation, toposort};
|
|
|
|
use super::*;
|
|
|
|
struct GraphBuilder<'ctx> {
|
|
ctx: &'ctx DowngradeContext,
|
|
graph: DiGraph<usize, ()>,
|
|
nodes: HashMap<usize, NodeIndex>
|
|
}
|
|
|
|
impl GraphBuilder<'_> {
|
|
fn connect(&mut self, idx: usize) {
|
|
let node = self.graph.add_node(idx);
|
|
self.nodes.insert(idx, node);
|
|
let deps = self.ctx.thunk_deps.get(idx).unwrap();
|
|
for (&refee, _) in deps {
|
|
if !self.nodes.contains_key(&refee) {
|
|
self.connect(refee);
|
|
}
|
|
self.graph.add_edge(node, *self.nodes.get(&refee).unwrap(), ());
|
|
}
|
|
}
|
|
}
|
|
|
|
pub fn sort_dependencies(ctx: &DowngradeContext) -> Vec<Vec<usize>> {
|
|
let mut builder = GraphBuilder {
|
|
ctx,
|
|
graph: DiGraph::new(),
|
|
nodes: HashMap::new(),
|
|
};
|
|
builder.connect(ctx.thunks.len() - 1);
|
|
let mut graph = condensation(builder.graph, false);
|
|
let sorted = toposort(&graph, None).unwrap();
|
|
sorted.into_iter().map(|idx| graph.remove_node(idx).unwrap()).collect_vec()
|
|
}
|