logicaffeine_kernel/dag/sem/
table.rs1pub trait Key: Copy + Eq {
11 const VACANT: Self;
13 fn hash(&self) -> u64;
14}
15
16const K: u64 = 0x9E37_79B9_7F4A_7C15;
17
18#[inline]
19fn mix2(a: u32, b: u32) -> u64 {
20 (((a as u64) << 32) | b as u64).wrapping_mul(K)
21}
22
23impl Key for (u32, u32) {
24 const VACANT: Self = (u32::MAX, u32::MAX);
25
26 #[inline]
27 fn hash(&self) -> u64 {
28 mix2(self.0, self.1)
29 }
30}
31
32impl Key for (u32, u32, u32) {
33 const VACANT: Self = (u32::MAX, u32::MAX, u32::MAX);
34
35 #[inline]
36 fn hash(&self) -> u64 {
37 (mix2(self.0, self.1) ^ (self.2 as u64)).wrapping_mul(K)
38 }
39}
40
41impl Key for (u32, u32, u32, u32) {
42 const VACANT: Self = (u32::MAX, u32::MAX, u32::MAX, u32::MAX);
43
44 #[inline]
45 fn hash(&self) -> u64 {
46 (mix2(self.0, self.1) ^ (((self.2 as u64) << 32) | self.3 as u64)).wrapping_mul(K)
47 }
48}
49
50impl Key for (u32, u64) {
51 const VACANT: Self = (u32::MAX, u64::MAX);
52
53 #[inline]
54 fn hash(&self) -> u64 {
55 ((self.0 as u64).wrapping_mul(K) ^ self.1).wrapping_mul(K)
56 }
57}
58
59const EMPTY: u32 = u32::MAX;
60
61#[derive(Copy, Clone)]
62struct Slot<Q> {
63 key: Q,
64 val: u32,
66}
67
68#[derive(Clone)]
71pub struct Table<Q: Key> {
72 slots: Vec<Slot<Q>>,
73 shift: u32,
74 len: usize,
75}
76
77impl<Q: Key> Default for Table<Q> {
78 fn default() -> Self {
79 Self::new()
80 }
81}
82
83impl<Q: Key> Table<Q> {
84 const VACANT: Slot<Q> = Slot {
85 key: Q::VACANT,
86 val: EMPTY,
87 };
88
89 pub fn new() -> Table<Q> {
90 let cap = 1 << 10;
91 Table {
92 slots: vec![Self::VACANT; cap],
93 shift: 64 - 10,
94 len: 0,
95 }
96 }
97
98 #[inline]
99 pub fn get(&self, k: &Q) -> Option<u32> {
100 let mask = self.slots.len() - 1;
101 let mut i = (k.hash() >> self.shift) as usize;
102 loop {
103 let s = &self.slots[i];
104 if s.val == EMPTY {
105 return None;
106 }
107 if s.key == *k {
108 return Some(s.val);
109 }
110 i = (i + 1) & mask;
111 }
112 }
113
114 #[inline]
116 pub fn insert(&mut self, k: Q, v: u32) {
117 debug_assert!(v != EMPTY);
118 if (self.len + 1) * 2 > self.slots.len() {
119 self.grow();
120 }
121 self.place(k, v);
122 self.len += 1;
123 }
124
125 #[inline]
126 fn place(&mut self, k: Q, v: u32) {
127 let mask = self.slots.len() - 1;
128 let mut i = (k.hash() >> self.shift) as usize;
129 while self.slots[i].val != EMPTY {
130 i = (i + 1) & mask;
131 }
132 self.slots[i] = Slot { key: k, val: v };
133 }
134
135 fn grow(&mut self) {
136 let cap = self.slots.len() * 2;
137 let old = std::mem::replace(&mut self.slots, vec![Self::VACANT; cap]);
138 self.shift = 64 - cap.trailing_zeros();
139 for s in old {
140 if s.val != EMPTY {
141 self.place(s.key, s.val);
142 }
143 }
144 }
145
146 pub fn contains(&self, k: &Q) -> bool {
147 self.get(k).is_some()
148 }
149
150 pub fn clear(&mut self) {
152 if self.len > 0 {
153 self.slots.fill(Self::VACANT);
154 self.len = 0;
155 }
156 }
157
158 pub fn len(&self) -> usize {
159 self.len
160 }
161
162 pub fn is_empty(&self) -> bool {
163 self.len == 0
164 }
165
166 pub fn bytes(&self) -> usize {
167 self.slots.capacity() * std::mem::size_of::<Slot<Q>>()
168 }
169}
170
171#[derive(Copy, Clone)]
172struct StampedSlot<Q> {
173 key: Q,
174 val: u32,
175 generation: u32,
177}
178
179#[derive(Clone)]
181pub struct StampedTable<Q: Key> {
182 slots: Vec<StampedSlot<Q>>,
183 shift: u32,
184 len: usize,
185 generation: u32,
186}
187
188impl<Q: Key> Default for StampedTable<Q> {
189 fn default() -> Self {
190 Self::new()
191 }
192}
193
194impl<Q: Key> StampedTable<Q> {
195 const VACANT: StampedSlot<Q> = StampedSlot {
196 key: Q::VACANT,
197 val: 0,
198 generation: 0,
199 };
200
201 pub fn new() -> StampedTable<Q> {
202 let cap = 1 << 10;
203 StampedTable {
204 slots: vec![Self::VACANT; cap],
205 shift: 64 - 10,
206 len: 0,
207 generation: 1,
208 }
209 }
210
211 #[inline]
212 pub fn get(&self, k: &Q) -> Option<u32> {
213 let mask = self.slots.len() - 1;
214 let mut i = (k.hash() >> self.shift) as usize;
215 loop {
216 let s = &self.slots[i];
217 if s.generation != self.generation {
218 return None;
219 }
220 if s.key == *k {
221 return Some(s.val);
222 }
223 i = (i + 1) & mask;
224 }
225 }
226
227 #[inline]
229 pub fn insert(&mut self, k: Q, v: u32) {
230 if (self.len + 1) * 2 > self.slots.len() {
231 self.grow();
232 }
233 self.place(k, v);
234 self.len += 1;
235 }
236
237 #[inline]
238 fn place(&mut self, k: Q, v: u32) {
239 let mask = self.slots.len() - 1;
240 let mut i = (k.hash() >> self.shift) as usize;
241 while self.slots[i].generation == self.generation {
242 i = (i + 1) & mask;
243 }
244 self.slots[i] = StampedSlot {
245 key: k,
246 val: v,
247 generation: self.generation,
248 };
249 }
250
251 fn grow(&mut self) {
252 let cap = self.slots.len() * 2;
253 let old = std::mem::replace(&mut self.slots, vec![Self::VACANT; cap]);
254 self.shift = 64 - cap.trailing_zeros();
255 let g = self.generation;
256 self.generation = 1;
257 for s in old {
258 if s.generation == g {
259 self.place(s.key, s.val);
260 }
261 }
262 }
263
264 pub fn clear(&mut self) {
266 self.len = 0;
267 self.generation = self.generation.wrapping_add(1);
268 if self.generation == 0 {
269 for s in self.slots.iter_mut() {
270 s.generation = 0;
271 }
272 self.generation = 1;
273 }
274 }
275
276 pub fn bytes(&self) -> usize {
277 self.slots.capacity() * std::mem::size_of::<StampedSlot<Q>>()
278 }
279}