1use alloc::vec::{self, Vec};
6use core::marker::PhantomData;
7use core::{slice, iter};
8
9use crate::gc::*;
10
11pub trait Key: Copy + Eq + Ord + 'static {
15 fn new(slot: usize, generation: usize) -> Self;
16 fn get_slot(&self) -> usize;
17 fn get_generation(&self) -> usize;
18}
19
20#[macro_export]
22macro_rules! new_key {
23 ($($(#[doc = $doc:expr])? $vis:vis struct $name:ident;)*) => {$(
24 #[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
25 $(#[doc = $doc])?
26 $vis struct $name(usize, usize);
27 impl $crate::slotmap::Key for $name {
28 fn new(slot: usize, generation: usize) -> Self { Self(slot, generation) }
29 fn get_slot(&self) -> usize { self.0 }
30 fn get_generation(&self) -> usize { self.1 }
31 }
32 )*}
33}
34
35#[derive(Clone, Collect)]
36#[collect(no_drop)]
37struct Slot<T> {
38 value: Option<T>,
39 #[collect(require_static)] generation: usize,
40}
41
42#[derive(Clone, Collect)]
47#[collect(no_drop)]
48pub struct SlotMap<K: Key, T> {
49 slots: Vec<Slot<T>>,
50 #[collect(require_static)] empty_slots: Vec<usize>,
51 #[collect(require_static)] num_values: usize,
52 #[collect(require_static)] _key: PhantomData<K>
53}
54impl<K: Key, T> Default for SlotMap<K, T> {
55 fn default() -> Self {
56 Self::new()
57 }
58}
59impl<K: Key, T> SlotMap<K, T> {
60 pub fn new() -> Self {
62 SlotMap {
63 slots: vec![],
64 empty_slots: vec![],
65 num_values: 0,
66 _key: PhantomData,
67 }
68 }
69 #[cfg(test)]
70 fn invariant(&self) -> bool {
71 self.num_values == self.slots.iter().filter(|x| x.value.is_some()).count()
72 &&
73 self.num_values + self.empty_slots.len() == self.slots.len()
74 }
75 pub fn insert(&mut self, value: T) -> K {
77 #[cfg(test)] assert!(self.invariant());
78
79 self.num_values += 1;
80 let key = match self.empty_slots.pop() {
81 Some(slot) => {
82 debug_assert!(self.slots[slot].value.is_none());
83 self.slots[slot].value = Some(value);
84 K::new(slot, self.slots[slot].generation)
85 }
86 None => {
87 debug_assert!(self.slots.iter().all(|x| x.value.is_some()));
88 let slot = self.slots.len();
89 self.slots.push(Slot { value: Some(value), generation: 0 });
90 K::new(slot, 0)
91 }
92 };
93
94 #[cfg(test)] assert!(self.invariant());
95 #[allow(clippy::let_and_return)] key
96 }
97 pub fn remove(&mut self, key: K) -> Option<T> {
100 #[cfg(test)] assert!(self.invariant());
101
102 let slot = self.slots.get_mut(key.get_slot())?;
103 let res = if slot.generation == key.get_generation() { slot.value.take() } else { None };
104 if res.is_some() {
105 slot.generation += 1;
106 self.num_values -= 1;
107 self.empty_slots.push(key.get_slot());
108 }
109
110 #[cfg(test)] assert!(self.invariant());
111 res
112 }
113 pub fn clear(&mut self) {
115 #[cfg(test)] assert!(self.invariant());
116
117 for (i, slot) in self.slots.iter_mut().enumerate() {
118 if slot.value.take().is_some() {
119 slot.generation += 1;
120 self.empty_slots.push(i);
121 }
122 }
123 self.num_values = 0;
124
125 #[cfg(test)] assert!(self.invariant());
126 }
127 pub fn retain_mut<F: FnMut(K, &mut T) -> bool>(&mut self, mut f: F) {
130 #[cfg(test)] assert!(self.invariant());
131
132 for (i, slot) in self.slots.iter_mut().enumerate() {
133 if let Some(value) = &mut slot.value {
134 if !f(K::new(i, slot.generation), value) {
135 slot.value = None;
136 slot.generation += 1;
137 self.num_values -= 1;
138 self.empty_slots.push(i);
139 }
140 }
141 }
142
143 #[cfg(test)] assert!(self.invariant());
144 }
145 pub fn get(&self, key: K) -> Option<&T> {
147 let slot = self.slots.get(key.get_slot())?;
148 if slot.generation == key.get_generation() { slot.value.as_ref() } else { None }
149 }
150 pub fn get_mut(&mut self, key: K) -> Option<&mut T> {
152 let slot = self.slots.get_mut(key.get_slot())?;
153 if slot.generation == key.get_generation() { slot.value.as_mut() } else { None }
154 }
155 pub fn len(&self) -> usize {
157 self.num_values
158 }
159 pub fn is_empty(&self) -> bool {
161 self.len() == 0
162 }
163 pub fn iter(&self) -> Iter<K, T> {
165 Iter(self.slots.iter().enumerate(), PhantomData)
166 }
167 pub fn iter_mut(&mut self) -> IterMut<K, T> {
169 IterMut(self.slots.iter_mut().enumerate(), PhantomData)
170 }
171}
172impl<K: Key, T> IntoIterator for SlotMap<K, T> {
173 type IntoIter = IntoIter<K, T>;
174 type Item = (K, T);
175 fn into_iter(self) -> IntoIter<K, T> {
176 IntoIter(self.slots.into_iter().enumerate(), PhantomData)
177 }
178}
179
180pub struct IntoIter<K: Key, T>(iter::Enumerate<vec::IntoIter<Slot<T>>>, PhantomData<K>);
181pub struct Iter<'a, K: Key, T>(iter::Enumerate<slice::Iter<'a, Slot<T>>>, PhantomData<K>);
182pub struct IterMut<'a, K: Key, T>(iter::Enumerate<slice::IterMut<'a, Slot<T>>>, PhantomData<K>);
183
184impl<K: Key, T> Iterator for IntoIter<K, T> {
185 type Item = (K, T);
186 fn next(&mut self) -> Option<Self::Item> {
187 loop {
188 let (i, slot) = self.0.next()?;
189 if let Some(x) = slot.value { return Some((K::new(i, slot.generation), x)) }
190 }
191 }
192}
193impl<'a, K: Key, T> Iterator for Iter<'a, K, T> {
194 type Item = (K, &'a T);
195 fn next(&mut self) -> Option<Self::Item> {
196 loop {
197 let (i, slot) = self.0.next()?;
198 if let Some(x) = slot.value.as_ref() { return Some((K::new(i, slot.generation), x)) }
199 }
200 }
201}
202impl<'a, K: Key, T> Iterator for IterMut<'a, K, T> {
203 type Item = (K, &'a mut T);
204 fn next(&mut self) -> Option<Self::Item> {
205 loop {
206 let (i, slot) = self.0.next()?;
207 if let Some(x) = slot.value.as_mut() { return Some((K::new(i, slot.generation), x)) }
208 }
209 }
210}
211
212#[test]
213fn test_slotmap() {
214 use alloc::collections::BTreeSet;
215 new_key! {
216 struct TestKey;
217 }
218 let mut map: SlotMap<TestKey, i32> = SlotMap::new();
219 assert_eq!(map.len(), 0);
220 assert_eq!(map.slots.len(), 0);
221
222 let key = map.insert(56);
223 assert_eq!(*map.get(key).unwrap(), 56);
224 *map.get_mut(key).unwrap() = 23;
225 assert_eq!(*map.get(key).unwrap(), 23);
226 assert_eq!(map.slots.len(), 1);
227
228 let key2 = map.insert(11);
229 assert_eq!(*map.get(key).unwrap(), 23);
230 assert_eq!(*map.get(key2).unwrap(), 11);
231 assert_eq!(map.slots.len(), 2);
232
233 assert_eq!(map.remove(key), Some(23));
234 assert!(map.get(key).is_none());
235 assert_eq!(*map.get(key2).unwrap(), 11);
236 assert_eq!(map.slots.len(), 2);
237
238 assert_eq!(map.remove(key), None);
239 assert!(map.get(key).is_none());
240 assert_eq!(*map.get(key2).unwrap(), 11);
241 assert_eq!(map.slots.len(), 2);
242
243 for (_, v) in map.iter_mut() { *v += 1; }
244 assert!(map.get(key).is_none());
245 assert_eq!(*map.get(key2).unwrap(), 12);
246 assert_eq!(map.slots.len(), 2);
247
248 assert_eq!(map.remove(key2), Some(12));
249 assert!(map.get(key).is_none());
250 assert!(map.get(key2).is_none());
251 assert_eq!(map.slots.len(), 2);
252
253 assert_eq!(map.remove(key2), None);
254 assert!(map.get(key).is_none());
255 assert!(map.get(key2).is_none());
256 assert_eq!(map.slots.len(), 2);
257
258 for _ in 0..4 {
259 let mut keys = vec![];
260 for i in 0..128 {
261 keys.push((map.insert(i), i));
262 }
263 assert_eq!(map.slots.len(), 128);
264 keys[20..].reverse();
265 keys[..100].reverse();
266 keys[40..70].reverse();
267
268 for i in 0..keys.len() {
269 assert_eq!(map.len(), 128 - i);
270 for j in 0..i {
271 assert!(map.get(keys[j].0).is_none());
272 assert!(map.get_mut(keys[j].0).is_none());
273 assert!(map.remove(keys[j].0).is_none());
274 }
275 assert_eq!(*map.get(keys[i].0).unwrap(), keys[i].1);
276 assert_eq!(*map.get_mut(keys[i].0).unwrap(), keys[i].1);
277 assert_eq!(map.remove(keys[i].0), Some(keys[i].1));
278 assert_eq!(map.remove(keys[i].0), None);
279 assert_eq!(map.remove(keys[i].0), None);
280 assert!(map.get(keys[i].0).is_none());
281 assert!(map.get_mut(keys[i].0).is_none());
282 for j in i+1..keys.len() {
283 assert_eq!(*map.get(keys[j].0).unwrap(), keys[j].1);
284 assert_eq!(*map.get_mut(keys[j].0).unwrap(), keys[j].1);
285 }
286 assert_eq!(map.len(), 128 - i - 1);
287
288 let mut cache = BTreeSet::default();
289 let cpy = map.clone();
290
291 cache.clear();
292 for (key, val) in map.iter() {
293 assert!(cache.insert(*val));
294 assert_eq!(map.get(key).unwrap(), val);
295 assert_eq!(cpy.get(key).unwrap(), val);
296 }
297 cache.clear();
298 for (key, val) in map.iter_mut() {
299 assert!(cache.insert(*val));
300 assert_eq!(cpy.get(key).unwrap(), val);
301 }
302 cache.clear();
303 for (key, val) in map.clone() {
304 assert!(cache.insert(val));
305 assert_eq!(*map.get(key).unwrap(), val);
306 assert_eq!(*cpy.get(key).unwrap(), val);
307 }
308 }
309 }
310
311 assert_eq!(map.slots.len(), 128);
312 assert_eq!(map.len(), 0);
313 assert!(map.is_empty());
314
315 let mut keys = vec![];
316 for i in 0..32 {
317 keys.push((i, map.insert(i)));
318 }
319 keys[..25].reverse();
320 keys[7..].reverse();
321 keys[11..19].reverse();
322
323 assert_eq!(map.slots.len(), 128);
324 assert_eq!(map.len(), 32);
325 assert!(!map.is_empty());
326 for (i, key) in keys.iter().copied() {
327 assert_eq!(*map.get(key).unwrap(), i);
328 assert_eq!(*map.get_mut(key).unwrap(), i);
329 }
330
331 map.clear();
332 assert_eq!(map.slots.len(), 128);
333 assert_eq!(map.len(), 0);
334 assert!(map.is_empty());
335 for (_, key) in keys.iter().copied() {
336 assert_eq!(map.get(key).copied(), None);
337 assert_eq!(map.get_mut(key).copied(), None);
338 }
339
340 map.clear();
341 let k1 = map.insert(12);
342 assert_eq!(map.remove(k1), Some(12));
343 assert_eq!(map.remove(k1), None);
344 assert_eq!(map.remove(k1), None);
345 let k2 = map.insert(13);
346 assert_eq!(k1.0, k2.0);
347 assert_eq!(k1.1 + 1, k2.1);
348 assert_eq!(map.remove(k1), None);
349 assert_eq!(map.remove(k1), None);
350 assert_eq!(map.remove(k2), Some(13));
351 assert_eq!(map.remove(k2), None);
352 assert_eq!(map.remove(k2), None);
353
354 map.clear();
355 let kv1 = map.insert(54);
356 let kv2 = map.insert(-4);
357 let kv3 = map.insert(51);
358 let kv4 = map.insert(-53);
359 let kv5 = map.insert(52);
360 let kv6 = map.insert(12);
361 let kv7 = map.insert(2);
362 assert_eq!(map.get(kv1).copied(), Some(54));
363 assert_eq!(map.get(kv2).copied(), Some(-4));
364 assert_eq!(map.get(kv3).copied(), Some(51));
365 assert_eq!(map.get(kv4).copied(), Some(-53));
366 assert_eq!(map.get(kv5).copied(), Some(52));
367 assert_eq!(map.get(kv6).copied(), Some(12));
368 assert_eq!(map.get(kv7).copied(), Some(2));
369 map.retain_mut(|k, v| k == kv6 || *v % 2 != 0);
370 assert_eq!(map.get(kv1).copied(), None);
371 assert_eq!(map.get(kv2).copied(), None);
372 assert_eq!(map.get(kv3).copied(), Some(51));
373 assert_eq!(map.get(kv4).copied(), Some(-53));
374 assert_eq!(map.get(kv5).copied(), None);
375 assert_eq!(map.get(kv6).copied(), Some(12));
376 assert_eq!(map.get(kv7).copied(), None);
377}