antecedent_graph/
workspace.rs1use crate::types::DenseNodeId;
6
7#[derive(Clone, Debug, Default)]
9pub struct BitSet {
10 words: Vec<u64>,
11 len: usize,
12}
13
14impl BitSet {
15 #[must_use]
17 pub fn with_len(len: usize) -> Self {
18 Self { words: vec![0; len.div_ceil(64)], len }
19 }
20
21 pub fn clear(&mut self) {
23 for w in &mut self.words {
24 *w = 0;
25 }
26 }
27
28 pub fn resize(&mut self, len: usize) {
30 self.len = len;
31 self.words.resize(len.div_ceil(64), 0);
32 }
33
34 #[must_use]
36 pub const fn bit_len(&self) -> usize {
37 self.len
38 }
39
40 #[must_use]
42 pub fn words(&self) -> &[u64] {
43 &self.words
44 }
45
46 pub fn insert(&mut self, id: DenseNodeId) {
48 let i = id.as_usize();
49 debug_assert!(i < self.len);
50 self.words[i / 64] |= 1u64 << (i % 64);
51 }
52
53 pub fn remove(&mut self, id: DenseNodeId) {
55 let i = id.as_usize();
56 if i >= self.len {
57 return;
58 }
59 self.words[i / 64] &= !(1u64 << (i % 64));
60 }
61
62 #[must_use]
64 pub fn contains(&self, id: DenseNodeId) -> bool {
65 let i = id.as_usize();
66 if i >= self.len {
67 return false;
68 }
69 (self.words[i / 64] >> (i % 64)) & 1 == 1
70 }
71
72 #[must_use]
74 pub fn any(&self) -> bool {
75 self.words.iter().any(|w| *w != 0)
76 }
77
78 #[must_use]
80 pub fn count_ones(&self) -> usize {
81 self.words.iter().map(|w| w.count_ones() as usize).sum()
82 }
83
84 #[must_use]
86 pub fn to_dense_ids(&self) -> Vec<DenseNodeId> {
87 let mut out = Vec::with_capacity(self.count_ones());
88 for i in 0..self.len {
89 let Ok(raw) = u32::try_from(i) else {
90 break;
91 };
92 let id = DenseNodeId::from_raw(raw);
93 if self.contains(id) {
94 out.push(id);
95 }
96 }
97 out
98 }
99
100 pub fn union_with(&mut self, other: &Self) {
102 debug_assert_eq!(self.len, other.len);
103 for (a, b) in self.words.iter_mut().zip(other.words.iter()) {
104 *a |= *b;
105 }
106 }
107
108 pub fn intersect_with(&mut self, other: &Self) {
110 debug_assert_eq!(self.len, other.len);
111 for (a, b) in self.words.iter_mut().zip(other.words.iter()) {
112 *a &= *b;
113 }
114 }
115
116 pub fn difference_with(&mut self, other: &Self) {
118 debug_assert_eq!(self.len, other.len);
119 for (a, b) in self.words.iter_mut().zip(other.words.iter()) {
120 *a &= !*b;
121 }
122 }
123
124 #[must_use]
126 pub fn is_subset_of(&self, other: &Self) -> bool {
127 debug_assert_eq!(self.len, other.len);
128 self.words.iter().zip(other.words.iter()).all(|(a, b)| a & !b == 0)
129 }
130
131 #[must_use]
133 pub fn equal_set(&self, other: &Self) -> bool {
134 self.len == other.len && self.words == other.words
135 }
136}
137
138impl std::hash::Hash for BitSet {
139 fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
140 self.len.hash(state);
141 self.words.hash(state);
142 }
143}
144
145impl PartialEq for BitSet {
146 fn eq(&self, other: &Self) -> bool {
147 self.equal_set(other)
148 }
149}
150
151impl Eq for BitSet {}
152
153#[derive(Clone, Debug, Default)]
155pub struct GraphWorkspace {
156 pub visited: BitSet,
158 pub frontier: Vec<DenseNodeId>,
160 pub scratch_nodes: Vec<DenseNodeId>,
162 pub predecessor: Vec<Option<DenseNodeId>>,
164}
165
166impl GraphWorkspace {
167 pub fn prepare(&mut self, n: usize) {
169 self.visited.resize(n);
170 self.visited.clear();
171 self.frontier.clear();
172 self.scratch_nodes.clear();
173 self.predecessor.clear();
174 self.predecessor.resize(n, None);
175 }
176}