webgraph_algo/
top_sort.rs1use crate::{
9 visits::depth_first::SeqPred,
10 visits::{depth_first::*, Sequential},
11};
12use dsi_progress_logger::ProgressLog;
13use no_break::NoBreak;
14use std::ops::ControlFlow::Continue;
15use webgraph::traits::RandomAccessGraph;
16
17pub fn top_sort(graph: impl RandomAccessGraph, pl: &mut impl ProgressLog) -> Box<[usize]> {
23 let num_nodes = graph.num_nodes();
24 pl.item_name("node");
25 pl.expected_updates(Some(num_nodes));
26 pl.start("Computing topological sort");
27
28 let mut visit = SeqPred::new(&graph);
29 let mut top_sort = Box::new_uninit_slice(num_nodes);
30 let mut pos = num_nodes;
31
32 visit
33 .visit(0..num_nodes, |event| {
34 match event {
35 EventPred::Previsit { .. } => {
36 pl.light_update();
37 }
38 EventPred::Postvisit { node, .. } => {
39 pos -= 1;
40 top_sort[pos].write(node);
41 }
42 _ => (),
43 }
44 Continue(())
45 })
46 .continue_value_no_break();
47
48 pl.done();
49 unsafe { top_sort.assume_init() }
51}