wasmtime_environ/graphs/
dfs.rs1use super::*;
2
3pub struct Dfs<Node> {
5 stack: Vec<DfsEvent<Node>>,
6}
7
8impl<Node> Default for Dfs<Node> {
9 fn default() -> Self {
10 Self {
11 stack: Default::default(),
12 }
13 }
14}
15
16impl<Node> Dfs<Node> {
17 pub fn new(roots: impl IntoIterator<Item = Node>) -> Self {
19 let mut dfs = Self::default();
20 dfs.add_roots(roots);
21 dfs
22 }
23
24 pub fn add_root(&mut self, root: Node) {
26 self.stack.push(DfsEvent::Pre(root));
27 }
28
29 pub fn add_roots(&mut self, roots: impl IntoIterator<Item = Node>) {
31 self.stack
32 .extend(roots.into_iter().map(|v| DfsEvent::Pre(v)));
33 }
34}
35
36#[derive(Clone, Copy, Debug, PartialEq, Eq)]
38pub enum DfsEvent<Node> {
39 Pre(Node),
41
42 AfterEdge(Node, Node),
44
45 Post(Node),
47}
48
49impl<Node> Dfs<Node>
50where
51 Node: Copy,
52{
53 pub fn next<G>(&mut self, graph: G, seen: impl Fn(Node) -> bool) -> Option<DfsEvent<Node>>
57 where
58 G: Graph<Node>,
59 {
60 loop {
61 let event = self.stack.pop()?;
62
63 if let DfsEvent::Pre(node) = event {
64 if seen(node) {
65 continue;
66 }
67
68 let successors = graph.successors(node);
69
70 let (min, max) = successors.size_hint();
71 let estimated_successors_len = max.unwrap_or_else(|| 2 * min);
72 self.stack.reserve(
73 2 * estimated_successors_len
75 + 1,
77 );
78
79 self.stack.push(DfsEvent::Post(node));
80 for succ in successors {
81 self.stack.push(DfsEvent::AfterEdge(node, succ));
82 if !seen(succ) {
83 self.stack.push(DfsEvent::Pre(succ));
84 }
85 }
86 }
87
88 return Some(event);
89 }
90 }
91}