concurrent_slotmap/
lib.rs

1extern crate alloc;
2
3use core::{
4    cell::Cell,
5    cmp, fmt,
6    hash::{Hash, Hasher},
7    hint,
8    iter::{self, FusedIterator},
9    marker::PhantomData,
10    mem::{self, MaybeUninit},
11    num::NonZeroU32,
12    slice,
13    sync::atomic::{
14        self, AtomicI32, AtomicU32, AtomicUsize,
15        Ordering::{Acquire, Relaxed, Release},
16    },
17};
18pub use slot::Slot;
19use slot::{header_ptr_from_slots, Vec};
20use std::{hash::DefaultHasher, thread};
21
22pub mod hyaline;
23mod slot;
24
25/// The slot index used to signify the lack thereof.
26const NIL: u32 = u32::MAX;
27
28/// The number of low bits that can be used for user-tagged generations.
29const TAG_BITS: u32 = 8;
30
31/// The mask for user-tagged generations.
32const TAG_MASK: u32 = (1 << TAG_BITS) - 1;
33
34/// The number of bits following the user-tag bits that are used for the state of a slot.
35const STATE_BITS: u32 = 2;
36
37/// The mask for the state of a slot.
38const STATE_MASK: u32 = 0b11 << TAG_BITS;
39
40/// The state tag used to signify that the slot is vacant.
41const VACANT_TAG: u32 = 0b00 << TAG_BITS;
42
43/// The state tag used to signify that the slot is occupied.
44const OCCUPIED_TAG: u32 = 0b01 << TAG_BITS;
45
46/// The state tag used to signify that the slot has been invalidated.
47const INVALIDATED_TAG: u32 = 0b10 << TAG_BITS;
48
49/// The state tag used to signify that the invalidated slot has been reclaimed.
50const RECLAIMED_TAG: u32 = 0b11 << TAG_BITS;
51
52/// The mask for the generation.
53const GENERATION_MASK: u32 = u32::MAX << (TAG_BITS + STATE_BITS);
54
55/// A single generation.
56const ONE_GENERATION: u32 = 1 << (TAG_BITS + STATE_BITS);
57
58/// The number of shards to use.
59static SHARD_COUNT: AtomicUsize = AtomicUsize::new(0);
60
61thread_local! {
62    /// The thread-local shard index.
63    static SHARD_INDEX: Cell<usize> = const { Cell::new(0) };
64}
65
66pub struct SlotMap<K, V> {
67    inner: SlotMapInner<V>,
68    marker: PhantomData<fn(K) -> K>,
69}
70
71struct SlotMapInner<V> {
72    /// ```compile_fail,E0597
73    /// let map = concurrent_slotmap::SlotMap::<_, &'static str>::new(1);
74    /// let guard = &map.pin();
75    /// let id = {
76    ///     let s = "oh no".to_owned();
77    ///     map.insert(&s, guard)
78    /// };
79    /// dbg!(map.get(id, guard));
80    /// ```
81    slots: Vec<V>,
82    collector: hyaline::CollectorHandle,
83}
84
85#[repr(transparent)]
86struct Header {
87    shards: [HeaderShard],
88}
89
90#[repr(align(128))]
91struct HeaderShard {
92    /// The list of slots which have already been dropped and are ready to be claimed by insert
93    /// operations.
94    free_list: AtomicU32,
95    /// The number of occupied slots.
96    len: AtomicI32,
97}
98
99// SAFETY: `SlotMap` is an owned collection, which makes it safe to send to another thread as long
100// as the value is safe to send to another thread. The key is a phantom parameter.
101unsafe impl<K, V: Send> Send for SlotMap<K, V> {}
102
103// SAFETY: `SlotMap` allows pushing through a shared reference, which allows a shared `SlotMap` to
104// be used to send values to another thread. Additionally, `SlotMap` allows getting a reference to
105// any value from any thread. Therefore, it is safe to share `SlotMap` between threads as long as
106// the value is both sendable and shareable. The key is a phantom parameter.
107unsafe impl<K, V: Send + Sync> Sync for SlotMap<K, V> {}
108
109impl<V> SlotMap<SlotId, V> {
110    #[must_use]
111    #[track_caller]
112    pub fn new(max_capacity: u32) -> Self {
113        Self::with_key(max_capacity)
114    }
115
116    /// # Safety
117    ///
118    /// Please see the safety documentation of [`with_collector_and_key`].
119    ///
120    /// [`with_collector_and_key`]: Self::with_collector_and_key
121    #[must_use]
122    #[track_caller]
123    pub unsafe fn with_collector(max_capacity: u32, collector: hyaline::CollectorHandle) -> Self {
124        // SAFETY: Enforced by the caller.
125        unsafe { Self::with_collector_and_key(max_capacity, collector) }
126    }
127}
128
129impl<K, V> SlotMap<K, V> {
130    #[must_use]
131    #[track_caller]
132    pub fn with_key(max_capacity: u32) -> Self {
133        // SAFETY: It's not possible to obtain a `hyaline::Guard` that isn't bound to the collection
134        // without using either the unsafe `hyaline::CollectorHandle::pin` or the unsafe
135        // `SlotMap::with_collector[_and_key]` followed by `SlotMap::pin`.
136        unsafe { Self::with_collector_and_key(max_capacity, hyaline::CollectorHandle::new()) }
137    }
138
139    /// # Safety
140    ///
141    /// The given `collector` must not be used to create any `Guard` that outlives the collection.
142    /// It would result in the `Guard`'s drop implementation attempting to free slots from the
143    /// already freed collection, resulting in a Use-After-Free. You must ensure that the `Guard`
144    /// has its lifetime bound to the collections it protects.
145    ///
146    /// Note that it is not enough for [`CollectorHandle::pin`] to be unsafe because
147    /// [`SlotMap::pin`] is safe:
148    ///
149    /// ```no_run
150    /// # use concurrent_slotmap::{hyaline::CollectorHandle, SlotMap};
151    /// #
152    /// let collector = CollectorHandle::new();
153    /// let map1 = unsafe { SlotMap::<_, i32>::with_collector(1, collector.clone()) };
154    /// let guard = &map1.pin();
155    /// let map2 = unsafe { SlotMap::<_, i32>::with_collector(1, collector) };
156    ///
157    /// map2.remove(map2.insert(69, guard), guard);
158    ///
159    /// // undefined behavior! ⚠️
160    /// ```
161    ///
162    /// [`CollectorHandle::pin`]: hyaline::CollectorHandle::pin
163    #[must_use]
164    #[track_caller]
165    pub unsafe fn with_collector_and_key(
166        max_capacity: u32,
167        collector: hyaline::CollectorHandle,
168    ) -> Self {
169        SlotMap {
170            inner: SlotMapInner {
171                slots: Vec::new(max_capacity),
172                collector,
173            },
174            marker: PhantomData,
175        }
176    }
177
178    #[inline]
179    #[must_use]
180    pub fn capacity(&self) -> u32 {
181        self.inner.slots.capacity()
182    }
183
184    #[inline]
185    #[must_use]
186    pub fn len(&self) -> u32 {
187        self.inner.header().len()
188    }
189
190    #[inline]
191    #[must_use]
192    pub fn is_empty(&self) -> bool {
193        self.len() == 0
194    }
195
196    #[inline]
197    #[must_use]
198    pub fn collector(&self) -> &hyaline::CollectorHandle {
199        &self.inner.collector
200    }
201
202    #[inline]
203    #[must_use]
204    pub fn pin(&self) -> hyaline::Guard<'_> {
205        self.inner.pin()
206    }
207
208    /// # Panics
209    ///
210    /// Panics if `guard.collector()` does not equal `self.collector()`.
211    #[inline]
212    #[track_caller]
213    pub fn slots<'a>(&'a self, guard: &'a hyaline::Guard<'a>) -> Slots<'a, V> {
214        self.inner.check_guard(guard);
215
216        Slots {
217            slots: self.inner.slots.iter(),
218        }
219    }
220}
221
222impl<K: Key, V> SlotMap<K, V> {
223    /// # Panics
224    ///
225    /// Panics if `guard.collector()` does not equal `self.collector()`.
226    #[inline]
227    #[track_caller]
228    pub fn insert<'a>(&'a self, value: V, guard: &'a hyaline::Guard<'a>) -> K {
229        self.insert_with_tag(value, 0, guard)
230    }
231
232    /// # Panics
233    ///
234    /// - Panics if `guard.collector()` does not equal `self.collector()`.
235    /// - Panics if `tag` has more than the low 8 bits set.
236    #[inline]
237    #[track_caller]
238    pub fn insert_with_tag<'a>(&'a self, value: V, tag: u32, guard: &'a hyaline::Guard<'a>) -> K {
239        K::from_id(self.inner.insert_with_tag_with(tag, guard, |_| value))
240    }
241
242    /// # Panics
243    ///
244    /// Panics if `guard.global()` is `Some` and does not equal `self.global()`.
245    #[inline]
246    #[track_caller]
247    pub fn insert_with<'a>(&'a self, guard: &'a hyaline::Guard<'a>, f: impl FnOnce(K) -> V) -> K {
248        self.insert_with_tag_with(0, guard, f)
249    }
250
251    /// # Panics
252    ///
253    /// - Panics if `guard.collector()` does not equal `self.collector()`.
254    /// - Panics if `tag` has more than the low 8 bits set.
255    #[inline]
256    #[track_caller]
257    pub fn insert_with_tag_with<'a>(
258        &'a self,
259        tag: u32,
260        guard: &'a hyaline::Guard<'a>,
261        f: impl FnOnce(K) -> V,
262    ) -> K {
263        let f = |id| f(K::from_id(id));
264
265        K::from_id(self.inner.insert_with_tag_with(tag, guard, f))
266    }
267
268    #[inline]
269    pub fn insert_mut(&mut self, value: V) -> K {
270        self.insert_with_tag_mut(value, 0)
271    }
272
273    /// # Panics
274    ///
275    /// Panics if `tag` has more than the low 8 bits set.
276    #[inline]
277    #[track_caller]
278    pub fn insert_with_tag_mut(&mut self, value: V, tag: u32) -> K {
279        K::from_id(self.inner.insert_with_tag_with_mut(tag, |_| value))
280    }
281
282    #[inline]
283    pub fn insert_with_mut(&mut self, f: impl FnOnce(K) -> V) -> K {
284        self.insert_with_tag_with_mut(0, f)
285    }
286
287    /// # Panics
288    ///
289    /// Panics if `tag` has more than the low 8 bits set.
290    #[inline]
291    #[track_caller]
292    pub fn insert_with_tag_with_mut(&mut self, tag: u32, f: impl FnOnce(K) -> V) -> K {
293        let f = |id| f(K::from_id(id));
294
295        K::from_id(self.inner.insert_with_tag_with_mut(tag, f))
296    }
297
298    /// # Panics
299    ///
300    /// Panics if `guard.collector()` does not equal `self.collector()`.
301    #[inline]
302    #[track_caller]
303    pub fn remove<'a>(&'a self, key: K, guard: &'a hyaline::Guard<'a>) -> Option<&'a V> {
304        self.inner.remove(key.as_id(), guard)
305    }
306
307    #[inline]
308    pub fn remove_mut(&mut self, key: K) -> Option<V> {
309        self.inner.remove_mut(key.as_id())
310    }
311
312    /// # Safety
313    ///
314    /// `key` must refer to a currently occupied slot. That also excludes a race condition when
315    /// calling this method.
316    #[inline]
317    #[track_caller]
318    pub unsafe fn remove_unchecked<'a>(&'a self, key: K, guard: &'a hyaline::Guard<'a>) -> &'a V {
319        // SAFETY: Enforced by the caller.
320        unsafe { self.inner.remove_unchecked(key.as_id(), guard) }
321    }
322
323    #[cfg(test)]
324    fn remove_index<'a>(&'a self, index: u32, guard: &'a hyaline::Guard<'a>) -> Option<&'a V> {
325        self.inner.remove_index(index, guard)
326    }
327
328    #[inline]
329    #[track_caller]
330    pub fn invalidate<'a>(&'a self, key: K, guard: &'a hyaline::Guard<'a>) -> Option<&'a V> {
331        self.inner.invalidate(key.as_id(), guard)
332    }
333
334    #[inline]
335    pub fn remove_invalidated(&self, key: K) -> Option<()> {
336        self.inner.remove_invalidated(key.as_id())
337    }
338
339    /// # Safety
340    ///
341    /// `key` must refer to a currently invalidated slot. That also excludes a race condition when
342    /// calling this method.
343    #[inline]
344    pub unsafe fn remove_invalidated_unchecked(&self, key: K) {
345        // SAFETY: Enforced by the caller.
346        unsafe { self.inner.remove_invalidated_unchecked(key.as_id()) };
347    }
348
349    /// # Panics
350    ///
351    /// Panics if `guard.collector()` does not equal `self.collector()`.
352    #[inline(always)]
353    #[must_use]
354    #[track_caller]
355    pub fn get<'a>(&'a self, key: K, guard: &'a hyaline::Guard<'a>) -> Option<&'a V> {
356        self.inner.get(key.as_id(), guard)
357    }
358
359    #[inline(always)]
360    #[must_use]
361    pub fn get_mut(&mut self, key: K) -> Option<&mut V> {
362        self.inner.get_mut(key.as_id())
363    }
364
365    #[inline]
366    #[must_use]
367    pub fn get_disjoint_mut<const N: usize>(&mut self, keys: [K; N]) -> Option<[&mut V; N]> {
368        self.inner.get_disjoint_mut(keys.map(Key::as_id))
369    }
370
371    #[cfg(test)]
372    fn index<'a>(&'a self, index: u32, guard: &'a hyaline::Guard<'a>) -> Option<&'a V> {
373        self.inner.index(index, guard)
374    }
375
376    /// # Safety
377    ///
378    /// The slot must be currently occupied.
379    ///
380    /// # Panics
381    ///
382    /// Panics if `guard.collector()` does not equal `self.collector()`.
383    #[inline(always)]
384    #[must_use]
385    #[track_caller]
386    pub unsafe fn get_unchecked<'a>(&'a self, key: K, guard: &'a hyaline::Guard<'a>) -> &'a V {
387        // SAFETY: Enforced by the caller.
388        unsafe { self.inner.get_unchecked(key.as_id(), guard) }
389    }
390
391    /// # Safety
392    ///
393    /// The slot must be currently occupied.
394    #[inline(always)]
395    #[must_use]
396    pub unsafe fn get_unchecked_mut(&mut self, key: K) -> &mut V {
397        // SAFETY: Enforced by the caller.
398        unsafe { self.inner.get_unchecked_mut(key.as_id()) }
399    }
400
401    /// # Panics
402    ///
403    /// Panics if `guard.collector()` does not equal `self.collector()`.
404    #[inline]
405    #[must_use]
406    #[track_caller]
407    pub fn iter<'a>(&'a self, guard: &'a hyaline::Guard<'a>) -> Iter<'a, K, V> {
408        self.inner.check_guard(guard);
409
410        Iter {
411            slots: self.inner.slots.iter().enumerate(),
412            marker: PhantomData,
413        }
414    }
415
416    #[inline]
417    #[must_use]
418    pub fn iter_mut(&mut self) -> IterMut<'_, K, V> {
419        IterMut {
420            slots: self.inner.slots.iter_mut().enumerate(),
421            marker: PhantomData,
422        }
423    }
424}
425
426impl<K: Key, V> SlotMap<K, MaybeUninit<V>> {
427    /// # Panics
428    ///
429    /// Panics if `guard.collector()` does not equal `self.collector()`.
430    #[inline]
431    #[track_caller]
432    pub fn revive_or_insert_with<'a>(
433        &'a self,
434        guard: &'a hyaline::Guard<'a>,
435        f: impl FnOnce(K) -> MaybeUninit<V>,
436    ) -> (K, &'a MaybeUninit<V>) {
437        let f = |id| f(K::from_id(id));
438
439        let (id, value) = self.inner.revive_or_insert_with(guard, f);
440
441        (K::from_id(id), value)
442    }
443}
444
445impl<V> SlotMapInner<V> {
446    fn pin(&self) -> hyaline::Guard<'_> {
447        // SAFETY: The guard's lifetime is bound to the collection.
448        unsafe { self.collector.pin() }
449    }
450
451    #[track_caller]
452    fn insert_with_tag_with<'a>(
453        &'a self,
454        tag: u32,
455        guard: &'a hyaline::Guard<'a>,
456        f: impl FnOnce(SlotId) -> V,
457    ) -> SlotId {
458        assert_eq!(tag & !TAG_MASK, 0);
459
460        let id = if let Some((id, slot)) = self.allocate_slot(tag, guard) {
461            // SAFETY: The free-list always contains slots that are no longer read by any threads
462            // and we have removed the slot from the free-list such that no other threads can be
463            // writing the same slot.
464            unsafe { slot.value.get().cast::<V>().write(f(id)) };
465
466            slot.generation.store(id.generation(), Release);
467
468            id
469        } else {
470            self.slots.push_with_tag_with(tag, f).0
471        };
472
473        self.header().shard().len.fetch_add(1, Relaxed);
474
475        id
476    }
477
478    #[track_caller]
479    fn allocate_slot<'a>(
480        &'a self,
481        tag: u32,
482        guard: &'a hyaline::Guard<'a>,
483    ) -> Option<(SlotId, &'a Slot<V>)> {
484        self.check_guard(guard);
485
486        'outer: for shard in self.header().shards() {
487            let mut free_list_head = shard.free_list.load(Acquire);
488            let mut backoff = Backoff::new();
489
490            loop {
491                if free_list_head == NIL {
492                    continue 'outer;
493                }
494
495                // SAFETY: We always push indices of existing slots into the free-lists and the
496                // slots vector never shrinks, therefore the index must have staid in bounds.
497                let slot = unsafe { self.slots.get_unchecked(free_list_head) };
498
499                let next_free = slot.next_free.load(Relaxed);
500
501                match shard.free_list.compare_exchange_weak(
502                    free_list_head,
503                    next_free,
504                    Release,
505                    Acquire,
506                ) {
507                    Ok(_) => {
508                        let generation = slot.generation.load(Relaxed);
509
510                        debug_assert!(generation & STATE_MASK == VACANT_TAG);
511
512                        let new_generation = generation | OCCUPIED_TAG | tag;
513
514                        // SAFETY: We always push slots with their state tag set to `VACANT_TAG`
515                        // into the free-list and we replaced the tag with `OCCUPIED_TAG` above.
516                        let id = unsafe { SlotId::new_unchecked(free_list_head, new_generation) };
517
518                        return Some((id, slot));
519                    }
520                    Err(new_head) => {
521                        free_list_head = new_head;
522                        backoff.spin();
523                    }
524                }
525            }
526        }
527
528        None
529    }
530
531    #[track_caller]
532    fn insert_with_tag_with_mut(&mut self, tag: u32, f: impl FnOnce(SlotId) -> V) -> SlotId {
533        assert_eq!(tag & !TAG_MASK, 0);
534
535        // SAFETY: We unbind the lifetime to convince the borrow checker that we don't borrow
536        // `self.slots` mutably more than once. We don't because the header and slots are occupying
537        // disjoint memory ranges.
538        let header = unsafe { mem::transmute::<&mut Header, &mut Header>(self.slots.header_mut()) };
539
540        for shard in header.shards_mut() {
541            let free_list_head = *shard.free_list.get_mut();
542
543            if free_list_head != NIL {
544                // SAFETY: We always push indices of existing slots into the free-lists and the
545                // slots vector never shrinks, therefore the index must have staid in bounds.
546                let slot = unsafe { self.slots.get_unchecked_mut(free_list_head) };
547
548                *shard.free_list.get_mut() = *slot.next_free.get_mut();
549
550                let generation = *slot.generation.get_mut();
551
552                debug_assert!(generation & STATE_MASK == VACANT_TAG);
553
554                let new_generation = generation | OCCUPIED_TAG | tag;
555
556                // SAFETY: We always push slots with their state tag set to `VACANT_TAG` into the
557                // free-list and we replaced the tag with `OCCUPIED_TAG` above.
558                let id = unsafe { SlotId::new_unchecked(free_list_head, new_generation) };
559
560                *slot.value.get_mut() = MaybeUninit::new(f(id));
561
562                *slot.generation.get_mut() = new_generation;
563
564                let len = header.shard_mut().len.get_mut();
565                *len = len.wrapping_add(1);
566
567                return id;
568            }
569        }
570
571        let id = self.slots.push_with_tag_with_mut(tag, f);
572
573        let len = header.shard_mut().len.get_mut();
574        *len = len.wrapping_add(1);
575
576        id
577    }
578
579    #[track_caller]
580    fn remove<'a>(&'a self, id: SlotId, guard: &'a hyaline::Guard<'a>) -> Option<&'a V> {
581        self.check_guard(guard);
582
583        let slot = self.slots.get(id.index)?;
584        let new_generation = (id.generation() & GENERATION_MASK).wrapping_add(ONE_GENERATION);
585
586        if slot
587            .generation
588            .compare_exchange(id.generation(), new_generation, Acquire, Relaxed)
589            .is_err()
590        {
591            return None;
592        }
593
594        self.header().shard().len.fetch_sub(1, Relaxed);
595
596        // SAFETY: We set the slot's state tag to `VACANT_TAG` such that no other threads can access
597        // the slot going forward.
598        unsafe { guard.defer_reclaim(id.index, &self.slots) };
599
600        // SAFETY:
601        // * The `Acquire` ordering when loading the slot's generation synchronizes with the
602        //   `Release` ordering in `SlotMap::insert`, making sure that the newly written value is
603        //   visible here.
604        // * The `compare_exchange` above succeeded, which means that the previous state tag of the
605        //   slot must have been `OCCUPIED_TAG`, which means it must have been initialized in
606        //   `SlotMap::insert[_mut]`.
607        Some(unsafe { slot.value_unchecked() })
608    }
609
610    fn remove_mut(&mut self, id: SlotId) -> Option<V> {
611        // SAFETY: We unbind the lifetime to convince the borrow checker that we don't borrow
612        // `self.slots` mutably more than once. We don't because the header and slots are occupying
613        // disjoint memory ranges.
614        let header = unsafe { mem::transmute::<&mut Header, &mut Header>(self.slots.header_mut()) };
615
616        let slot = self.slots.get_mut(id.index)?;
617        let generation = *slot.generation.get_mut();
618
619        if generation == id.generation() {
620            let new_generation = (generation & GENERATION_MASK).wrapping_add(ONE_GENERATION);
621            *slot.generation.get_mut() = new_generation;
622
623            *slot.next_free.get_mut() = *header.shard_mut().free_list.get_mut();
624            *header.shard_mut().free_list.get_mut() = id.index;
625
626            let len = header.shard_mut().len.get_mut();
627            *len = len.wrapping_sub(1);
628
629            // SAFETY:
630            // * The mutable reference makes sure that access to the slot is synchronized.
631            // * We checked that `id.generation` matches the slot's generation, which means that the
632            //   previous state tag of the slot must have been `OCCUPIED_TAG`, which means it must
633            //   have been initialized in `SlotMap::insert[_mut]`.
634            // * We set the slot's state tag to `VACANT_TAG` such that future attempts to access the
635            //   slot will fail.
636            Some(unsafe { slot.value.get().cast::<V>().read() })
637        } else {
638            None
639        }
640    }
641
642    #[track_caller]
643    unsafe fn remove_unchecked<'a>(&'a self, id: SlotId, guard: &'a hyaline::Guard<'a>) -> &'a V {
644        self.check_guard(guard);
645
646        // SAFETY: The caller must ensure that the index is in bounds.
647        let slot = unsafe { self.slots.get_unchecked(id.index) };
648
649        let new_generation = (id.generation() & GENERATION_MASK).wrapping_add(ONE_GENERATION);
650
651        let generation = slot.generation.swap(new_generation, Acquire);
652
653        assert_unsafe_precondition!(
654            is_occupied(generation),
655            "`id` must refer to a currently occupied slot",
656        );
657
658        self.header().shard().len.fetch_sub(1, Relaxed);
659
660        // SAFETY: We set the slot's state tag to `VACANT_TAG` such that no other threads can access
661        // the slot going forward. The caller must ensure that a race condition doesn't occur.
662        unsafe { guard.defer_reclaim(id.index, &self.slots) };
663
664        // SAFETY:
665        // * The `Acquire` ordering when loading the slot's generation synchronizes with the
666        //   `Release` ordering in `SlotMap::insert`, making sure that the newly written value is
667        //   visible here.
668        // * The caller must ensure that the slot is occupied, which means it must have been
669        //   initialized in `SlotMap::insert[_mut]`.
670        unsafe { slot.value_unchecked() }
671    }
672
673    #[cfg(test)]
674    fn remove_index<'a>(&'a self, index: u32, guard: &'a hyaline::Guard<'a>) -> Option<&'a V> {
675        self.check_guard(guard);
676
677        let slot = self.slots.get(index)?;
678        let mut generation = slot.generation.load(Relaxed);
679
680        loop {
681            if !is_occupied(generation) {
682                return None;
683            }
684
685            let new_generation = (generation & GENERATION_MASK).wrapping_add(ONE_GENERATION);
686
687            match slot.generation.compare_exchange_weak(
688                generation,
689                new_generation,
690                Acquire,
691                Relaxed,
692            ) {
693                Ok(_) => break,
694                Err(new_generation) => generation = new_generation,
695            }
696        }
697
698        self.header().shard().len.fetch_sub(1, Relaxed);
699
700        // SAFETY: We set the slot's state tag to `VACANT_TAG` such that no other threads can access
701        // the slot going forward.
702        unsafe { guard.defer_reclaim(index, &self.slots) };
703
704        // SAFETY:
705        // * The `Acquire` ordering when loading the slot's generation synchronizes with the
706        //   `Release` ordering in `SlotMap::insert`, making sure that the newly written value is
707        //   visible here.
708        // * The `compare_exchange_weak` above succeeded, which means that the previous state tag of
709        //   the slot must have been `OCCUPIED_TAG`, which means it must have been initialized in
710        //   `SlotMap::insert[_mut]`.
711        Some(unsafe { slot.value_unchecked() })
712    }
713
714    #[track_caller]
715    fn invalidate<'a>(&'a self, id: SlotId, guard: &'a hyaline::Guard<'a>) -> Option<&'a V> {
716        self.check_guard(guard);
717
718        let slot = self.slots.get(id.index)?;
719        let new_generation = (id.generation() & !STATE_MASK) | INVALIDATED_TAG;
720
721        if slot
722            .generation
723            .compare_exchange(id.generation(), new_generation, Acquire, Relaxed)
724            .is_err()
725        {
726            return None;
727        }
728
729        self.header().shard().len.fetch_sub(1, Relaxed);
730
731        // SAFETY: We set the slot's state tag to `INVALIDATED_TAG` such that no other threads can
732        // access the slot going forward.
733        unsafe { guard.defer_reclaim_invalidated(id.index, &self.slots) };
734
735        // SAFETY:
736        // * The `Acquire` ordering when loading the slot's generation synchronizes with the
737        //   `Release` ordering in `SlotMap::insert`, making sure that the newly written value is
738        //   visible here.
739        // * The `compare_exchange` above succeeded, which means that the previous state tag of the
740        //   slot must have been `OCCUPIED_TAG`, which means it must have been initialized in
741        //   `SlotMap::insert[_mut]`.
742        Some(unsafe { slot.value_unchecked() })
743    }
744
745    fn remove_invalidated(&self, id: SlotId) -> Option<()> {
746        let slot = self.slots.get(id.index)?;
747        let mut generation = slot.generation.load(Relaxed);
748        let new_generation = (id.generation() & GENERATION_MASK).wrapping_add(ONE_GENERATION);
749
750        loop {
751            if generation & !STATE_MASK != id.generation() & !STATE_MASK {
752                break None;
753            }
754
755            if generation & STATE_MASK == RECLAIMED_TAG {
756                match slot.generation.compare_exchange_weak(
757                    generation,
758                    new_generation,
759                    Acquire,
760                    Relaxed,
761                ) {
762                    Ok(_) => {
763                        // SAFETY:
764                        // * The `Acquire` ordering when loading the slot's generation synchronizes
765                        //   with the `Release` ordering in `SlotMap::insert`, making sure that the
766                        //   newly written value is visible here.
767                        // * The `compare_exchange_weak` above succeeded, which means that the
768                        //   previous state tag of the slot must have been `RECLAIMED_TAG`, which
769                        //   means it must have been reclaimed in `reclaim_invalidated`, which means
770                        //   it must have been invalidated in `SlotMap::invalidate`, which means it
771                        //   must have been initialized in `SlotMap::insert[_mut]`.
772                        // * We set the slot's state tag to `VACANT_TAG` such that future attempts
773                        //   to access the slot will fail.
774                        unsafe { reclaim(id.index, self.slots.as_ptr()) };
775
776                        break Some(());
777                    }
778                    Err(new_generation) => generation = new_generation,
779                }
780            } else if generation & STATE_MASK == INVALIDATED_TAG {
781                match slot.generation.compare_exchange_weak(
782                    generation,
783                    new_generation,
784                    Relaxed,
785                    Relaxed,
786                ) {
787                    Ok(_) => break Some(()),
788                    Err(new_generation) => generation = new_generation,
789                }
790            } else {
791                break None;
792            }
793        }
794    }
795
796    unsafe fn remove_invalidated_unchecked(&self, id: SlotId) {
797        // SAFETY: The caller must ensure that the index is in bounds.
798        let slot = unsafe { self.slots.get_unchecked(id.index) };
799
800        let new_generation = (id.generation() & GENERATION_MASK).wrapping_add(ONE_GENERATION);
801
802        let generation = slot.generation.swap(new_generation, Relaxed);
803
804        assert_unsafe_precondition!(
805            generation & STATE_MASK == RECLAIMED_TAG || generation & STATE_MASK == INVALIDATED_TAG,
806            "`id` must refer to a currently invalidated slot",
807        );
808
809        if generation & STATE_MASK == RECLAIMED_TAG {
810            atomic::fence(Acquire);
811
812            // SAFETY:
813            // * The `Acquire` fence after loading the slot's generation synchronizes with the
814            //   `Release` ordering in `SlotMap::insert`, making sure that the newly written value
815            //   is visible here.
816            // * The previous state tag of the slot was `RECLAIMED_TAG`, which means it must have
817            //   been reclaimed in `reclaim_invalidated`, which means it must have been invalidated
818            //   in `SlotMap::invalidate`, which means it must have been initialized in
819            //   `SlotMap::insert[_mut]`.
820            // * We set the slot's state tag to `VACANT_TAG` such that future attempts to access the
821            //   slot will fail.
822            // * The caller must ensure that a race condition doesn't occur.
823            unsafe { reclaim(id.index, self.slots.as_ptr()) };
824        }
825    }
826
827    #[inline(always)]
828    #[track_caller]
829    fn get<'a>(&'a self, id: SlotId, guard: &'a hyaline::Guard<'a>) -> Option<&'a V> {
830        self.check_guard(guard);
831
832        let slot = self.slots.get(id.index)?;
833        let generation = slot.generation.load(Acquire);
834
835        if generation == id.generation() {
836            // SAFETY:
837            // * The `Acquire` ordering when loading the slot's generation synchronizes with the
838            //   `Release` ordering in `SlotMap::insert`, making sure that the newly written value
839            //   is visible here.
840            // * We checked that `id.generation` matches the slot's generation, which means that the
841            //   state tag of the slot must have been `OCCUPIED_TAG`, which means it must have been
842            //   initialized in `SlotMap::insert[_mut]`.
843            Some(unsafe { slot.value_unchecked() })
844        } else {
845            None
846        }
847    }
848
849    #[inline(always)]
850    fn get_mut(&mut self, id: SlotId) -> Option<&mut V> {
851        let slot = self.slots.get_mut(id.index)?;
852        let generation = *slot.generation.get_mut();
853
854        if generation == id.generation() {
855            // SAFETY:
856            // * The mutable reference makes sure that access to the slot is synchronized.
857            // * We checked that `id.generation` matches the slot's generation, which means that the
858            //   state tag of the slot must have been `OCCUPIED_TAG`, which means it must have been
859            //   initialized in `SlotMap::insert[_mut]`.
860            Some(unsafe { slot.value_unchecked_mut() })
861        } else {
862            None
863        }
864    }
865
866    #[inline]
867    fn get_disjoint_mut<const N: usize>(&mut self, ids: [SlotId; N]) -> Option<[&mut V; N]> {
868        fn get_disjoint_check_valid<const N: usize>(ids: &[SlotId; N], len: u32) -> bool {
869            let mut valid = true;
870
871            for (i, id) in ids.iter().enumerate() {
872                valid &= id.index < len;
873
874                for id2 in &ids[..i] {
875                    valid &= id.index != id2.index;
876                }
877            }
878
879            valid
880        }
881
882        let len = self.slots.capacity_mut();
883
884        if get_disjoint_check_valid(&ids, len) {
885            // SAFETY: We checked that all indices are disjunct and in bounds of the slots vector.
886            unsafe { self.get_disjoint_unchecked_mut(ids) }
887        } else {
888            None
889        }
890    }
891
892    #[inline]
893    unsafe fn get_disjoint_unchecked_mut<const N: usize>(
894        &mut self,
895        ids: [SlotId; N],
896    ) -> Option<[&mut V; N]> {
897        let mut refs = MaybeUninit::<[&mut V; N]>::uninit();
898        let refs_ptr = refs.as_mut_ptr().cast::<&mut V>();
899
900        for i in 0..N {
901            // SAFETY: `i` is in bounds of the array.
902            let id = unsafe { ids.get_unchecked(i) };
903
904            // SAFETY:
905            // * The caller must ensure that `ids` contains only IDs whose indices are in bounds of
906            //   the slots vector.
907            // * The caller must ensure that `ids` contains only IDs with disjunct indices.
908            let slot = unsafe { self.slots.get_unchecked_mut(id.index) };
909
910            // SAFETY: We unbind the lifetime to convince the borrow checker that we don't
911            // repeatedly borrow from `self.slots`. We don't for the same reasons as above.
912            // `Vec::get_unchecked_mut` also only borrows the one element and not the whole `Vec`.
913            let slot = unsafe { mem::transmute::<&mut Slot<V>, &mut Slot<V>>(slot) };
914
915            let generation = *slot.generation.get_mut();
916
917            if generation != id.generation() {
918                return None;
919            }
920
921            // SAFETY:
922            // * The mutable reference makes sure that access to the slot is synchronized.
923            // * We checked that `id.generation` matches the slot's generation, which means that the
924            //   state tag of the slot must have been `OCCUPIED_TAG`, which means it must have been
925            //   initialized in `SlotMap::insert[_mut]`.
926            let value = unsafe { slot.value_unchecked_mut() };
927
928            // SAFETY: `i` is in bounds of the array.
929            unsafe { *refs_ptr.add(i) = value };
930        }
931
932        // SAFETY: We initialized all the elements.
933        Some(unsafe { refs.assume_init() })
934    }
935
936    #[cfg(test)]
937    fn index<'a>(&'a self, index: u32, guard: &'a hyaline::Guard<'a>) -> Option<&'a V> {
938        self.check_guard(guard);
939
940        let slot = self.slots.get(index)?;
941        let generation = slot.generation.load(Acquire);
942
943        if is_occupied(generation) {
944            // SAFETY:
945            // * The `Acquire` ordering when loading the slot's generation synchronizes with the
946            //   `Release` ordering in `SlotMap::insert`, making sure that the newly written value
947            //   is visible here.
948            // * We checked that the slot is occupied, which means that it must have been
949            //   initialized in `SlotMap::insert[_mut]`.
950            Some(unsafe { slot.value_unchecked() })
951        } else {
952            None
953        }
954    }
955
956    #[inline(always)]
957    #[track_caller]
958    unsafe fn get_unchecked<'a>(&'a self, id: SlotId, guard: &'a hyaline::Guard<'a>) -> &'a V {
959        self.check_guard(guard);
960
961        // SAFETY: The caller must ensure that the index is in bounds.
962        let slot = unsafe { self.slots.get_unchecked(id.index) };
963
964        let _generation = slot.generation.load(Acquire);
965
966        // SAFETY:
967        // * The `Acquire` ordering when loading the slot's generation synchronizes with the
968        //   `Release` ordering in `SlotMap::insert`, making sure that the newly written value is
969        //   visible here.
970        // * The caller must ensure that the slot is initialized.
971        unsafe { slot.value_unchecked() }
972    }
973
974    #[inline(always)]
975    unsafe fn get_unchecked_mut(&mut self, id: SlotId) -> &mut V {
976        // SAFETY: The caller must ensure that the index is in bounds.
977        let slot = unsafe { self.slots.get_unchecked_mut(id.index) };
978
979        // SAFETY:
980        // * The mutable reference makes sure that access to the slot is synchronized.
981        // * The caller must ensure that the slot is initialized.
982        unsafe { slot.value_unchecked_mut() }
983    }
984
985    #[inline]
986    fn collector(&self) -> &hyaline::CollectorHandle {
987        &self.collector
988    }
989
990    #[inline]
991    fn header(&self) -> &Header {
992        self.slots.header()
993    }
994
995    #[inline(always)]
996    #[track_caller]
997    fn check_guard(&self, guard: &hyaline::Guard<'_>) {
998        #[inline(never)]
999        #[track_caller]
1000        fn collector_mismatch() -> ! {
1001            panic!("the given guard does not belong to this collection");
1002        }
1003
1004        if guard.collector() != self.collector() {
1005            collector_mismatch();
1006        }
1007    }
1008}
1009
1010impl<V> SlotMapInner<MaybeUninit<V>> {
1011    #[track_caller]
1012    fn revive_or_insert_with<'a>(
1013        &'a self,
1014        guard: &'a hyaline::Guard<'a>,
1015        f: impl FnOnce(SlotId) -> MaybeUninit<V>,
1016    ) -> (SlotId, &'a MaybeUninit<V>) {
1017        let (id, slot) = if let Some((id, slot)) = self.allocate_slot(0, guard) {
1018            slot.generation.store(id.generation(), Release);
1019
1020            (id, slot)
1021        } else {
1022            self.slots.push_with_tag_with(0, f)
1023        };
1024
1025        self.header().shard().len.fetch_add(1, Relaxed);
1026
1027        // SAFETY: The value is wrapped in `MaybeUninit`.
1028        (id, unsafe { slot.value_unchecked() })
1029    }
1030}
1031
1032unsafe fn reclaim<V>(index: u32, slots: *const Slot<V>) {
1033    // SAFETY: The caller must ensure that `index` is in bounds of `slots` and that `slots` is a
1034    // valid pointer to the allocation of `Slot<V>`s.
1035    let slot = unsafe { &*slots.add(index as usize) };
1036
1037    // SAFETY: The caller must ensure that we have exclusive access to the slot.
1038    unsafe { slot.value.get().cast::<V>().drop_in_place() };
1039
1040    // SAFETY: The caller must ensure that `slots` is a valid pointer to the allocation of
1041    // `Slot<V>`s, and that allocation has the `Header` right before the start of the slots.
1042    let header = unsafe { &*header_ptr_from_slots(slots.cast()) };
1043
1044    let shard = header.shard();
1045
1046    let mut free_list_head = shard.free_list.load(Acquire);
1047    let mut backoff = Backoff::new();
1048
1049    loop {
1050        slot.next_free.store(free_list_head, Relaxed);
1051
1052        match shard
1053            .free_list
1054            .compare_exchange_weak(free_list_head, index, Release, Acquire)
1055        {
1056            Ok(_) => break,
1057            Err(new_head) => {
1058                free_list_head = new_head;
1059                backoff.spin();
1060            }
1061        }
1062    }
1063}
1064
1065unsafe fn reclaim_invalidated<V>(index: u32, slots: *const Slot<V>) {
1066    // SAFETY: The caller must ensure that `index` is in bounds of `slots` and that `slots` is a
1067    // valid pointer to the allocation of `Slot<V>`s.
1068    let slot = unsafe { &*slots.add(index as usize) };
1069
1070    let mut generation = slot.generation.load(Relaxed);
1071
1072    while generation & STATE_MASK == INVALIDATED_TAG {
1073        let new_generation = (generation & !STATE_MASK) | RECLAIMED_TAG;
1074
1075        match slot
1076            .generation
1077            .compare_exchange_weak(generation, new_generation, Relaxed, Relaxed)
1078        {
1079            Ok(_) => return,
1080            Err(new_generation) => generation = new_generation,
1081        }
1082    }
1083
1084    debug_assert!(generation & STATE_MASK == VACANT_TAG);
1085
1086    atomic::fence(Acquire);
1087
1088    // SAFETY:
1089    // * The `Acquire` fence after loading the slot's generation synchronizes with the `Release`
1090    //   ordering in `SlotMap::insert`, making sure that the newly written value is visible here.
1091    // * The previous state tag of the slot must have been `VACANT_TAG`, which means it must have
1092    //   been removed in `SlotMap::remove_invalidated`, which means it must have been invalidated in
1093    //   `SlotMap::invalidate`, which means it must have been initialized in
1094    //   `SlotMap::insert[_mut]`.
1095    unsafe { reclaim(index, slots) };
1096}
1097
1098impl<K: fmt::Debug + Key, V: fmt::Debug> fmt::Debug for SlotMap<K, V> {
1099    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1100        f.debug_struct("SlotMap").finish_non_exhaustive()
1101    }
1102}
1103
1104impl<V> Drop for SlotMapInner<V> {
1105    fn drop(&mut self) {
1106        if !core::mem::needs_drop::<V>() {
1107            return;
1108        }
1109
1110        for slot in self.slots.iter_mut() {
1111            if *slot.generation.get_mut() & STATE_MASK != VACANT_TAG {
1112                let ptr = slot.value.get_mut().as_mut_ptr();
1113
1114                // SAFETY:
1115                // * The mutable reference makes sure that access to the slot is synchronized.
1116                // * We checked that the slot is not vacant, which means that it must have been
1117                //   initialized in `SlotMap::insert[_mut]`.
1118                unsafe { ptr.drop_in_place() };
1119            }
1120        }
1121    }
1122}
1123
1124impl<'a, K: Key, V> IntoIterator for &'a mut SlotMap<K, V> {
1125    type Item = (K, &'a mut V);
1126
1127    type IntoIter = IterMut<'a, K, V>;
1128
1129    #[inline]
1130    fn into_iter(self) -> Self::IntoIter {
1131        self.iter_mut()
1132    }
1133}
1134
1135impl Header {
1136    #[inline]
1137    fn shard(&self) -> &HeaderShard {
1138        let shard_index = SHARD_INDEX.with(Cell::get);
1139
1140        // SAFETY: `set_shard_index` ensures that `SHARD_INDEX` is in bounds of the shards.
1141        unsafe { self.shards.get_unchecked(shard_index) }
1142    }
1143
1144    #[inline]
1145    fn shard_mut(&mut self) -> &mut HeaderShard {
1146        // SAFETY: There is always a non-zero number of shards.
1147        unsafe { self.shards.get_unchecked_mut(0) }
1148    }
1149
1150    #[inline]
1151    fn shards(&self) -> HeaderShards<'_> {
1152        let shard_index = SHARD_INDEX.with(Cell::get);
1153
1154        HeaderShards {
1155            shards: &self.shards,
1156            shard_index,
1157            yielded: 0,
1158        }
1159    }
1160
1161    #[inline]
1162    fn shards_mut(&mut self) -> slice::IterMut<'_, HeaderShard> {
1163        self.shards.iter_mut()
1164    }
1165
1166    #[inline]
1167    fn len(&self) -> u32 {
1168        self.shards()
1169            .map(|shard| shard.len.load(Relaxed))
1170            .sum::<i32>()
1171            .try_into()
1172            .unwrap_or(0)
1173    }
1174}
1175
1176struct HeaderShards<'a> {
1177    shards: &'a [HeaderShard],
1178    shard_index: usize,
1179    yielded: usize,
1180}
1181
1182impl<'a> Iterator for HeaderShards<'a> {
1183    type Item = &'a HeaderShard;
1184
1185    #[inline]
1186    fn next(&mut self) -> Option<Self::Item> {
1187        if self.yielded < self.shards.len() {
1188            let current_index = (self.shard_index + self.yielded) & (self.shards.len() - 1);
1189            self.yielded += 1;
1190
1191            // SAFETY: `Header::shards` ensures that `current_index` starts out in bounds of the
1192            // shards and we made sure that the next iteration has an index that's in bounds too.
1193            Some(unsafe { self.shards.get_unchecked(current_index) })
1194        } else {
1195            None
1196        }
1197    }
1198}
1199
1200#[inline(never)]
1201fn set_shard_index() {
1202    let mut state = DefaultHasher::new();
1203    thread::current().id().hash(&mut state);
1204    let thread_id_hash = state.finish();
1205
1206    let shard_count = SHARD_COUNT.load(Relaxed);
1207    let shard_index = (thread_id_hash & (shard_count as u64 - 1)) as usize;
1208    SHARD_INDEX.with(|cell| cell.set(shard_index));
1209}
1210
1211pub trait Key: Sized {
1212    fn from_id(id: SlotId) -> Self;
1213
1214    #[allow(clippy::wrong_self_convention)]
1215    fn as_id(self) -> SlotId;
1216}
1217
1218impl Key for SlotId {
1219    #[inline(always)]
1220    fn from_id(id: SlotId) -> Self {
1221        id
1222    }
1223
1224    #[inline(always)]
1225    fn as_id(self) -> SlotId {
1226        self
1227    }
1228}
1229
1230#[derive(Clone, Copy)]
1231#[repr(C, align(8))]
1232pub struct SlotId {
1233    #[cfg(target_endian = "little")]
1234    index: u32,
1235    generation: NonZeroU32,
1236    #[cfg(target_endian = "big")]
1237    index: u32,
1238}
1239
1240impl Default for SlotId {
1241    #[inline]
1242    fn default() -> Self {
1243        Self::INVALID
1244    }
1245}
1246
1247impl SlotId {
1248    pub const INVALID: Self = SlotId {
1249        index: u32::MAX,
1250        generation: NonZeroU32::MAX,
1251    };
1252
1253    pub const TAG_BITS: u32 = TAG_BITS;
1254
1255    pub const TAG_MASK: u32 = TAG_MASK;
1256
1257    pub const STATE_BITS: u32 = STATE_BITS;
1258
1259    pub const STATE_MASK: u32 = STATE_MASK;
1260
1261    pub const OCCUPIED_TAG: u32 = OCCUPIED_TAG;
1262
1263    #[inline(always)]
1264    #[must_use]
1265    #[track_caller]
1266    pub const fn new(index: u32, generation: u32) -> Self {
1267        assert!(is_occupied(generation));
1268
1269        // SAFETY: We checked that the state tag of `generation` is `OCCUPIED_TAG`.
1270        unsafe { SlotId::new_unchecked(index, generation) }
1271    }
1272
1273    /// # Safety
1274    ///
1275    /// `generation`, when masked out with [`STATE_MASK`], must equal [`OCCUPIED_TAG`].
1276    ///
1277    /// [`STATE_MASK`]: Self::STATE_MASK
1278    /// [`OCCUPIED_TAG`]: Self::OCCUPIED_TAG
1279    #[inline(always)]
1280    #[must_use]
1281    pub const unsafe fn new_unchecked(index: u32, generation: u32) -> Self {
1282        // TODO: Replace with `assert_unsafe_precondition` when it can be made const.
1283        debug_assert!(is_occupied(generation));
1284
1285        // SAFETY: The caller must ensure that the state tag of `generation` is `OCCUPIED_TAG`.
1286        let generation = unsafe { NonZeroU32::new_unchecked(generation) };
1287
1288        SlotId { index, generation }
1289    }
1290
1291    #[inline(always)]
1292    #[must_use]
1293    pub const fn index(self) -> u32 {
1294        self.index
1295    }
1296
1297    #[inline(always)]
1298    #[must_use]
1299    pub const fn generation(self) -> u32 {
1300        self.generation.get()
1301    }
1302
1303    #[inline(always)]
1304    #[must_use]
1305    pub const fn tag(self) -> u32 {
1306        self.generation.get() & TAG_MASK
1307    }
1308
1309    #[inline]
1310    fn as_u64(self) -> u64 {
1311        u64::from(self.index) | (u64::from(self.generation.get()) << 32)
1312    }
1313}
1314
1315impl fmt::Debug for SlotId {
1316    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1317        if *self == Self::INVALID {
1318            return f.write_str("INVALID");
1319        }
1320
1321        let generation = self.generation() >> (TAG_BITS + STATE_BITS);
1322        write!(f, "{}v{}", self.index, generation)?;
1323
1324        if self.generation() & TAG_MASK != 0 {
1325            write!(f, "t{}", self.generation() & TAG_MASK)?;
1326        }
1327
1328        Ok(())
1329    }
1330}
1331
1332impl PartialEq for SlotId {
1333    #[inline]
1334    fn eq(&self, other: &Self) -> bool {
1335        self.as_u64() == other.as_u64()
1336    }
1337}
1338
1339impl Eq for SlotId {}
1340
1341impl Hash for SlotId {
1342    #[inline]
1343    fn hash<H: Hasher>(&self, state: &mut H) {
1344        self.as_u64().hash(state);
1345    }
1346}
1347
1348impl PartialOrd for SlotId {
1349    #[inline]
1350    fn partial_cmp(&self, other: &Self) -> Option<cmp::Ordering> {
1351        Some(self.cmp(other))
1352    }
1353}
1354
1355impl Ord for SlotId {
1356    #[inline]
1357    fn cmp(&self, other: &Self) -> cmp::Ordering {
1358        self.as_u64().cmp(&other.as_u64())
1359    }
1360}
1361
1362#[macro_export]
1363macro_rules! declare_key {
1364    (
1365        $(#[$meta:meta])*
1366        $vis:vis struct $name:ident $(;)?
1367    ) => {
1368        $(#[$meta])*
1369        #[repr(transparent)]
1370        $vis struct $name($crate::SlotId);
1371
1372        impl $crate::Key for $name {
1373            #[inline(always)]
1374            fn from_id(id: $crate::SlotId) -> Self {
1375                $name(id)
1376            }
1377
1378            #[inline(always)]
1379            fn as_id(self) -> $crate::SlotId {
1380                self.0
1381            }
1382        }
1383    };
1384}
1385
1386pub struct Iter<'a, K, V> {
1387    slots: iter::Enumerate<slice::Iter<'a, Slot<V>>>,
1388    marker: PhantomData<fn(K) -> K>,
1389}
1390
1391impl<K, V: fmt::Debug> fmt::Debug for Iter<'_, K, V> {
1392    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1393        f.debug_struct("Iter").finish_non_exhaustive()
1394    }
1395}
1396
1397impl<'a, K: Key, V> Iterator for Iter<'a, K, V> {
1398    type Item = (K, &'a V);
1399
1400    #[inline]
1401    fn next(&mut self) -> Option<Self::Item> {
1402        loop {
1403            let (index, slot) = self.slots.next()?;
1404            let generation = slot.generation.load(Acquire);
1405
1406            if is_occupied(generation) {
1407                // Our capacity can never exceed `u32::MAX`.
1408                #[allow(clippy::cast_possible_truncation)]
1409                let index = index as u32;
1410
1411                // SAFETY: We checked that the occupied bit is set.
1412                let id = unsafe { SlotId::new_unchecked(index, generation) };
1413
1414                // SAFETY:
1415                // * The `Acquire` ordering when loading the slot's generation synchronizes with the
1416                //   `Release` ordering in `SlotMap::insert`, making sure that the newly written
1417                //   value is visible here.
1418                // * We checked that the slot is occupied, which means that it must have been
1419                //   initialized in `SlotMap::insert[_mut]`.
1420                let r = unsafe { slot.value_unchecked() };
1421
1422                break Some((K::from_id(id), r));
1423            }
1424        }
1425    }
1426
1427    #[inline]
1428    fn size_hint(&self) -> (usize, Option<usize>) {
1429        (0, Some(self.slots.len()))
1430    }
1431}
1432
1433impl<K: Key, V> DoubleEndedIterator for Iter<'_, K, V> {
1434    #[inline]
1435    fn next_back(&mut self) -> Option<Self::Item> {
1436        loop {
1437            let (index, slot) = self.slots.next_back()?;
1438            let generation = slot.generation.load(Acquire);
1439
1440            if is_occupied(generation) {
1441                // Our capacity can never exceed `u32::MAX`.
1442                #[allow(clippy::cast_possible_truncation)]
1443                let index = index as u32;
1444
1445                // SAFETY: We checked that the occupied bit is set.
1446                let id = unsafe { SlotId::new_unchecked(index, generation) };
1447
1448                // SAFETY:
1449                // * The `Acquire` ordering when loading the slot's generation synchronizes with the
1450                //   `Release` ordering in `SlotMap::insert`, making sure that the newly written
1451                //   value is visible here.
1452                // * We checked that the slot is occupied, which means that it must have been
1453                //   initialized in `SlotMap::insert[_mut]`.
1454                let r = unsafe { slot.value_unchecked() };
1455
1456                break Some((K::from_id(id), r));
1457            }
1458        }
1459    }
1460}
1461
1462impl<K: Key, V> FusedIterator for Iter<'_, K, V> {}
1463
1464pub struct IterMut<'a, K, V> {
1465    slots: iter::Enumerate<slice::IterMut<'a, Slot<V>>>,
1466    marker: PhantomData<fn(K) -> K>,
1467}
1468
1469impl<K, V: fmt::Debug> fmt::Debug for IterMut<'_, K, V> {
1470    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1471        f.debug_struct("IterMut").finish_non_exhaustive()
1472    }
1473}
1474
1475impl<'a, K: Key, V> Iterator for IterMut<'a, K, V> {
1476    type Item = (K, &'a mut V);
1477
1478    #[inline]
1479    fn next(&mut self) -> Option<Self::Item> {
1480        loop {
1481            let (index, slot) = self.slots.next()?;
1482            let generation = *slot.generation.get_mut();
1483
1484            if is_occupied(generation) {
1485                // Our capacity can never exceed `u32::MAX`.
1486                #[allow(clippy::cast_possible_truncation)]
1487                let index = index as u32;
1488
1489                // SAFETY: We checked that the `OCCUPIED_BIT` is set.
1490                let id = unsafe { SlotId::new_unchecked(index, generation) };
1491
1492                // SAFETY: We checked that the slot is occupied, which means that it must have been
1493                // initialized in `SlotMap::insert[_mut]`.
1494                let r = unsafe { slot.value_unchecked_mut() };
1495
1496                break Some((K::from_id(id), r));
1497            }
1498        }
1499    }
1500
1501    #[inline]
1502    fn size_hint(&self) -> (usize, Option<usize>) {
1503        (0, Some(self.slots.len()))
1504    }
1505}
1506
1507impl<K: Key, V> DoubleEndedIterator for IterMut<'_, K, V> {
1508    #[inline]
1509    fn next_back(&mut self) -> Option<Self::Item> {
1510        loop {
1511            let (index, slot) = self.slots.next_back()?;
1512            let generation = *slot.generation.get_mut();
1513
1514            if is_occupied(generation) {
1515                // Our capacity can never exceed `u32::MAX`.
1516                #[allow(clippy::cast_possible_truncation)]
1517                let index = index as u32;
1518
1519                // SAFETY: We checked that the `OCCUPIED_BIT` is set.
1520                let id = unsafe { SlotId::new_unchecked(index, generation) };
1521
1522                // SAFETY: We checked that the slot is occupied, which means that it must have been
1523                // initialized in `SlotMap::insert[_mut]`.
1524                let r = unsafe { slot.value_unchecked_mut() };
1525
1526                break Some((K::from_id(id), r));
1527            }
1528        }
1529    }
1530}
1531
1532impl<K: Key, V> FusedIterator for IterMut<'_, K, V> {}
1533
1534pub struct Slots<'a, V> {
1535    slots: slice::Iter<'a, Slot<V>>,
1536}
1537
1538impl<V: fmt::Debug> fmt::Debug for Slots<'_, V> {
1539    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1540        f.debug_struct("Slots").finish_non_exhaustive()
1541    }
1542}
1543
1544impl<'a, V> Iterator for Slots<'a, V> {
1545    type Item = &'a Slot<V>;
1546
1547    #[inline]
1548    fn next(&mut self) -> Option<Self::Item> {
1549        self.slots.next()
1550    }
1551
1552    #[inline]
1553    fn size_hint(&self) -> (usize, Option<usize>) {
1554        self.slots.size_hint()
1555    }
1556}
1557
1558impl<V> DoubleEndedIterator for Slots<'_, V> {
1559    #[inline]
1560    fn next_back(&mut self) -> Option<Self::Item> {
1561        self.slots.next_back()
1562    }
1563}
1564
1565impl<V> FusedIterator for Slots<'_, V> {}
1566
1567const fn is_occupied(generation: u32) -> bool {
1568    generation & STATE_MASK == OCCUPIED_TAG
1569}
1570
1571const SPIN_LIMIT: u32 = 6;
1572
1573struct Backoff {
1574    step: u32,
1575}
1576
1577impl Backoff {
1578    fn new() -> Self {
1579        Backoff { step: 0 }
1580    }
1581
1582    fn spin(&mut self) {
1583        for _ in 0..1 << self.step {
1584            hint::spin_loop();
1585        }
1586
1587        if self.step <= SPIN_LIMIT {
1588            self.step += 1;
1589        }
1590    }
1591}
1592
1593macro_rules! assert_unsafe_precondition {
1594    ($condition:expr, $message:expr $(,)?) => {
1595        // The nesting is intentional. There is a special path in the compiler for `if false`
1596        // facilitating conditional compilation without `#[cfg]` and the problems that come with it.
1597        if cfg!(debug_assertions) {
1598            if !$condition {
1599                crate::panic_nounwind(concat!("unsafe precondition(s) validated: ", $message));
1600            }
1601        }
1602    };
1603}
1604use assert_unsafe_precondition;
1605
1606/// Polyfill for `core::panicking::panic_nounwind`.
1607#[cold]
1608#[inline(never)]
1609fn panic_nounwind(message: &'static str) -> ! {
1610    struct UnwindGuard;
1611
1612    impl Drop for UnwindGuard {
1613        fn drop(&mut self) {
1614            panic!();
1615        }
1616    }
1617
1618    let _guard = UnwindGuard;
1619    std::panic::panic_any(message);
1620}
1621
1622#[cfg(test)]
1623mod tests {
1624    use super::*;
1625    use std::thread;
1626
1627    #[test]
1628    fn basic_usage1() {
1629        let map = SlotMap::new(10);
1630        let guard = &map.pin();
1631
1632        let x = map.insert(69, guard);
1633        let y = map.insert(42, guard);
1634
1635        assert_eq!(map.get(x, guard), Some(&69));
1636        assert_eq!(map.get(y, guard), Some(&42));
1637
1638        map.remove(x, guard);
1639
1640        let x2 = map.insert(12, guard);
1641
1642        assert_eq!(map.get(x2, guard), Some(&12));
1643        assert_eq!(map.get(x, guard), None);
1644
1645        map.remove(y, guard);
1646        map.remove(x2, guard);
1647
1648        assert_eq!(map.get(y, guard), None);
1649        assert_eq!(map.get(x2, guard), None);
1650    }
1651
1652    #[test]
1653    fn basic_usage2() {
1654        let map = SlotMap::new(10);
1655        let guard = &map.pin();
1656
1657        let x = map.insert(1, guard);
1658        let y = map.insert(2, guard);
1659        let z = map.insert(3, guard);
1660
1661        assert_eq!(map.get(x, guard), Some(&1));
1662        assert_eq!(map.get(y, guard), Some(&2));
1663        assert_eq!(map.get(z, guard), Some(&3));
1664
1665        map.remove(y, guard);
1666
1667        let y2 = map.insert(20, guard);
1668
1669        assert_eq!(map.get(y2, guard), Some(&20));
1670        assert_eq!(map.get(y, guard), None);
1671
1672        map.remove(x, guard);
1673        map.remove(z, guard);
1674
1675        let x2 = map.insert(10, guard);
1676
1677        assert_eq!(map.get(x2, guard), Some(&10));
1678        assert_eq!(map.get(x, guard), None);
1679
1680        let z2 = map.insert(30, guard);
1681
1682        assert_eq!(map.get(z2, guard), Some(&30));
1683        assert_eq!(map.get(x, guard), None);
1684
1685        map.remove(x2, guard);
1686
1687        assert_eq!(map.get(x2, guard), None);
1688
1689        map.remove(y2, guard);
1690        map.remove(z2, guard);
1691
1692        assert_eq!(map.get(y2, guard), None);
1693        assert_eq!(map.get(z2, guard), None);
1694    }
1695
1696    #[test]
1697    fn basic_usage3() {
1698        let map = SlotMap::new(10);
1699        let guard = &map.pin();
1700
1701        let x = map.insert(1, guard);
1702        let y = map.insert(2, guard);
1703
1704        assert_eq!(map.get(x, guard), Some(&1));
1705        assert_eq!(map.get(y, guard), Some(&2));
1706
1707        let z = map.insert(3, guard);
1708
1709        assert_eq!(map.get(z, guard), Some(&3));
1710
1711        map.remove(x, guard);
1712        map.remove(z, guard);
1713
1714        let z2 = map.insert(30, guard);
1715        let x2 = map.insert(10, guard);
1716
1717        assert_eq!(map.get(x2, guard), Some(&10));
1718        assert_eq!(map.get(z2, guard), Some(&30));
1719        assert_eq!(map.get(x, guard), None);
1720        assert_eq!(map.get(z, guard), None);
1721
1722        map.remove(x2, guard);
1723        map.remove(y, guard);
1724        map.remove(z2, guard);
1725
1726        assert_eq!(map.get(x2, guard), None);
1727        assert_eq!(map.get(y, guard), None);
1728        assert_eq!(map.get(z2, guard), None);
1729    }
1730
1731    #[test]
1732    fn basic_usage_invalidated1() {
1733        let map = SlotMap::new(10);
1734        let guard = &map.pin();
1735
1736        let x = map.insert(69, guard);
1737        let y = map.insert(42, guard);
1738
1739        assert_eq!(map.get(x, guard), Some(&69));
1740        assert_eq!(map.get(y, guard), Some(&42));
1741
1742        map.invalidate(x, guard);
1743        map.remove_invalidated(x);
1744
1745        let x2 = map.insert(12, guard);
1746
1747        assert_eq!(map.get(x2, guard), Some(&12));
1748        assert_eq!(map.get(x, guard), None);
1749
1750        map.invalidate(y, guard);
1751        map.invalidate(x2, guard);
1752
1753        assert_eq!(map.get(y, guard), None);
1754        assert_eq!(map.get(x2, guard), None);
1755
1756        map.remove_invalidated(y);
1757        map.remove_invalidated(x2);
1758
1759        assert_eq!(map.get(y, guard), None);
1760        assert_eq!(map.get(x2, guard), None);
1761    }
1762
1763    #[test]
1764    fn basic_usage_invalidated2() {
1765        let map = SlotMap::new(10);
1766        let guard = &map.pin();
1767
1768        let x = map.insert(1, guard);
1769        let y = map.insert(2, guard);
1770        let z = map.insert(3, guard);
1771
1772        assert_eq!(map.get(x, guard), Some(&1));
1773        assert_eq!(map.get(y, guard), Some(&2));
1774        assert_eq!(map.get(z, guard), Some(&3));
1775
1776        map.invalidate(y, guard);
1777        map.remove_invalidated(y);
1778
1779        let y2 = map.insert(20, guard);
1780
1781        assert_eq!(map.get(y2, guard), Some(&20));
1782        assert_eq!(map.get(y, guard), None);
1783
1784        map.invalidate(x, guard);
1785        map.invalidate(z, guard);
1786        map.remove_invalidated(x);
1787        map.remove_invalidated(z);
1788
1789        let x2 = map.insert(10, guard);
1790
1791        assert_eq!(map.get(x2, guard), Some(&10));
1792        assert_eq!(map.get(x, guard), None);
1793
1794        let z2 = map.insert(30, guard);
1795
1796        assert_eq!(map.get(z2, guard), Some(&30));
1797        assert_eq!(map.get(x, guard), None);
1798
1799        map.invalidate(x2, guard);
1800
1801        assert_eq!(map.get(x2, guard), None);
1802
1803        map.remove_invalidated(x2);
1804
1805        assert_eq!(map.get(x2, guard), None);
1806
1807        map.invalidate(y2, guard);
1808        map.invalidate(z2, guard);
1809
1810        assert_eq!(map.get(y2, guard), None);
1811        assert_eq!(map.get(z2, guard), None);
1812
1813        map.remove_invalidated(y2);
1814        map.remove_invalidated(z2);
1815
1816        assert_eq!(map.get(y2, guard), None);
1817        assert_eq!(map.get(z2, guard), None);
1818    }
1819
1820    #[test]
1821    fn basic_usage_invalidated3() {
1822        let map = SlotMap::new(10);
1823        let guard = &map.pin();
1824
1825        let x = map.insert(1, guard);
1826        let y = map.insert(2, guard);
1827
1828        assert_eq!(map.get(x, guard), Some(&1));
1829        assert_eq!(map.get(y, guard), Some(&2));
1830
1831        let z = map.insert(3, guard);
1832
1833        assert_eq!(map.get(z, guard), Some(&3));
1834
1835        map.invalidate(x, guard);
1836        map.invalidate(z, guard);
1837        map.remove_invalidated(x);
1838        map.remove_invalidated(z);
1839
1840        let z2 = map.insert(30, guard);
1841        let x2 = map.insert(10, guard);
1842
1843        assert_eq!(map.get(x2, guard), Some(&10));
1844        assert_eq!(map.get(z2, guard), Some(&30));
1845        assert_eq!(map.get(x, guard), None);
1846        assert_eq!(map.get(z, guard), None);
1847
1848        map.invalidate(x2, guard);
1849        map.invalidate(y, guard);
1850        map.invalidate(z2, guard);
1851
1852        assert_eq!(map.get(x2, guard), None);
1853        assert_eq!(map.get(y, guard), None);
1854        assert_eq!(map.get(z2, guard), None);
1855
1856        map.remove_invalidated(x2);
1857        map.remove_invalidated(y);
1858        map.remove_invalidated(z2);
1859
1860        assert_eq!(map.get(x2, guard), None);
1861        assert_eq!(map.get(y, guard), None);
1862        assert_eq!(map.get(z2, guard), None);
1863    }
1864
1865    #[test]
1866    fn basic_usage_mut1() {
1867        let mut map = SlotMap::new(10);
1868
1869        let x = map.insert_mut(69);
1870        let y = map.insert_mut(42);
1871
1872        assert_eq!(map.get_mut(x), Some(&mut 69));
1873        assert_eq!(map.get_mut(y), Some(&mut 42));
1874
1875        map.remove_mut(x);
1876
1877        let x2 = map.insert_mut(12);
1878
1879        assert_eq!(map.get_mut(x2), Some(&mut 12));
1880        assert_eq!(map.get_mut(x), None);
1881
1882        map.remove_mut(y);
1883        map.remove_mut(x2);
1884
1885        assert_eq!(map.get_mut(y), None);
1886        assert_eq!(map.get_mut(x2), None);
1887    }
1888
1889    #[test]
1890    fn basic_usage_mut2() {
1891        let mut map = SlotMap::new(10);
1892
1893        let x = map.insert_mut(1);
1894        let y = map.insert_mut(2);
1895        let z = map.insert_mut(3);
1896
1897        assert_eq!(map.get_mut(x), Some(&mut 1));
1898        assert_eq!(map.get_mut(y), Some(&mut 2));
1899        assert_eq!(map.get_mut(z), Some(&mut 3));
1900
1901        map.remove_mut(y);
1902
1903        let y2 = map.insert_mut(20);
1904
1905        assert_eq!(map.get_mut(y2), Some(&mut 20));
1906        assert_eq!(map.get_mut(y), None);
1907
1908        map.remove_mut(x);
1909        map.remove_mut(z);
1910
1911        let x2 = map.insert_mut(10);
1912
1913        assert_eq!(map.get_mut(x2), Some(&mut 10));
1914        assert_eq!(map.get_mut(x), None);
1915
1916        let z2 = map.insert_mut(30);
1917
1918        assert_eq!(map.get_mut(z2), Some(&mut 30));
1919        assert_eq!(map.get_mut(x), None);
1920
1921        map.remove_mut(x2);
1922
1923        assert_eq!(map.get_mut(x2), None);
1924
1925        map.remove_mut(y2);
1926        map.remove_mut(z2);
1927
1928        assert_eq!(map.get_mut(y2), None);
1929        assert_eq!(map.get_mut(z2), None);
1930    }
1931
1932    #[test]
1933    fn basic_usage_mut3() {
1934        let mut map = SlotMap::new(10);
1935
1936        let x = map.insert_mut(1);
1937        let y = map.insert_mut(2);
1938
1939        assert_eq!(map.get_mut(x), Some(&mut 1));
1940        assert_eq!(map.get_mut(y), Some(&mut 2));
1941
1942        let z = map.insert_mut(3);
1943
1944        assert_eq!(map.get_mut(z), Some(&mut 3));
1945
1946        map.remove_mut(x);
1947        map.remove_mut(z);
1948
1949        let z2 = map.insert_mut(30);
1950        let x2 = map.insert_mut(10);
1951
1952        assert_eq!(map.get_mut(x2), Some(&mut 10));
1953        assert_eq!(map.get_mut(z2), Some(&mut 30));
1954        assert_eq!(map.get_mut(x), None);
1955        assert_eq!(map.get_mut(z), None);
1956
1957        map.remove_mut(x2);
1958        map.remove_mut(y);
1959        map.remove_mut(z2);
1960
1961        assert_eq!(map.get_mut(x2), None);
1962        assert_eq!(map.get_mut(y), None);
1963        assert_eq!(map.get_mut(z2), None);
1964    }
1965
1966    #[test]
1967    fn iter1() {
1968        let map = SlotMap::new(10);
1969        let guard = &map.pin();
1970
1971        let x = map.insert(1, guard);
1972        let _ = map.insert(2, guard);
1973        let y = map.insert(3, guard);
1974
1975        let mut iter = map.iter(guard);
1976
1977        assert_eq!(*iter.next().unwrap().1, 1);
1978        assert_eq!(*iter.next().unwrap().1, 2);
1979        assert_eq!(*iter.next().unwrap().1, 3);
1980        assert!(iter.next().is_none());
1981
1982        map.remove(x, guard);
1983        map.remove(y, guard);
1984
1985        let mut iter = map.iter(guard);
1986
1987        assert_eq!(*iter.next().unwrap().1, 2);
1988        assert!(iter.next().is_none());
1989
1990        map.insert(3, guard);
1991        map.insert(1, guard);
1992
1993        let mut iter = map.iter(guard);
1994
1995        assert_eq!(*iter.next().unwrap().1, 2);
1996        assert_eq!(*iter.next().unwrap().1, 3);
1997        assert_eq!(*iter.next().unwrap().1, 1);
1998        assert!(iter.next().is_none());
1999    }
2000
2001    #[test]
2002    fn iter2() {
2003        let map = SlotMap::new(10);
2004        let guard = &map.pin();
2005
2006        let x = map.insert(1, guard);
2007        let y = map.insert(2, guard);
2008        let z = map.insert(3, guard);
2009
2010        map.remove(x, guard);
2011
2012        let mut iter = map.iter(guard);
2013
2014        assert_eq!(*iter.next().unwrap().1, 2);
2015        assert_eq!(*iter.next().unwrap().1, 3);
2016        assert!(iter.next().is_none());
2017
2018        map.remove(y, guard);
2019
2020        let mut iter = map.iter(guard);
2021
2022        assert_eq!(*iter.next().unwrap().1, 3);
2023        assert!(iter.next().is_none());
2024
2025        map.remove(z, guard);
2026
2027        let mut iter = map.iter(guard);
2028
2029        assert!(iter.next().is_none());
2030    }
2031
2032    #[test]
2033    fn iter3() {
2034        let map = SlotMap::new(10);
2035        let guard = &map.pin();
2036
2037        let _ = map.insert(1, guard);
2038        let x = map.insert(2, guard);
2039
2040        let mut iter = map.iter(guard);
2041
2042        assert_eq!(*iter.next().unwrap().1, 1);
2043        assert_eq!(*iter.next().unwrap().1, 2);
2044        assert!(iter.next().is_none());
2045
2046        map.remove(x, guard);
2047
2048        let x = map.insert(2, guard);
2049        let _ = map.insert(3, guard);
2050        let y = map.insert(4, guard);
2051
2052        map.remove(y, guard);
2053
2054        let mut iter = map.iter(guard);
2055
2056        assert_eq!(*iter.next().unwrap().1, 1);
2057        assert_eq!(*iter.next().unwrap().1, 2);
2058        assert_eq!(*iter.next().unwrap().1, 3);
2059        assert!(iter.next().is_none());
2060
2061        map.remove(x, guard);
2062
2063        let mut iter = map.iter(guard);
2064
2065        assert_eq!(*iter.next().unwrap().1, 1);
2066        assert_eq!(*iter.next().unwrap().1, 3);
2067        assert!(iter.next().is_none());
2068    }
2069
2070    #[test]
2071    fn iter_mut1() {
2072        let mut map = SlotMap::new(10);
2073
2074        let x = map.insert_mut(1);
2075        let _ = map.insert_mut(2);
2076        let y = map.insert_mut(3);
2077
2078        let mut iter = map.iter_mut();
2079
2080        assert_eq!(*iter.next().unwrap().1, 1);
2081        assert_eq!(*iter.next().unwrap().1, 2);
2082        assert_eq!(*iter.next().unwrap().1, 3);
2083        assert!(iter.next().is_none());
2084
2085        map.remove_mut(x);
2086        map.remove_mut(y);
2087
2088        let mut iter = map.iter_mut();
2089
2090        assert_eq!(*iter.next().unwrap().1, 2);
2091        assert!(iter.next().is_none());
2092
2093        map.insert_mut(3);
2094        map.insert_mut(1);
2095
2096        let mut iter = map.iter_mut();
2097
2098        assert_eq!(*iter.next().unwrap().1, 1);
2099        assert_eq!(*iter.next().unwrap().1, 2);
2100        assert_eq!(*iter.next().unwrap().1, 3);
2101        assert!(iter.next().is_none());
2102    }
2103
2104    #[test]
2105    fn iter_mut2() {
2106        let mut map = SlotMap::new(10);
2107
2108        let x = map.insert_mut(1);
2109        let y = map.insert_mut(2);
2110        let z = map.insert_mut(3);
2111
2112        map.remove_mut(x);
2113
2114        let mut iter = map.iter_mut();
2115
2116        assert_eq!(*iter.next().unwrap().1, 2);
2117        assert_eq!(*iter.next().unwrap().1, 3);
2118        assert!(iter.next().is_none());
2119
2120        map.remove_mut(y);
2121
2122        let mut iter = map.iter_mut();
2123
2124        assert_eq!(*iter.next().unwrap().1, 3);
2125        assert!(iter.next().is_none());
2126
2127        map.remove_mut(z);
2128
2129        let mut iter = map.iter_mut();
2130
2131        assert!(iter.next().is_none());
2132    }
2133
2134    #[test]
2135    fn iter_mut3() {
2136        let mut map = SlotMap::new(10);
2137
2138        let _ = map.insert_mut(1);
2139        let x = map.insert_mut(2);
2140
2141        let mut iter = map.iter_mut();
2142
2143        assert_eq!(*iter.next().unwrap().1, 1);
2144        assert_eq!(*iter.next().unwrap().1, 2);
2145        assert!(iter.next().is_none());
2146
2147        map.remove_mut(x);
2148
2149        let x = map.insert_mut(2);
2150        let _ = map.insert_mut(3);
2151        let y = map.insert_mut(4);
2152
2153        map.remove_mut(y);
2154
2155        let mut iter = map.iter_mut();
2156
2157        assert_eq!(*iter.next().unwrap().1, 1);
2158        assert_eq!(*iter.next().unwrap().1, 2);
2159        assert_eq!(*iter.next().unwrap().1, 3);
2160        assert!(iter.next().is_none());
2161
2162        map.remove_mut(x);
2163
2164        let mut iter = map.iter_mut();
2165
2166        assert_eq!(*iter.next().unwrap().1, 1);
2167        assert_eq!(*iter.next().unwrap().1, 3);
2168        assert!(iter.next().is_none());
2169    }
2170
2171    #[test]
2172    fn reusing_slots1() {
2173        let map = SlotMap::new(10);
2174
2175        let x = map.insert(0, &map.pin());
2176        let y = map.insert(0, &map.pin());
2177
2178        map.remove(y, &map.pin());
2179        map.pin().flush();
2180
2181        let y2 = map.insert(0, &map.pin());
2182        assert_eq!(y2.index, y.index);
2183        assert_ne!(y2.generation, y.generation);
2184
2185        map.remove(x, &map.pin());
2186        map.pin().flush();
2187
2188        let x2 = map.insert(0, &map.pin());
2189        assert_eq!(x2.index, x.index);
2190        assert_ne!(x2.generation, x.generation);
2191
2192        map.remove(y2, &map.pin());
2193        map.remove(x2, &map.pin());
2194    }
2195
2196    #[test]
2197    fn reusing_slots2() {
2198        let map = SlotMap::new(10);
2199
2200        let x = map.insert(0, &map.pin());
2201
2202        map.remove(x, &map.pin());
2203        map.pin().flush();
2204
2205        let x2 = map.insert(0, &map.pin());
2206        assert_eq!(x.index, x2.index);
2207        assert_ne!(x.generation, x2.generation);
2208
2209        let y = map.insert(0, &map.pin());
2210        let z = map.insert(0, &map.pin());
2211
2212        map.remove(y, &map.pin());
2213        map.remove(x2, &map.pin());
2214        map.pin().flush();
2215
2216        let x3 = map.insert(0, &map.pin());
2217        let y2 = map.insert(0, &map.pin());
2218        assert_eq!(x3.index, x2.index);
2219        assert_ne!(x3.generation, x2.generation);
2220        assert_eq!(y2.index, y.index);
2221        assert_ne!(y2.generation, y.generation);
2222
2223        map.remove(x3, &map.pin());
2224        map.remove(y2, &map.pin());
2225        map.remove(z, &map.pin());
2226    }
2227
2228    #[test]
2229    fn reusing_slots3() {
2230        let map = SlotMap::new(10);
2231
2232        let x = map.insert(0, &map.pin());
2233        let y = map.insert(0, &map.pin());
2234
2235        map.remove(x, &map.pin());
2236        map.remove(y, &map.pin());
2237        map.pin().flush();
2238
2239        let y2 = map.insert(0, &map.pin());
2240        let x2 = map.insert(0, &map.pin());
2241        let z = map.insert(0, &map.pin());
2242        assert_eq!(x2.index, x.index);
2243        assert_ne!(x2.generation, x.generation);
2244        assert_eq!(y2.index, y.index);
2245        assert_ne!(y2.generation, y.generation);
2246
2247        map.remove(x2, &map.pin());
2248        map.remove(z, &map.pin());
2249        map.remove(y2, &map.pin());
2250        map.pin().flush();
2251
2252        let y3 = map.insert(0, &map.pin());
2253        let z2 = map.insert(0, &map.pin());
2254        let x3 = map.insert(0, &map.pin());
2255        assert_eq!(y3.index, y2.index);
2256        assert_ne!(y3.generation, y2.generation);
2257        assert_eq!(z2.index, z.index);
2258        assert_ne!(z2.generation, z.generation);
2259        assert_eq!(x3.index, x2.index);
2260        assert_ne!(x3.generation, x2.generation);
2261
2262        map.remove(x3, &map.pin());
2263        map.remove(y3, &map.pin());
2264        map.remove(z2, &map.pin());
2265    }
2266
2267    #[test]
2268    fn reusing_slots_invalidated1() {
2269        let map = SlotMap::new(10);
2270
2271        let x = map.insert(0, &map.pin());
2272        let y = map.insert(0, &map.pin());
2273
2274        map.invalidate(y, &map.pin());
2275        map.remove_invalidated(y);
2276        map.pin().flush();
2277
2278        let y2 = map.insert(0, &map.pin());
2279        assert_eq!(y2.index, y.index);
2280        assert_ne!(y2.generation, y.generation);
2281
2282        map.invalidate(x, &map.pin());
2283        map.remove_invalidated(x);
2284        map.pin().flush();
2285
2286        let x2 = map.insert(0, &map.pin());
2287        assert_eq!(x2.index, x.index);
2288        assert_ne!(x2.generation, x.generation);
2289
2290        map.invalidate(y2, &map.pin());
2291        map.invalidate(x2, &map.pin());
2292        map.remove_invalidated(y2);
2293        map.remove_invalidated(x2);
2294    }
2295
2296    #[test]
2297    fn reusing_slots_invalidated2() {
2298        let map = SlotMap::new(10);
2299
2300        let x = map.insert(0, &map.pin());
2301
2302        map.invalidate(x, &map.pin());
2303        map.remove_invalidated(x);
2304        map.pin().flush();
2305
2306        let x2 = map.insert(0, &map.pin());
2307        assert_eq!(x.index, x2.index);
2308        assert_ne!(x.generation, x2.generation);
2309
2310        let y = map.insert(0, &map.pin());
2311        let z = map.insert(0, &map.pin());
2312
2313        map.invalidate(y, &map.pin());
2314        map.invalidate(x2, &map.pin());
2315        map.remove_invalidated(y);
2316        map.remove_invalidated(x2);
2317        map.pin().flush();
2318
2319        let x3 = map.insert(0, &map.pin());
2320        let y2 = map.insert(0, &map.pin());
2321        assert_eq!(x3.index, x2.index);
2322        assert_ne!(x3.generation, x2.generation);
2323        assert_eq!(y2.index, y.index);
2324        assert_ne!(y2.generation, y.generation);
2325
2326        map.invalidate(x3, &map.pin());
2327        map.invalidate(y2, &map.pin());
2328        map.invalidate(z, &map.pin());
2329        map.remove_invalidated(x3);
2330        map.remove_invalidated(y2);
2331        map.remove_invalidated(z);
2332    }
2333
2334    #[test]
2335    fn reusing_slots_invalidated3() {
2336        let map = SlotMap::new(10);
2337
2338        let x = map.insert(0, &map.pin());
2339        let y = map.insert(0, &map.pin());
2340
2341        map.remove(x, &map.pin());
2342        map.remove(y, &map.pin());
2343        map.pin().flush();
2344
2345        let y2 = map.insert(0, &map.pin());
2346        let x2 = map.insert(0, &map.pin());
2347        let z = map.insert(0, &map.pin());
2348        assert_eq!(x2.index, x.index);
2349        assert_ne!(x2.generation, x.generation);
2350        assert_eq!(y2.index, y.index);
2351        assert_ne!(y2.generation, y.generation);
2352
2353        map.remove(x2, &map.pin());
2354        map.remove(z, &map.pin());
2355        map.remove(y2, &map.pin());
2356        map.pin().flush();
2357
2358        let y3 = map.insert(0, &map.pin());
2359        let z2 = map.insert(0, &map.pin());
2360        let x3 = map.insert(0, &map.pin());
2361        assert_eq!(y3.index, y2.index);
2362        assert_ne!(y3.generation, y2.generation);
2363        assert_eq!(z2.index, z.index);
2364        assert_ne!(z2.generation, z.generation);
2365        assert_eq!(x3.index, x2.index);
2366        assert_ne!(x3.generation, x2.generation);
2367
2368        map.remove(x3, &map.pin());
2369        map.remove(y3, &map.pin());
2370        map.remove(z2, &map.pin());
2371    }
2372
2373    #[test]
2374    fn reusing_slots_mut1() {
2375        let mut map = SlotMap::new(10);
2376
2377        let x = map.insert_mut(0);
2378        let y = map.insert_mut(0);
2379
2380        map.remove_mut(y);
2381
2382        let y2 = map.insert_mut(0);
2383        assert_eq!(y2.index, y.index);
2384        assert_ne!(y2.generation, y.generation);
2385
2386        map.remove_mut(x);
2387
2388        let x2 = map.insert_mut(0);
2389        assert_eq!(x2.index, x.index);
2390        assert_ne!(x2.generation, x.generation);
2391
2392        map.remove_mut(y2);
2393        map.remove_mut(x2);
2394    }
2395
2396    #[test]
2397    fn reusing_slots_mut2() {
2398        let mut map = SlotMap::new(10);
2399
2400        let x = map.insert_mut(0);
2401
2402        map.remove_mut(x);
2403
2404        let x2 = map.insert_mut(0);
2405        assert_eq!(x.index, x2.index);
2406        assert_ne!(x.generation, x2.generation);
2407
2408        let y = map.insert_mut(0);
2409        let z = map.insert_mut(0);
2410
2411        map.remove_mut(y);
2412        map.remove_mut(x2);
2413
2414        let x3 = map.insert_mut(0);
2415        let y2 = map.insert_mut(0);
2416        assert_eq!(x3.index, x2.index);
2417        assert_ne!(x3.generation, x2.generation);
2418        assert_eq!(y2.index, y.index);
2419        assert_ne!(y2.generation, y.generation);
2420
2421        map.remove_mut(x3);
2422        map.remove_mut(y2);
2423        map.remove_mut(z);
2424    }
2425
2426    #[test]
2427    fn reusing_slots_mut3() {
2428        let mut map = SlotMap::new(10);
2429
2430        let x = map.insert_mut(0);
2431        let y = map.insert_mut(0);
2432
2433        map.remove_mut(x);
2434        map.remove_mut(y);
2435
2436        let y2 = map.insert_mut(0);
2437        let x2 = map.insert_mut(0);
2438        let z = map.insert_mut(0);
2439        assert_eq!(x2.index, x.index);
2440        assert_ne!(x2.generation, x.generation);
2441        assert_eq!(y2.index, y.index);
2442        assert_ne!(y2.generation, y.generation);
2443
2444        map.remove_mut(x2);
2445        map.remove_mut(z);
2446        map.remove_mut(y2);
2447
2448        let y3 = map.insert_mut(0);
2449        let z2 = map.insert_mut(0);
2450        let x3 = map.insert_mut(0);
2451        assert_eq!(y3.index, y2.index);
2452        assert_ne!(y3.generation, y2.generation);
2453        assert_eq!(z2.index, z.index);
2454        assert_ne!(z2.generation, z.generation);
2455        assert_eq!(x3.index, x2.index);
2456        assert_ne!(x3.generation, x2.generation);
2457
2458        map.remove_mut(x3);
2459        map.remove_mut(y3);
2460        map.remove_mut(z2);
2461    }
2462
2463    #[test]
2464    fn get_disjoint_mut() {
2465        let mut map = SlotMap::new(3);
2466
2467        let x = map.insert_mut(1);
2468        let y = map.insert_mut(2);
2469        let z = map.insert_mut(3);
2470
2471        assert_eq!(map.get_disjoint_mut([x, y]), Some([&mut 1, &mut 2]));
2472        assert_eq!(map.get_disjoint_mut([y, z]), Some([&mut 2, &mut 3]));
2473        assert_eq!(map.get_disjoint_mut([z, x]), Some([&mut 3, &mut 1]));
2474
2475        assert_eq!(
2476            map.get_disjoint_mut([x, y, z]),
2477            Some([&mut 1, &mut 2, &mut 3]),
2478        );
2479        assert_eq!(
2480            map.get_disjoint_mut([z, y, x]),
2481            Some([&mut 3, &mut 2, &mut 1]),
2482        );
2483
2484        assert_eq!(map.get_disjoint_mut([x, x]), None);
2485        assert_eq!(
2486            map.get_disjoint_mut([x, SlotId::new(3, OCCUPIED_TAG)]),
2487            None,
2488        );
2489
2490        map.remove_mut(y);
2491
2492        assert_eq!(map.get_disjoint_mut([x, z]), Some([&mut 1, &mut 3]));
2493
2494        assert_eq!(map.get_disjoint_mut([y]), None);
2495        assert_eq!(map.get_disjoint_mut([x, y]), None);
2496        assert_eq!(map.get_disjoint_mut([y, z]), None);
2497
2498        let y = map.insert_mut(2);
2499
2500        assert_eq!(
2501            map.get_disjoint_mut([x, y, z]),
2502            Some([&mut 1, &mut 2, &mut 3]),
2503        );
2504
2505        map.remove_mut(x);
2506        map.remove_mut(z);
2507
2508        assert_eq!(map.get_disjoint_mut([y]), Some([&mut 2]));
2509
2510        assert_eq!(map.get_disjoint_mut([x]), None);
2511        assert_eq!(map.get_disjoint_mut([z]), None);
2512
2513        map.remove_mut(y);
2514
2515        assert_eq!(map.get_disjoint_mut([]), Some([]));
2516    }
2517
2518    #[test]
2519    fn tagged() {
2520        let map = SlotMap::new(1);
2521        let guard = &map.pin();
2522
2523        let x = map.insert_with_tag(42, 1, guard);
2524        assert_eq!(x.generation() & TAG_MASK, 1);
2525        assert_eq!(map.get(x, guard), Some(&42));
2526    }
2527
2528    #[test]
2529    fn tagged_mut() {
2530        let mut map = SlotMap::new(1);
2531
2532        let x = map.insert_with_tag_mut(42, 1);
2533        assert_eq!(x.generation() & TAG_MASK, 1);
2534        assert_eq!(map.get_mut(x), Some(&mut 42));
2535    }
2536
2537    #[test]
2538    fn remove_unchecked() {
2539        let map = SlotMap::new(1);
2540
2541        let x = map.insert(69, &map.pin());
2542
2543        // SAFETY: `x` refers to an occupied slot.
2544        assert_eq!(unsafe { map.remove_unchecked(x, &map.pin()) }, &69);
2545
2546        assert_eq!(map.get(x, &map.pin()), None);
2547    }
2548
2549    #[test]
2550    fn invalidate() {
2551        let map = SlotMap::new(1);
2552
2553        let x = map.insert(69, &map.pin());
2554
2555        assert_eq!(map.invalidate(x, &map.pin()), Some(&69));
2556        assert_eq!(map.invalidate(x, &map.pin()), None);
2557        assert_eq!(map.get(x, &map.pin()), None);
2558        assert_eq!(map.remove(x, &map.pin()), None);
2559        assert_eq!(map.remove_invalidated(x), Some(()));
2560        assert_eq!(map.remove_invalidated(x), None);
2561        assert_eq!(map.get(x, &map.pin()), None);
2562        assert_eq!(map.remove(x, &map.pin()), None);
2563
2564        map.pin().flush();
2565
2566        let guard = &map.pin();
2567        let y = map.insert(42, guard);
2568
2569        assert_eq!(map.invalidate(y, guard), Some(&42));
2570        assert_eq!(map.invalidate(y, guard), None);
2571        assert_eq!(map.get(y, guard), None);
2572        assert_eq!(map.remove(y, guard), None);
2573        assert_eq!(map.remove_invalidated(y), Some(()));
2574        assert_eq!(map.remove_invalidated(y), None);
2575        assert_eq!(map.get(y, guard), None);
2576        assert_eq!(map.remove(y, guard), None);
2577    }
2578
2579    #[test]
2580    fn remove_invalidated_unchecked() {
2581        let map = SlotMap::new(1);
2582
2583        let x = map.insert(69, &map.pin());
2584
2585        assert_eq!(map.invalidate(x, &map.pin()), Some(&69));
2586
2587        // SAFETY: `x` refers to an invalidated slot.
2588        unsafe { map.remove_invalidated_unchecked(x) };
2589
2590        assert_eq!(map.get(x, &map.pin()), None);
2591    }
2592
2593    #[test]
2594    fn revive_or_insert() {
2595        let mut map = SlotMap::new(1);
2596
2597        let x = map.insert(MaybeUninit::new(Box::new(69)), &map.pin());
2598        map.remove(x, &map.pin());
2599        map.pin().flush();
2600
2601        let guard = map.pin();
2602        let (y, value) = map.revive_or_insert_with(&guard, |_| MaybeUninit::new(Box::new(42)));
2603
2604        assert_eq!(y, SlotId::new(x.index, x.generation() + ONE_GENERATION));
2605
2606        assert_eq!(
2607            // SAFETY: The value is initialized.
2608            unsafe { value.assume_init_ref() },
2609            &Box::new(69),
2610        );
2611
2612        drop(guard);
2613
2614        // SAFETY: The value is initialized.
2615        unsafe { MaybeUninit::assume_init(map.remove_mut(y).unwrap()) };
2616    }
2617
2618    #[test]
2619    fn header_shards() {
2620        let map = SlotMap::<_, i32>::new(0);
2621
2622        thread::scope(|s| {
2623            let map = &map;
2624            let shard_count = SHARD_COUNT.load(Relaxed);
2625
2626            for _ in 0..shard_count {
2627                s.spawn(move || {
2628                    assert_eq!(map.inner.header().shards().count(), shard_count);
2629                });
2630            }
2631        });
2632    }
2633
2634    // TODO: Testing concurrent generational collections is the most massive pain in the ass. We
2635    // aren't testing the actual implementations but rather ones that don't take the generation into
2636    // account because of that.
2637
2638    const ITERATIONS: u32 = if cfg!(miri) { 1_000 } else { 1_000_000 };
2639
2640    #[test]
2641    fn multi_threaded1() {
2642        const THREADS: u32 = 2;
2643
2644        let map = SlotMap::new(ITERATIONS);
2645
2646        thread::scope(|s| {
2647            let inserter = || {
2648                for _ in 0..ITERATIONS / THREADS {
2649                    map.insert(0, &map.pin());
2650                }
2651            };
2652
2653            for _ in 0..THREADS {
2654                s.spawn(inserter);
2655            }
2656        });
2657
2658        thread::scope(|s| {
2659            let remover = || {
2660                for index in 0..ITERATIONS {
2661                    let _ = map.remove(SlotId::new(index, OCCUPIED_TAG), &map.pin());
2662                }
2663            };
2664
2665            for _ in 0..THREADS {
2666                s.spawn(remover);
2667            }
2668        });
2669
2670        assert_eq!(map.len(), 0);
2671    }
2672
2673    #[test]
2674    fn multi_threaded2() {
2675        const CAPACITY: u32 = 8_000;
2676
2677        let map = SlotMap::new(CAPACITY);
2678
2679        thread::scope(|s| {
2680            let insert_remover = || {
2681                for _ in 0..ITERATIONS / 6 {
2682                    let x = map.insert(0, &map.pin());
2683                    let y = map.insert(0, &map.pin());
2684                    map.remove(y, &map.pin());
2685                    let z = map.insert(0, &map.pin());
2686                    map.remove(x, &map.pin());
2687                    map.remove(z, &map.pin());
2688                }
2689            };
2690            let iterator = || {
2691                for _ in 0..ITERATIONS / CAPACITY * 2 {
2692                    for index in 0..CAPACITY {
2693                        if let Some(value) = map.index(index, &map.pin()) {
2694                            let _ = *value;
2695                        }
2696                    }
2697                }
2698            };
2699
2700            s.spawn(iterator);
2701            s.spawn(iterator);
2702            s.spawn(iterator);
2703            s.spawn(insert_remover);
2704        });
2705    }
2706
2707    #[test]
2708    fn multi_threaded3() {
2709        let map = SlotMap::new(ITERATIONS / 10);
2710
2711        thread::scope(|s| {
2712            let inserter = || {
2713                for i in 0..ITERATIONS {
2714                    if i % 10 == 0 {
2715                        map.insert(0, &map.pin());
2716                    } else {
2717                        thread::yield_now();
2718                    }
2719                }
2720            };
2721            let remover = || {
2722                for _ in 0..ITERATIONS {
2723                    map.remove_index(0, &map.pin());
2724                }
2725            };
2726            let getter = || {
2727                for _ in 0..ITERATIONS {
2728                    if let Some(value) = map.index(0, &map.pin()) {
2729                        let _ = *value;
2730                    }
2731                }
2732            };
2733
2734            s.spawn(getter);
2735            s.spawn(getter);
2736            s.spawn(getter);
2737            s.spawn(getter);
2738            s.spawn(remover);
2739            s.spawn(remover);
2740            s.spawn(remover);
2741            s.spawn(inserter);
2742        });
2743    }
2744}