Skip to main content

weavatrix_graph/algo/walk/
workspace.rs

1use crate::Vec;
2use alloc::collections::VecDeque;
3
4/// Reusable allocation storage for breadth-first and depth-first traversals.
5#[derive(Debug, Clone)]
6pub struct TraversalWorkspace<Node> {
7    marks: Vec<u32>,
8    epoch: u32,
9    pub(super) queue: VecDeque<Node>,
10    pub(super) stack: Vec<Node>,
11    pub(super) scratch: Vec<Node>,
12}
13
14impl<Node> TraversalWorkspace<Node> {
15    #[must_use]
16    pub const fn new() -> Self {
17        Self {
18            marks: Vec::new(),
19            epoch: 0,
20            queue: VecDeque::new(),
21            stack: Vec::new(),
22            scratch: Vec::new(),
23        }
24    }
25
26    pub(super) fn begin(&mut self, node_bound: usize) {
27        if self.marks.len() < node_bound {
28            self.marks.resize(node_bound, 0);
29        }
30        self.epoch = self.epoch.wrapping_add(1);
31        if self.epoch == 0 {
32            self.marks.fill(0);
33            self.epoch = 1;
34        }
35        self.queue.clear();
36        self.stack.clear();
37        self.scratch.clear();
38    }
39
40    pub(super) fn mark(&mut self, slot: usize) -> bool {
41        let Some(mark) = self.marks.get_mut(slot) else {
42            return false;
43        };
44        if *mark == self.epoch {
45            return false;
46        }
47        *mark = self.epoch;
48        true
49    }
50}
51
52impl<Node> Default for TraversalWorkspace<Node> {
53    fn default() -> Self {
54        Self::new()
55    }
56}