slotmapd/
hop.rs

1// Needed because assigning to non-Copy union is unsafe in stable but not in nightly.
2#![allow(unused_unsafe)]
3
4//! Contains the faster iteration, slower insertion/removal slot map
5//! implementation.
6//!
7//! This data structure is essentially the same as a regular [`SlotMap`], but
8//! maintains extra information when inserting/removing elements that allows it
9//! to 'hop over' vacant slots during iteration, making it potentially much
10//! faster for iteration.
11//!
12//! The trade-off is that compared to a regular [`SlotMap`] insertion/removal is
13//! roughly twice as slow. Random indexing has identical performance for both.
14//!
15//! [`SlotMap`]: crate::SlotMap
16
17#[cfg(all(nightly, any(doc, feature = "unstable")))]
18use alloc::collections::TryReserveError;
19use alloc::vec::Vec;
20use core::fmt;
21use core::iter::FusedIterator;
22use core::marker::PhantomData;
23use core::mem::ManuallyDrop;
24#[allow(unused_imports)] // MaybeUninit is only used on nightly at the moment.
25use core::mem::MaybeUninit;
26use core::ops::{Index, IndexMut};
27
28use crate::util::{Never, UnwrapUnchecked};
29use crate::{DefaultKey, Key, KeyData};
30
31// Metadata to maintain the freelist.
32#[derive(Clone, Copy, Debug)]
33#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
34struct FreeListEntry {
35    next: u32,
36    prev: u32,
37    other_end: u32,
38}
39
40// Storage inside a slot or metadata for the freelist when vacant.
41union SlotUnion<T> {
42    value: ManuallyDrop<T>,
43    free: FreeListEntry,
44}
45
46// A slot, which represents storage for a value and a current version.
47// Can be occupied or vacant.
48struct Slot<T> {
49    u: SlotUnion<T>,
50    version: u32, // Even = vacant, odd = occupied.
51}
52
53// Safe API to read a slot.
54enum SlotContent<'a, T: 'a> {
55    Occupied(&'a T),
56    Vacant(&'a FreeListEntry),
57}
58
59enum SlotContentMut<'a, T: 'a> {
60    OccupiedMut(&'a mut T),
61    VacantMut(&'a mut FreeListEntry),
62}
63
64use self::SlotContent::{Occupied, Vacant};
65use self::SlotContentMut::{OccupiedMut, VacantMut};
66
67impl<T> Slot<T> {
68    // Is this slot occupied?
69    #[inline(always)]
70    pub fn occupied(&self) -> bool {
71        self.version % 2 == 1
72    }
73
74    pub fn get(&self) -> SlotContent<T> {
75        unsafe {
76            if self.occupied() {
77                Occupied(&*self.u.value)
78            } else {
79                Vacant(&self.u.free)
80            }
81        }
82    }
83
84    pub fn get_mut(&mut self) -> SlotContentMut<T> {
85        unsafe {
86            if self.occupied() {
87                OccupiedMut(&mut *self.u.value)
88            } else {
89                VacantMut(&mut self.u.free)
90            }
91        }
92    }
93}
94
95impl<T> Drop for Slot<T> {
96    fn drop(&mut self) {
97        if core::mem::needs_drop::<T>() && self.occupied() {
98            // This is safe because we checked that we're occupied.
99            unsafe {
100                ManuallyDrop::drop(&mut self.u.value);
101            }
102        }
103    }
104}
105
106impl<T: Clone> Clone for Slot<T> {
107    fn clone(&self) -> Self {
108        Self {
109            u: match self.get() {
110                Occupied(value) => SlotUnion {
111                    value: ManuallyDrop::new(value.clone()),
112                },
113                Vacant(&free) => SlotUnion { free },
114            },
115            version: self.version,
116        }
117    }
118
119    fn clone_from(&mut self, source: &Self) {
120        match (self.get_mut(), source.get()) {
121            (OccupiedMut(self_val), Occupied(source_val)) => self_val.clone_from(source_val),
122            (VacantMut(self_free), Vacant(&source_free)) => *self_free = source_free,
123            (_, Occupied(value)) => {
124                self.u = SlotUnion {
125                    value: ManuallyDrop::new(value.clone()),
126                }
127            },
128            (_, Vacant(&free)) => self.u = SlotUnion { free },
129        }
130        self.version = source.version;
131    }
132}
133
134impl<T: fmt::Debug> fmt::Debug for Slot<T> {
135    fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
136        let mut builder = fmt.debug_struct("Slot");
137        builder.field("version", &self.version);
138        match self.get() {
139            Occupied(value) => builder.field("value", value).finish(),
140            Vacant(free) => builder.field("free", free).finish(),
141        }
142    }
143}
144
145/// Hop slot map, storage with stable unique keys.
146///
147/// See [crate documentation](crate) for more details.
148#[derive(Debug)]
149pub struct HopSlotMap<K: Key, V> {
150    slots: Vec<Slot<V>>,
151    num_elems: u32,
152    _k: PhantomData<fn(K) -> K>,
153}
154
155impl<V> HopSlotMap<DefaultKey, V> {
156    /// Constructs a new, empty [`HopSlotMap`].
157    ///
158    /// # Examples
159    ///
160    /// ```
161    /// # use slotmapd::*;
162    /// let mut sm: HopSlotMap<_, i32> = HopSlotMap::new();
163    /// ```
164    pub fn new() -> Self {
165        Self::with_capacity_and_key(0)
166    }
167
168    /// Creates an empty [`HopSlotMap`] with the given capacity.
169    ///
170    /// The slot map will not reallocate until it holds at least `capacity`
171    /// elements.
172    ///
173    /// # Examples
174    ///
175    /// ```
176    /// # use slotmapd::*;
177    /// let mut sm: HopSlotMap<_, i32> = HopSlotMap::with_capacity(10);
178    /// ```
179    pub fn with_capacity(capacity: usize) -> Self {
180        Self::with_capacity_and_key(capacity)
181    }
182}
183
184impl<K: Key, V> HopSlotMap<K, V> {
185    /// Constructs a new, empty [`HopSlotMap`] with a custom key type.
186    ///
187    /// # Examples
188    ///
189    /// ```
190    /// # use slotmapd::*;
191    /// new_key_type! {
192    ///     struct PositionKey;
193    /// }
194    /// let mut positions: HopSlotMap<PositionKey, i32> = HopSlotMap::with_key();
195    /// ```
196    pub fn with_key() -> Self {
197        Self::with_capacity_and_key(0)
198    }
199
200    /// Creates an empty [`HopSlotMap`] with the given capacity and a custom key
201    /// type.
202    ///
203    /// The slot map will not reallocate until it holds at least `capacity`
204    /// elements.
205    ///
206    /// # Examples
207    ///
208    /// ```
209    /// # use slotmapd::*;
210    /// new_key_type! {
211    ///     struct MessageKey;
212    /// }
213    /// let mut messages = HopSlotMap::with_capacity_and_key(3);
214    /// let welcome: MessageKey = messages.insert("Welcome");
215    /// let good_day = messages.insert("Good day");
216    /// let hello = messages.insert("Hello");
217    /// ```
218    pub fn with_capacity_and_key(capacity: usize) -> Self {
219        // Create slots with sentinel at index 0.
220        let mut slots = Vec::with_capacity(capacity + 1);
221        slots.push(Slot {
222            u: SlotUnion {
223                free: FreeListEntry {
224                    next: 0,
225                    prev: 0,
226                    other_end: 0,
227                },
228            },
229            version: 0,
230        });
231
232        Self {
233            slots,
234            num_elems: 0,
235            _k: PhantomData,
236        }
237    }
238
239    /// Returns the number of elements in the slot map.
240    ///
241    /// # Examples
242    ///
243    /// ```
244    /// # use slotmapd::*;
245    /// let mut sm = HopSlotMap::with_capacity(10);
246    /// sm.insert("len() counts actual elements, not capacity");
247    /// let key = sm.insert("removed elements don't count either");
248    /// sm.remove(key);
249    /// assert_eq!(sm.len(), 1);
250    /// ```
251    pub fn len(&self) -> usize {
252        self.num_elems as usize
253    }
254
255    /// Returns if the slot map is empty.
256    ///
257    /// # Examples
258    ///
259    /// ```
260    /// # use slotmapd::*;
261    /// let mut sm = HopSlotMap::new();
262    /// let key = sm.insert("dummy");
263    /// assert_eq!(sm.is_empty(), false);
264    /// sm.remove(key);
265    /// assert_eq!(sm.is_empty(), true);
266    /// ```
267    pub fn is_empty(&self) -> bool {
268        self.num_elems == 0
269    }
270
271    /// Returns the number of elements the [`HopSlotMap`] can hold without
272    /// reallocating.
273    ///
274    /// # Examples
275    ///
276    /// ```
277    /// # use slotmapd::*;
278    /// let sm: HopSlotMap<_, f64> = HopSlotMap::with_capacity(10);
279    /// assert_eq!(sm.capacity(), 10);
280    /// ```
281    pub fn capacity(&self) -> usize {
282        // One slot is reserved for the freelist sentinel.
283        self.slots.capacity() - 1
284    }
285
286    /// Reserves capacity for at least `additional` more elements to be inserted
287    /// in the [`HopSlotMap`]. The collection may reserve more space to
288    /// avoid frequent reallocations.
289    ///
290    /// # Panics
291    ///
292    /// Panics if the new allocation size overflows [`usize`].
293    ///
294    /// # Examples
295    ///
296    /// ```
297    /// # use slotmapd::*;
298    /// let mut sm = HopSlotMap::new();
299    /// sm.insert("foo");
300    /// sm.reserve(32);
301    /// assert!(sm.capacity() >= 33);
302    /// ```
303    pub fn reserve(&mut self, additional: usize) {
304        // One slot is reserved for the freelist sentinel.
305        let needed = (self.len() + additional).saturating_sub(self.slots.len() - 1);
306        self.slots.reserve(needed);
307    }
308
309    /// Tries to reserve capacity for at least `additional` more elements to be
310    /// inserted in the [`HopSlotMap`]. The collection may reserve more space to
311    /// avoid frequent reallocations.
312    ///
313    /// # Examples
314    ///
315    /// ```
316    /// # use slotmapd::*;
317    /// let mut sm = HopSlotMap::new();
318    /// sm.insert("foo");
319    /// sm.try_reserve(32).unwrap();
320    /// assert!(sm.capacity() >= 33);
321    /// ```
322    #[cfg(all(nightly, any(doc, feature = "unstable")))]
323    #[cfg_attr(all(nightly, doc), doc(cfg(feature = "unstable")))]
324    pub fn try_reserve(&mut self, additional: usize) -> Result<(), TryReserveError> {
325        // One slot is reserved for the freelist sentinel.
326        let needed = (self.len() + additional).saturating_sub(self.slots.len() - 1);
327        self.slots.try_reserve(needed)
328    }
329
330    /// Returns [`true`] if the slot map contains `key`.
331    ///
332    /// # Examples
333    ///
334    /// ```
335    /// # use slotmapd::*;
336    /// let mut sm = HopSlotMap::new();
337    /// let key = sm.insert(42);
338    /// assert_eq!(sm.contains_key(key), true);
339    /// sm.remove(key);
340    /// assert_eq!(sm.contains_key(key), false);
341    /// ```
342    pub fn contains_key(&self, key: K) -> bool {
343        let kd = key.data();
344        self.slots
345            .get(kd.idx as usize)
346            .map_or(false, |slot| slot.version == kd.version.get())
347    }
348
349    /// Inserts a value into the slot map. Returns a unique key that can be
350    /// used to access this value.
351    ///
352    /// # Panics
353    ///
354    /// Panics if the number of elements in the slot map equals
355    /// 2<sup>32</sup> - 2.
356    ///
357    /// # Examples
358    ///
359    /// ```
360    /// # use slotmapd::*;
361    /// let mut sm = HopSlotMap::new();
362    /// let key = sm.insert(42);
363    /// assert_eq!(sm[key], 42);
364    /// ```
365    #[inline(always)]
366    pub fn insert(&mut self, value: V) -> K {
367        unsafe { self.try_insert_with_key::<_, Never>(move |_| Ok(value)).unwrap_unchecked_() }
368    }
369
370    // Helper function to make using the freelist painless.
371    // For that same ergonomy it uses u32, not usize as index.
372    // Safe iff idx is a valid index and the slot at that index is vacant.
373    unsafe fn freelist(&mut self, idx: u32) -> &mut FreeListEntry {
374        &mut self.slots.get_unchecked_mut(idx as usize).u.free
375    }
376
377    /// Inserts a value given by `f` into the slot map. The key where the
378    /// value will be stored is passed into `f`. This is useful to store values
379    /// that contain their own key.
380    ///
381    /// # Panics
382    ///
383    /// Panics if the number of elements in the slot map equals
384    /// 2<sup>32</sup> - 2.
385    ///
386    /// # Examples
387    ///
388    /// ```
389    /// # use slotmapd::*;
390    /// let mut sm = HopSlotMap::new();
391    /// let key = sm.insert_with_key(|k| (k, 20));
392    /// assert_eq!(sm[key], (key, 20));
393    /// ```
394    #[inline(always)]
395    pub fn insert_with_key<F>(&mut self, f: F) -> K
396    where
397        F: FnOnce(K) -> V,
398    {
399        unsafe { self.try_insert_with_key::<_, Never>(move |k| Ok(f(k))).unwrap_unchecked_() }
400    }
401
402    /// Inserts a value given by `f` into the slot map. The key where the
403    /// value will be stored is passed into `f`. This is useful to store values
404    /// that contain their own key.
405    ///
406    /// If `f` returns `Err`, this method returns the error. The slotmap is untouched.
407    ///
408    /// # Panics
409    ///
410    /// Panics if the number of elements in the slot map equals
411    /// 2<sup>32</sup> - 2.
412    ///
413    /// # Examples
414    ///
415    /// ```
416    /// # use slotmapd::*;
417    /// let mut sm = HopSlotMap::new();
418    /// let key = sm.try_insert_with_key::<_, ()>(|k| Ok((k, 20))).unwrap();
419    /// assert_eq!(sm[key], (key, 20));
420    ///
421    /// sm.try_insert_with_key::<_, ()>(|k| Err(())).unwrap_err();
422    /// ```
423    pub fn try_insert_with_key<F, E>(&mut self, f: F) -> Result<K, E>
424    where
425        F: FnOnce(K) -> Result<V, E>,
426    {
427        // In case f panics, we don't make any changes until we have the value.
428        let new_num_elems = self.num_elems + 1;
429        if new_num_elems == core::u32::MAX {
430            panic!("HopSlotMap number of elements overflow");
431        }
432
433        // All unsafe accesses here are safe due to the invariants of the slot
434        // map freelist.
435        unsafe {
436            let head = self.freelist(0).next;
437
438            // We have a contiguous block of vacant slots starting at head.
439            // Put our new element at the back slot.
440            let front = head;
441            let back = self.freelist(front).other_end;
442            let slot_idx = back as usize;
443
444            // Freelist is empty.
445            if slot_idx == 0 {
446                let version = 1;
447                let key = KeyData::new(self.slots.len() as u32, version).into();
448
449                self.slots.push(Slot {
450                    u: SlotUnion {
451                        value: ManuallyDrop::new(f(key)?),
452                    },
453                    version,
454                });
455                self.num_elems = new_num_elems;
456                return Ok(key);
457            }
458
459            // Compute value first in case f panics or returns an error.
460            let occupied_version = self.slots[slot_idx].version | 1;
461            let key = KeyData::new(slot_idx as u32, occupied_version).into();
462            let value = f(key)?;
463
464            // Update freelist.
465            if front == back {
466                // Used last slot in this block, move next one to head.
467                let new_head = self.freelist(front).next;
468                self.freelist(0).next = new_head;
469                self.freelist(new_head).prev = 0;
470            } else {
471                // Continue using this block, only need to update other_ends.
472                let new_back = back - 1;
473                self.freelist(new_back).other_end = front;
474                self.freelist(front).other_end = new_back;
475            }
476
477            // And finally insert the value.
478            let slot = &mut self.slots[slot_idx];
479            slot.version = occupied_version;
480            slot.u.value = ManuallyDrop::new(value);
481            self.num_elems = new_num_elems;
482            Ok(key)
483        }
484    }
485
486    // Helper function to remove a value from a slot. Safe iff the slot is
487    // occupied. Returns the value removed.
488    #[inline(always)]
489    unsafe fn remove_from_slot(&mut self, idx: usize) -> V {
490        // Remove value from slot.
491        let slot = self.slots.get_unchecked_mut(idx);
492        slot.version = slot.version.wrapping_add(1);
493        let value = ManuallyDrop::take(&mut slot.u.value);
494
495        // This is safe and can't underflow because of the sentinel element at
496        // the start.
497        let left_vacant = !self.slots.get_unchecked(idx - 1).occupied();
498        let right_vacant = self.slots.get(idx + 1).map_or(false, |s| !s.occupied());
499
500        // Maintain freelist by either appending/prepending this slot to a
501        // contiguous block to the left or right, merging the two blocks to the
502        // left and right or inserting a new block.
503        let i = idx as u32;
504        match (left_vacant, right_vacant) {
505            (false, false) => {
506                // New block, insert it at the tail.
507                let old_tail = self.freelist(0).prev;
508                self.freelist(0).prev = i;
509                self.freelist(old_tail).next = i;
510                *self.freelist(i) = FreeListEntry {
511                    other_end: i,
512                    next: 0,
513                    prev: old_tail,
514                };
515            },
516
517            (false, true) => {
518                // Prepend to vacant block on right.
519                let front_data = *self.freelist(i + 1);
520
521                // Since the start of this block moved we must update the pointers to it.
522                self.freelist(front_data.other_end).other_end = i;
523                self.freelist(front_data.prev).next = i;
524                self.freelist(front_data.next).prev = i;
525                *self.freelist(i) = front_data;
526            },
527
528            (true, false) => {
529                // Append to vacant block on left.
530                let front = self.freelist(i - 1).other_end;
531                *self.freelist(i) = FreeListEntry {
532                    next: 0,
533                    prev: 0,
534                    other_end: front,
535                };
536                self.freelist(front).other_end = i;
537            },
538
539            (true, true) => {
540                // We must merge left and right.
541                // First snip right out of the freelist.
542                let right = *self.freelist(i + 1);
543                self.freelist(right.prev).next = right.next;
544                self.freelist(right.next).prev = right.prev;
545
546                // Now update endpoints.
547                let front = self.freelist(i - 1).other_end;
548                let back = right.other_end;
549                self.freelist(front).other_end = back;
550                self.freelist(back).other_end = front;
551
552                *self.freelist(i) = FreeListEntry {
553                    next: 0,
554                    prev: 0,
555                    other_end: 0,
556                };
557            },
558        }
559
560        self.num_elems -= 1;
561
562        value
563    }
564
565    /// Removes a key from the slot map, returning the value at the key if the
566    /// key was not previously removed.
567    ///
568    /// # Examples
569    ///
570    /// ```
571    /// # use slotmapd::*;
572    /// let mut sm = HopSlotMap::new();
573    /// let key = sm.insert(42);
574    /// assert_eq!(sm.remove(key), Some(42));
575    /// assert_eq!(sm.remove(key), None);
576    /// ```
577    pub fn remove(&mut self, key: K) -> Option<V> {
578        let kd = key.data();
579        if self.contains_key(key) {
580            // This is safe because we know that the slot is occupied.
581            Some(unsafe { self.remove_from_slot(kd.idx as usize) })
582        } else {
583            None
584        }
585    }
586
587    /// Retains only the elements specified by the predicate.
588    ///
589    /// In other words, remove all key-value pairs `(k, v)` such that
590    /// `f(k, &mut v)` returns false. This method invalidates any removed keys.
591    ///
592    /// # Examples
593    ///
594    /// ```
595    /// # use slotmapd::*;
596    /// let mut sm = HopSlotMap::new();
597    ///
598    /// let k1 = sm.insert(0);
599    /// let k2 = sm.insert(1);
600    /// let k3 = sm.insert(2);
601    ///
602    /// sm.retain(|key, val| key == k1 || *val == 1);
603    ///
604    /// assert!(sm.contains_key(k1));
605    /// assert!(sm.contains_key(k2));
606    /// assert!(!sm.contains_key(k3));
607    ///
608    /// assert_eq!(2, sm.len());
609    /// ```
610    pub fn retain<F>(&mut self, mut f: F)
611    where
612        F: FnMut(K, &mut V) -> bool,
613    {
614        let mut elems_left_to_scan = self.len();
615        let mut cur = unsafe { self.slots.get_unchecked(0).u.free.other_end as usize + 1 };
616        while elems_left_to_scan > 0 {
617            // This is safe because removing elements does not shrink slots, cur always
618            // points to an occupied slot.
619            let idx = cur;
620            let slot = unsafe { self.slots.get_unchecked_mut(cur) };
621            let version = slot.version;
622            let key = KeyData::new(cur as u32, version).into();
623            let should_remove = !f(key, unsafe { &mut *slot.u.value });
624
625            cur = match self.slots.get(cur + 1).map(|s| s.get()) {
626                Some(Occupied(_)) => cur + 1,
627                Some(Vacant(free)) => free.other_end as usize + 1,
628                None => 0,
629            };
630
631            if should_remove {
632                // This must happen after getting the next index.
633                unsafe { self.remove_from_slot(idx) };
634            }
635
636            elems_left_to_scan -= 1;
637        }
638    }
639
640    /// Clears the slot map. Keeps the allocated memory for reuse.
641    ///
642    /// # Examples
643    ///
644    /// ```
645    /// # use slotmapd::*;
646    /// let mut sm = HopSlotMap::new();
647    /// for i in 0..10 {
648    ///     sm.insert(i);
649    /// }
650    /// assert_eq!(sm.len(), 10);
651    /// sm.clear();
652    /// assert_eq!(sm.len(), 0);
653    /// ```
654    pub fn clear(&mut self) {
655        self.drain();
656    }
657
658    /// Clears the slot map, returning all key-value pairs in arbitrary order as
659    /// an iterator. Keeps the allocated memory for reuse.
660    ///
661    /// When the iterator is dropped all elements in the slot map are removed,
662    /// even if the iterator was not fully consumed. If the iterator is not
663    /// dropped (using e.g. [`std::mem::forget`]), only the elements that were
664    /// iterated over are removed.
665    ///
666    /// # Examples
667    ///
668    /// ```
669    /// # use slotmapd::*;
670    /// let mut sm = HopSlotMap::new();
671    /// let k = sm.insert(0);
672    /// let v: Vec<_> = sm.drain().collect();
673    /// assert_eq!(sm.len(), 0);
674    /// assert_eq!(v, vec![(k, 0)]);
675    /// ```
676    pub fn drain(&mut self) -> Drain<K, V> {
677        Drain {
678            cur: unsafe { self.slots.get_unchecked(0).u.free.other_end as usize + 1 },
679            sm: self,
680        }
681    }
682
683    /// Returns a reference to the value corresponding to the key.
684    ///
685    /// # Examples
686    ///
687    /// ```
688    /// # use slotmapd::*;
689    /// let mut sm = HopSlotMap::new();
690    /// let key = sm.insert("bar");
691    /// assert_eq!(sm.get(key), Some(&"bar"));
692    /// sm.remove(key);
693    /// assert_eq!(sm.get(key), None);
694    /// ```
695    pub fn get(&self, key: K) -> Option<&V> {
696        let kd = key.data();
697        // This is safe because we check version first and a key always contains
698        // an odd version, thus we are occupied.
699        self.slots
700            .get(kd.idx as usize)
701            .filter(|slot| slot.version == kd.version.get())
702            .map(|slot| unsafe { &*slot.u.value })
703    }
704
705    /// Returns a reference to the value corresponding to the key without
706    /// version or bounds checking.
707    ///
708    /// # Safety
709    ///
710    /// This should only be used if `contains_key(key)` is true. Otherwise it is
711    /// dangerous undefined behavior.
712    ///
713    /// # Examples
714    ///
715    /// ```
716    /// # use slotmapd::*;
717    /// let mut sm = HopSlotMap::new();
718    /// let key = sm.insert("bar");
719    /// assert_eq!(unsafe { sm.get_unchecked(key) }, &"bar");
720    /// sm.remove(key);
721    /// // sm.get_unchecked(key) is now dangerous!
722    /// ```
723    pub unsafe fn get_unchecked(&self, key: K) -> &V {
724        debug_assert!(self.contains_key(key));
725        &self.slots.get_unchecked(key.data().idx as usize).u.value
726    }
727
728    /// Returns a mutable reference to the value corresponding to the key.
729    ///
730    /// # Examples
731    ///
732    /// ```
733    /// # use slotmapd::*;
734    /// let mut sm = HopSlotMap::new();
735    /// let key = sm.insert(3.5);
736    /// if let Some(x) = sm.get_mut(key) {
737    ///     *x += 3.0;
738    /// }
739    /// assert_eq!(sm[key], 6.5);
740    /// ```
741    pub fn get_mut(&mut self, key: K) -> Option<&mut V> {
742        let kd = key.data();
743        // This is safe because we check version first and a key always contains
744        // an odd version, thus we are occupied.
745        self.slots
746            .get_mut(kd.idx as usize)
747            .filter(|slot| slot.version == kd.version.get())
748            .map(|slot| unsafe { &mut *slot.u.value })
749    }
750
751    /// Returns a mutable reference to the value corresponding to the key
752    /// without version or bounds checking.
753    ///
754    /// # Safety
755    ///
756    /// This should only be used if `contains_key(key)` is true. Otherwise it is
757    /// dangerous undefined behavior.
758    ///
759    /// # Examples
760    ///
761    /// ```
762    /// # use slotmapd::*;
763    /// let mut sm = HopSlotMap::new();
764    /// let key = sm.insert("foo");
765    /// unsafe { *sm.get_unchecked_mut(key) = "bar" };
766    /// assert_eq!(sm[key], "bar");
767    /// sm.remove(key);
768    /// // sm.get_unchecked_mut(key) is now dangerous!
769    /// ```
770    pub unsafe fn get_unchecked_mut(&mut self, key: K) -> &mut V {
771        debug_assert!(self.contains_key(key));
772        &mut self.slots.get_unchecked_mut(key.data().idx as usize).u.value
773    }
774
775    /// Returns mutable references to the values corresponding to the given
776    /// keys. All keys must be valid and disjoint, otherwise [`None`] is
777    /// returned.
778    ///
779    /// Requires at least stable Rust version 1.51.
780    ///
781    /// # Examples
782    ///
783    /// ```
784    /// # use slotmapd::*;
785    /// let mut sm = HopSlotMap::new();
786    /// let ka = sm.insert("butter");
787    /// let kb = sm.insert("apples");
788    /// let kc = sm.insert("charlie");
789    /// sm.remove(kc); // Make key c invalid.
790    /// assert_eq!(sm.get_disjoint_mut([ka, kb, kc]), None); // Has invalid key.
791    /// assert_eq!(sm.get_disjoint_mut([ka, ka]), None); // Not disjoint.
792    /// let [a, b] = sm.get_disjoint_mut([ka, kb]).unwrap();
793    /// std::mem::swap(a, b);
794    /// assert_eq!(sm[ka], "apples");
795    /// assert_eq!(sm[kb], "butter");
796    /// ```
797    #[cfg(has_min_const_generics)]
798    pub fn get_disjoint_mut<const N: usize>(&mut self, keys: [K; N]) -> Option<[&mut V; N]> {
799        // Create an uninitialized array of `MaybeUninit`. The `assume_init` is
800        // safe because the type we are claiming to have initialized here is a
801        // bunch of `MaybeUninit`s, which do not require initialization.
802        let mut ptrs: [MaybeUninit<*mut V>; N] = unsafe { MaybeUninit::uninit().assume_init() };
803
804        let mut i = 0;
805        while i < N {
806            // We can avoid this clone after min_const_generics and array_map.
807            let kd = keys[i].data();
808            if !self.contains_key(kd.into()) {
809                break;
810            }
811
812            // This key is valid, and thus the slot is occupied. Temporarily
813            // mark it as unoccupied so duplicate keys would show up as invalid.
814            // This gives us a linear time disjointness check.
815            unsafe {
816                let slot = self.slots.get_unchecked_mut(kd.idx as usize);
817                slot.version ^= 1;
818                ptrs[i] = MaybeUninit::new(&mut *slot.u.value);
819            }
820            i += 1;
821        }
822
823        // Undo temporary unoccupied markings.
824        for k in &keys[..i] {
825            let idx = k.data().idx as usize;
826            unsafe {
827                self.slots.get_unchecked_mut(idx).version ^= 1;
828            }
829        }
830
831        if i == N {
832            // All were valid and disjoint.
833            Some(unsafe { core::mem::transmute_copy::<_, [&mut V; N]>(&ptrs) })
834        } else {
835            None
836        }
837    }
838
839    /// Returns mutable references to the values corresponding to the given
840    /// keys. All keys must be valid and disjoint.
841    ///
842    /// Requires at least stable Rust version 1.51.
843    ///
844    /// # Safety
845    ///
846    /// This should only be used if `contains_key(key)` is true for every given
847    /// key and no two keys are equal. Otherwise it is potentially unsafe.
848    ///
849    /// # Examples
850    ///
851    /// ```
852    /// # use slotmapd::*;
853    /// let mut sm = HopSlotMap::new();
854    /// let ka = sm.insert("butter");
855    /// let kb = sm.insert("apples");
856    /// let [a, b] = unsafe { sm.get_disjoint_unchecked_mut([ka, kb]) };
857    /// std::mem::swap(a, b);
858    /// assert_eq!(sm[ka], "apples");
859    /// assert_eq!(sm[kb], "butter");
860    /// ```
861    #[cfg(has_min_const_generics)]
862    pub unsafe fn get_disjoint_unchecked_mut<const N: usize>(
863        &mut self,
864        keys: [K; N],
865    ) -> [&mut V; N] {
866        // Safe, see get_disjoint_mut.
867        let mut ptrs: [MaybeUninit<*mut V>; N] = MaybeUninit::uninit().assume_init();
868        for i in 0..N {
869            ptrs[i] = MaybeUninit::new(self.get_unchecked_mut(keys[i]));
870        }
871        core::mem::transmute_copy::<_, [&mut V; N]>(&ptrs)
872    }
873
874    /// An iterator visiting all key-value pairs in arbitrary order. The
875    /// iterator element type is `(K, &'a V)`.
876    ///
877    /// # Examples
878    ///
879    /// ```
880    /// # use slotmapd::*;
881    /// let mut sm = HopSlotMap::new();
882    /// let k0 = sm.insert(0);
883    /// let k1 = sm.insert(1);
884    /// let k2 = sm.insert(2);
885    ///
886    /// for (k, v) in sm.iter() {
887    ///     println!("key: {:?}, val: {}", k, v);
888    /// }
889    /// ```
890    pub fn iter(&self) -> Iter<K, V> {
891        Iter {
892            cur: unsafe { self.slots.get_unchecked(0).u.free.other_end as usize + 1 },
893            num_left: self.len(),
894            slots: &self.slots[..],
895            _k: PhantomData,
896        }
897    }
898
899    /// An iterator visiting all key-value pairs in arbitrary order, with
900    /// mutable references to the values. The iterator element type is
901    /// `(K, &'a mut V)`.
902    ///
903    /// # Examples
904    ///
905    /// ```
906    /// # use slotmapd::*;
907    /// let mut sm = HopSlotMap::new();
908    /// let k0 = sm.insert(10);
909    /// let k1 = sm.insert(20);
910    /// let k2 = sm.insert(30);
911    ///
912    /// for (k, v) in sm.iter_mut() {
913    ///     if k != k1 {
914    ///         *v *= -1;
915    ///     }
916    /// }
917    ///
918    /// assert_eq!(sm[k0], -10);
919    /// assert_eq!(sm[k1], 20);
920    /// assert_eq!(sm[k2], -30);
921    /// ```
922    pub fn iter_mut(&mut self) -> IterMut<K, V> {
923        IterMut {
924            cur: 0,
925            num_left: self.len(),
926            slots: &mut self.slots[..],
927            _k: PhantomData,
928        }
929    }
930
931    /// An iterator visiting all keys in arbitrary order. The iterator element
932    /// type is `K`.
933    ///
934    /// # Examples
935    ///
936    /// ```
937    /// # use slotmapd::*;
938    /// # use std::collections::HashSet;
939    /// let mut sm = HopSlotMap::new();
940    /// let k0 = sm.insert(10);
941    /// let k1 = sm.insert(20);
942    /// let k2 = sm.insert(30);
943    /// let keys: HashSet<_> = sm.keys().collect();
944    /// let check: HashSet<_> = vec![k0, k1, k2].into_iter().collect();
945    /// assert_eq!(keys, check);
946    /// ```
947    pub fn keys(&self) -> Keys<K, V> {
948        Keys { inner: self.iter() }
949    }
950
951    /// An iterator visiting all values in arbitrary order. The iterator element
952    /// type is `&'a V`.
953    ///
954    /// # Examples
955    ///
956    /// ```
957    /// # use slotmapd::*;
958    /// # use std::collections::HashSet;
959    /// let mut sm = HopSlotMap::new();
960    /// let k0 = sm.insert(10);
961    /// let k1 = sm.insert(20);
962    /// let k2 = sm.insert(30);
963    /// let values: HashSet<_> = sm.values().collect();
964    /// let check: HashSet<_> = vec![&10, &20, &30].into_iter().collect();
965    /// assert_eq!(values, check);
966    /// ```
967    pub fn values(&self) -> Values<K, V> {
968        Values { inner: self.iter() }
969    }
970
971    /// An iterator visiting all values mutably in arbitrary order. The iterator
972    /// element type is `&'a mut V`.
973    ///
974    /// # Examples
975    ///
976    /// ```
977    /// # use slotmapd::*;
978    /// # use std::collections::HashSet;
979    /// let mut sm = HopSlotMap::new();
980    /// sm.insert(1);
981    /// sm.insert(2);
982    /// sm.insert(3);
983    /// sm.values_mut().for_each(|n| { *n *= 3 });
984    /// let values: HashSet<_> = sm.into_iter().map(|(_k, v)| v).collect();
985    /// let check: HashSet<_> = vec![3, 6, 9].into_iter().collect();
986    /// assert_eq!(values, check);
987    /// ```
988    pub fn values_mut(&mut self) -> ValuesMut<K, V> {
989        ValuesMut {
990            inner: self.iter_mut(),
991        }
992    }
993}
994
995impl<K: Key, V> Clone for HopSlotMap<K, V>
996where
997    V: Clone,
998{
999    fn clone(&self) -> Self {
1000        Self {
1001            slots: self.slots.clone(),
1002            ..*self
1003        }
1004    }
1005
1006    fn clone_from(&mut self, source: &Self) {
1007        self.slots.clone_from(&source.slots);
1008        self.num_elems = source.num_elems;
1009    }
1010}
1011
1012impl<K: Key, V> Default for HopSlotMap<K, V> {
1013    fn default() -> Self {
1014        Self::with_key()
1015    }
1016}
1017
1018impl<K: Key, V> Index<K> for HopSlotMap<K, V> {
1019    type Output = V;
1020
1021    fn index(&self, key: K) -> &V {
1022        match self.get(key) {
1023            Some(r) => r,
1024            None => panic!("invalid HopSlotMap key used"),
1025        }
1026    }
1027}
1028
1029impl<K: Key, V> IndexMut<K> for HopSlotMap<K, V> {
1030    fn index_mut(&mut self, key: K) -> &mut V {
1031        match self.get_mut(key) {
1032            Some(r) => r,
1033            None => panic!("invalid HopSlotMap key used"),
1034        }
1035    }
1036}
1037
1038// Iterators.
1039/// A draining iterator for [`HopSlotMap`].
1040///
1041/// This iterator is created by [`HopSlotMap::drain`].
1042#[derive(Debug)]
1043pub struct Drain<'a, K: Key + 'a, V: 'a> {
1044    cur: usize,
1045    sm: &'a mut HopSlotMap<K, V>,
1046}
1047
1048/// An iterator that moves key-value pairs out of a [`HopSlotMap`].
1049///
1050/// This iterator is created by calling the `into_iter` method on [`HopSlotMap`],
1051/// provided by the [`IntoIterator`] trait.
1052#[derive(Debug, Clone)]
1053pub struct IntoIter<K: Key, V> {
1054    cur: usize,
1055    num_left: usize,
1056    slots: Vec<Slot<V>>,
1057    _k: PhantomData<fn(K) -> K>,
1058}
1059
1060/// An iterator over the key-value pairs in a [`HopSlotMap`].
1061///
1062/// This iterator is created by [`HopSlotMap::iter`].
1063#[derive(Debug)]
1064pub struct Iter<'a, K: Key + 'a, V: 'a> {
1065    cur: usize,
1066    num_left: usize,
1067    slots: &'a [Slot<V>],
1068    _k: PhantomData<fn(K) -> K>,
1069}
1070
1071impl<'a, K: 'a + Key, V: 'a> Clone for Iter<'a, K, V> {
1072    fn clone(&self) -> Self {
1073        Iter {
1074            cur: self.cur,
1075            num_left: self.num_left,
1076            slots: self.slots,
1077            _k: self._k.clone(),
1078        }
1079    }
1080}
1081
1082/// A mutable iterator over the key-value pairs in a [`HopSlotMap`].
1083///
1084/// This iterator is created by [`HopSlotMap::iter_mut`].
1085#[derive(Debug)]
1086pub struct IterMut<'a, K: Key + 'a, V: 'a> {
1087    cur: usize,
1088    num_left: usize,
1089    slots: &'a mut [Slot<V>],
1090    _k: PhantomData<fn(K) -> K>,
1091}
1092
1093/// An iterator over the keys in a [`HopSlotMap`].
1094///
1095/// This iterator is created by [`HopSlotMap::keys`].
1096#[derive(Debug)]
1097pub struct Keys<'a, K: Key + 'a, V: 'a> {
1098    inner: Iter<'a, K, V>,
1099}
1100
1101impl<'a, K: 'a + Key, V: 'a> Clone for Keys<'a, K, V> {
1102    fn clone(&self) -> Self {
1103        Keys {
1104            inner: self.inner.clone(),
1105        }
1106    }
1107}
1108
1109/// An iterator over the values in a [`HopSlotMap`].
1110///
1111/// This iterator is created by [`HopSlotMap::values`].
1112#[derive(Debug)]
1113pub struct Values<'a, K: Key + 'a, V: 'a> {
1114    inner: Iter<'a, K, V>,
1115}
1116
1117impl<'a, K: 'a + Key, V: 'a> Clone for Values<'a, K, V> {
1118    fn clone(&self) -> Self {
1119        Values {
1120            inner: self.inner.clone(),
1121        }
1122    }
1123}
1124
1125/// A mutable iterator over the values in a [`HopSlotMap`].
1126///
1127/// This iterator is created by [`HopSlotMap::values_mut`].
1128#[derive(Debug)]
1129pub struct ValuesMut<'a, K: Key + 'a, V: 'a> {
1130    inner: IterMut<'a, K, V>,
1131}
1132
1133impl<'a, K: Key, V> Iterator for Drain<'a, K, V> {
1134    type Item = (K, V);
1135
1136    fn next(&mut self) -> Option<(K, V)> {
1137        // All unchecked indices are safe due to the invariants of the freelist
1138        // and that self.sm.len() guarantees there is another element.
1139        if self.sm.len() == 0 {
1140            return None;
1141        }
1142
1143        // Skip ahead to next element. Must do this before removing.
1144        let idx = self.cur;
1145        self.cur = match self.sm.slots.get(idx + 1).map(|s| s.get()) {
1146            Some(Occupied(_)) => idx + 1,
1147            Some(Vacant(free)) => free.other_end as usize + 1,
1148            None => 0,
1149        };
1150
1151        let key = KeyData::new(idx as u32, unsafe { self.sm.slots.get_unchecked(idx).version });
1152        Some((key.into(), unsafe { self.sm.remove_from_slot(idx) }))
1153    }
1154
1155    fn size_hint(&self) -> (usize, Option<usize>) {
1156        (self.sm.len(), Some(self.sm.len()))
1157    }
1158}
1159
1160impl<'a, K: Key, V> Drop for Drain<'a, K, V> {
1161    fn drop(&mut self) {
1162        self.for_each(|_drop| {});
1163    }
1164}
1165
1166impl<K: Key, V> Iterator for IntoIter<K, V> {
1167    type Item = (K, V);
1168
1169    fn next(&mut self) -> Option<(K, V)> {
1170        if self.cur >= self.slots.len() {
1171            return None;
1172        }
1173
1174        let idx = match self.slots[self.cur].get() {
1175            Occupied(_) => self.cur,
1176            Vacant(free) => {
1177                // Skip block of contiguous vacant slots.
1178                let idx = free.other_end as usize + 1;
1179                if idx >= self.slots.len() {
1180                    return None;
1181                }
1182                idx
1183            },
1184        };
1185
1186        self.cur = idx + 1;
1187        self.num_left -= 1;
1188        let slot = &mut self.slots[idx];
1189        let key = KeyData::new(idx as u32, slot.version).into();
1190        slot.version = 0; // Prevent dropping after extracting the value.
1191        Some((key, unsafe { ManuallyDrop::take(&mut slot.u.value) }))
1192    }
1193
1194    fn size_hint(&self) -> (usize, Option<usize>) {
1195        (self.num_left, Some(self.num_left))
1196    }
1197}
1198
1199impl<'a, K: Key, V> Iterator for Iter<'a, K, V> {
1200    type Item = (K, &'a V);
1201
1202    fn next(&mut self) -> Option<(K, &'a V)> {
1203        // All unchecked indices are safe due to the invariants of the freelist
1204        // and that num_left guarantees there is another element.
1205        if self.num_left == 0 {
1206            return None;
1207        }
1208        self.num_left -= 1;
1209
1210        let idx = match unsafe { self.slots.get_unchecked(self.cur).get() } {
1211            Occupied(_) => self.cur,
1212            Vacant(free) => free.other_end as usize + 1,
1213        };
1214
1215        self.cur = idx + 1;
1216        let slot = unsafe { self.slots.get_unchecked(idx) };
1217        let key = KeyData::new(idx as u32, slot.version).into();
1218        Some((key, unsafe { &*slot.u.value }))
1219    }
1220
1221    fn size_hint(&self) -> (usize, Option<usize>) {
1222        (self.num_left, Some(self.num_left))
1223    }
1224}
1225
1226impl<'a, K: Key, V> Iterator for IterMut<'a, K, V> {
1227    type Item = (K, &'a mut V);
1228
1229    fn next(&mut self) -> Option<(K, &'a mut V)> {
1230        if self.cur >= self.slots.len() {
1231            return None;
1232        }
1233
1234        let idx = match self.slots[self.cur].get() {
1235            Occupied(_) => self.cur,
1236            Vacant(free) => {
1237                // Skip block of contiguous vacant slots.
1238                let idx = free.other_end as usize + 1;
1239                if idx >= self.slots.len() {
1240                    return None;
1241                }
1242                idx
1243            },
1244        };
1245
1246        self.cur = idx + 1;
1247        self.num_left -= 1;
1248
1249        // Unsafe necessary because Rust can't deduce that we won't
1250        // return multiple references to the same value.
1251        let slot = &mut self.slots[idx];
1252        let version = slot.version;
1253        let value_ref = unsafe {
1254            let ptr: *mut V = &mut *slot.u.value;
1255            &mut *ptr
1256        };
1257        Some((KeyData::new(idx as u32, version).into(), value_ref))
1258    }
1259
1260    fn size_hint(&self) -> (usize, Option<usize>) {
1261        (self.num_left, Some(self.num_left))
1262    }
1263}
1264
1265impl<'a, K: Key, V> Iterator for Keys<'a, K, V> {
1266    type Item = K;
1267
1268    fn next(&mut self) -> Option<K> {
1269        self.inner.next().map(|(key, _)| key)
1270    }
1271
1272    fn size_hint(&self) -> (usize, Option<usize>) {
1273        self.inner.size_hint()
1274    }
1275}
1276
1277impl<'a, K: Key, V> Iterator for Values<'a, K, V> {
1278    type Item = &'a V;
1279
1280    fn next(&mut self) -> Option<&'a V> {
1281        self.inner.next().map(|(_, value)| value)
1282    }
1283
1284    fn size_hint(&self) -> (usize, Option<usize>) {
1285        self.inner.size_hint()
1286    }
1287}
1288
1289impl<'a, K: Key, V> Iterator for ValuesMut<'a, K, V> {
1290    type Item = &'a mut V;
1291
1292    fn next(&mut self) -> Option<&'a mut V> {
1293        self.inner.next().map(|(_, value)| value)
1294    }
1295
1296    fn size_hint(&self) -> (usize, Option<usize>) {
1297        self.inner.size_hint()
1298    }
1299}
1300
1301impl<'a, K: Key, V> IntoIterator for &'a HopSlotMap<K, V> {
1302    type Item = (K, &'a V);
1303    type IntoIter = Iter<'a, K, V>;
1304
1305    fn into_iter(self) -> Self::IntoIter {
1306        self.iter()
1307    }
1308}
1309
1310impl<'a, K: Key, V> IntoIterator for &'a mut HopSlotMap<K, V> {
1311    type Item = (K, &'a mut V);
1312    type IntoIter = IterMut<'a, K, V>;
1313
1314    fn into_iter(self) -> Self::IntoIter {
1315        self.iter_mut()
1316    }
1317}
1318
1319impl<K: Key, V> IntoIterator for HopSlotMap<K, V> {
1320    type Item = (K, V);
1321    type IntoIter = IntoIter<K, V>;
1322
1323    fn into_iter(self) -> Self::IntoIter {
1324        IntoIter {
1325            cur: 0,
1326            num_left: self.len(),
1327            slots: self.slots,
1328            _k: PhantomData,
1329        }
1330    }
1331}
1332
1333impl<'a, K: Key, V> FusedIterator for Iter<'a, K, V> {}
1334impl<'a, K: Key, V> FusedIterator for IterMut<'a, K, V> {}
1335impl<'a, K: Key, V> FusedIterator for Keys<'a, K, V> {}
1336impl<'a, K: Key, V> FusedIterator for Values<'a, K, V> {}
1337impl<'a, K: Key, V> FusedIterator for ValuesMut<'a, K, V> {}
1338impl<'a, K: Key, V> FusedIterator for Drain<'a, K, V> {}
1339impl<K: Key, V> FusedIterator for IntoIter<K, V> {}
1340
1341impl<'a, K: Key, V> ExactSizeIterator for Iter<'a, K, V> {}
1342impl<'a, K: Key, V> ExactSizeIterator for IterMut<'a, K, V> {}
1343impl<'a, K: Key, V> ExactSizeIterator for Keys<'a, K, V> {}
1344impl<'a, K: Key, V> ExactSizeIterator for Values<'a, K, V> {}
1345impl<'a, K: Key, V> ExactSizeIterator for ValuesMut<'a, K, V> {}
1346impl<'a, K: Key, V> ExactSizeIterator for Drain<'a, K, V> {}
1347impl<K: Key, V> ExactSizeIterator for IntoIter<K, V> {}
1348
1349// Serialization with serde.
1350#[cfg(feature = "serde")]
1351mod serialize {
1352    use serde::{de, Deserialize, Deserializer, Serialize, Serializer};
1353
1354    use super::*;
1355
1356    #[derive(Serialize, Deserialize)]
1357    enum SerdeValue<T> {
1358        O(T),
1359        F(FreeListEntry),
1360    }
1361
1362    #[derive(Serialize, Deserialize)]
1363    struct SerdeSlot<T> {
1364        value: SerdeValue<T>,
1365        version: u32,
1366    }
1367
1368    impl<T: Serialize> Serialize for Slot<T> {
1369        fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
1370        where
1371            S: Serializer,
1372        {
1373            let serde_slot = SerdeSlot {
1374                version: self.version,
1375                value: match self.get() {
1376                    Occupied(value) => SerdeValue::O(value),
1377                    Vacant(f) => SerdeValue::F(*f),
1378                },
1379            };
1380            serde_slot.serialize(serializer)
1381        }
1382    }
1383
1384    impl<'de, T> Deserialize<'de> for Slot<T>
1385    where
1386        T: Deserialize<'de>,
1387    {
1388        fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
1389        where
1390            D: Deserializer<'de>,
1391        {
1392            let serde_slot: SerdeSlot<T> = Deserialize::deserialize(deserializer)?;
1393            let occupied = serde_slot.version % 2 == 1;
1394            if occupied ^ matches!(serde_slot.value, SerdeValue::O(_)) {
1395                return Err(de::Error::custom(&"inconsistent occupation in Slot"));
1396            }
1397
1398            Ok(Self {
1399                u: match serde_slot.value {
1400                    SerdeValue::O(value) => SlotUnion {
1401                        value: ManuallyDrop::new(value),
1402                    },
1403                    SerdeValue::F(free) => SlotUnion {
1404                        free,
1405                    },
1406                },
1407                version: serde_slot.version,
1408            })
1409        }
1410    }
1411
1412    impl<K: Key, V: Serialize> Serialize for HopSlotMap<K, V> {
1413        fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
1414        where
1415            S: Serializer,
1416        {
1417            self.slots.serialize(serializer)
1418        }
1419    }
1420
1421    impl<'de, K: Key, V: Deserialize<'de>> Deserialize<'de> for HopSlotMap<K, V> {
1422        fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
1423        where
1424            D: Deserializer<'de>,
1425        {
1426            let slots: Vec<Slot<V>> = Deserialize::deserialize(deserializer)?;
1427            if slots.len() >= u32::max_value() as usize {
1428                return Err(de::Error::custom(&"too many slots"));
1429            }
1430
1431            // Ensure the first slot exists and is empty for the sentinel.
1432            if slots.get(0).map_or(true, |slot| slot.version % 2 == 1) {
1433                return Err(de::Error::custom(&"first slot not empty"));
1434            }
1435
1436            let mut n_free: u32 = 0;
1437
1438            let mut next_block = 0;
1439            let mut prev = 0;
1440
1441            let mut loop_avoid = slots.len();
1442
1443            // go through block chain, check consistency and count free slots
1444            loop {
1445                if loop_avoid == 0 {
1446                    return Err(de::Error::custom(&"loop in block chain not starting/ending at zero"));
1447                }
1448                loop_avoid -= 1;
1449
1450                let fl: FreeListEntry;
1451                if let Some(Vacant(f)) = slots.get(next_block as usize).map(Slot::get) {
1452                    fl = *f
1453                } else {
1454                    return Err(de::Error::custom(&"next pointing to non-existent or occupied"));
1455                }
1456
1457                if next_block != 0 && fl.prev != prev {
1458                    return Err(de::Error::custom(&"prev not consistent"));
1459                }
1460                prev = next_block;
1461
1462                if fl.other_end < next_block {
1463                    return Err(de::Error::custom(&"block end before start"));
1464                }
1465                for i in next_block..=fl.other_end {
1466                    if slots.get(i as usize).map_or(true, |s| s.occupied()) {
1467                        return Err(de::Error::custom(&"block not free"));
1468                    }
1469                    n_free += 1;
1470                }
1471
1472                next_block = fl.next;
1473                if next_block == 0 {
1474                    break
1475                }
1476            }
1477
1478            let mut num_elems: u32 = 0;
1479            for slot in &slots {
1480                if slot.occupied() {
1481                    num_elems += 1
1482                }
1483            }
1484
1485            if num_elems + n_free != slots.len() as u32 {
1486                return Err(de::Error::custom(&"inconsistent occupancy"));
1487            }
1488
1489            Ok(Self {
1490                num_elems,
1491                slots,
1492                _k: PhantomData,
1493            })
1494        }
1495    }
1496}
1497
1498#[cfg(test)]
1499mod tests {
1500    use std::collections::{HashSet, HashMap};
1501
1502    use quickcheck::quickcheck;
1503
1504    use super::*;
1505
1506    #[derive(Clone)]
1507    struct CountDrop<'a>(&'a std::cell::RefCell<usize>);
1508
1509    impl<'a> Drop for CountDrop<'a> {
1510        fn drop(&mut self) {
1511            *self.0.borrow_mut() += 1;
1512        }
1513    }
1514
1515    #[cfg(all(nightly, feature = "unstable"))]
1516    #[test]
1517    fn check_drops() {
1518        let drops = std::cell::RefCell::new(0usize);
1519
1520        {
1521            let mut clone = {
1522                // Insert 1000 items.
1523                let mut sm = HopSlotMap::new();
1524                let mut sm_keys = Vec::new();
1525                for _ in 0..1000 {
1526                    sm_keys.push(sm.insert(CountDrop(&drops)));
1527                }
1528
1529                // Remove even keys.
1530                for i in (0..1000).filter(|i| i % 2 == 0) {
1531                    sm.remove(sm_keys[i]);
1532                }
1533
1534                // Should only have dropped 500 so far.
1535                assert_eq!(*drops.borrow(), 500);
1536
1537                // Let's clone ourselves and then die.
1538                sm.clone()
1539            };
1540
1541            // Now all original items should have been dropped exactly once.
1542            assert_eq!(*drops.borrow(), 1000);
1543
1544            // Reuse some empty slots.
1545            for _ in 0..250 {
1546                clone.insert(CountDrop(&drops));
1547            }
1548        }
1549
1550        // 1000 + 750 drops in total should have happened.
1551        assert_eq!(*drops.borrow(), 1750);
1552    }
1553
1554    #[cfg(all(nightly, feature = "unstable"))]
1555    #[test]
1556    fn disjoint() {
1557        // Intended to be run with miri to find any potential UB.
1558        let mut sm = HopSlotMap::new();
1559
1560        // Some churn.
1561        for i in 0..20usize {
1562            sm.insert(i);
1563        }
1564        sm.retain(|_, i| *i % 2 == 0);
1565
1566        let keys: Vec<_> = sm.keys().collect();
1567        for i in 0..keys.len() {
1568            for j in 0..keys.len() {
1569                if let Some([r0, r1]) = sm.get_disjoint_mut([keys[i], keys[j]]) {
1570                    *r0 ^= *r1;
1571                    *r1 = r1.wrapping_add(*r0);
1572                } else {
1573                    assert!(i == j);
1574                }
1575            }
1576        }
1577
1578        for i in 0..keys.len() {
1579            for j in 0..keys.len() {
1580                for k in 0..keys.len() {
1581                    if let Some([r0, r1, r2]) = sm.get_disjoint_mut([keys[i], keys[j], keys[k]]) {
1582                        *r0 ^= *r1;
1583                        *r0 = r0.wrapping_add(*r2);
1584                        *r1 ^= *r0;
1585                        *r1 = r1.wrapping_add(*r2);
1586                        *r2 ^= *r0;
1587                        *r2 = r2.wrapping_add(*r1);
1588                    } else {
1589                        assert!(i == j || j == k || i == k);
1590                    }
1591                }
1592            }
1593        }
1594    }
1595
1596    quickcheck! {
1597        fn qc_slotmap_equiv_hashmap(operations: Vec<(u8, u32)>) -> bool {
1598            let mut hm = HashMap::new();
1599            let mut hm_keys = Vec::new();
1600            let mut unique_key = 0u32;
1601            let mut sm = HopSlotMap::new();
1602            let mut sm_keys = Vec::new();
1603
1604            #[cfg(not(feature = "serde"))]
1605            let num_ops = 3;
1606            #[cfg(feature = "serde")]
1607            let num_ops = 4;
1608
1609            for (op, val) in operations {
1610                match op % num_ops {
1611                    // Insert.
1612                    0 => {
1613                        hm.insert(unique_key, val);
1614                        hm_keys.push(unique_key);
1615                        unique_key += 1;
1616
1617                        sm_keys.push(sm.insert(val));
1618                    }
1619
1620                    // Delete.
1621                    1 => {
1622                        // 10% of the time test clear.
1623                        if val % 10 == 0 {
1624                            let hmvals: HashSet<_> = hm.drain().map(|(_, v)| v).collect();
1625                            let smvals: HashSet<_> = sm.drain().map(|(_, v)| v).collect();
1626                            if hmvals != smvals {
1627                                return false;
1628                            }
1629                        }
1630                        if hm_keys.is_empty() { continue; }
1631
1632                        let idx = val as usize % hm_keys.len();
1633                        if hm.remove(&hm_keys[idx]) != sm.remove(sm_keys[idx]) {
1634                            return false;
1635                        }
1636                    }
1637
1638                    // Access.
1639                    2 => {
1640                        if hm_keys.is_empty() { continue; }
1641                        let idx = val as usize % hm_keys.len();
1642                        let (hm_key, sm_key) = (&hm_keys[idx], sm_keys[idx]);
1643
1644                        if hm.contains_key(hm_key) != sm.contains_key(sm_key) ||
1645                           hm.get(hm_key) != sm.get(sm_key) {
1646                            return false;
1647                        }
1648                    }
1649
1650                    // Serde round-trip.
1651                    #[cfg(feature = "serde")]
1652                    3 => {
1653                        let ser = serde_json::to_string(&sm).unwrap();
1654                        sm = serde_json::from_str(&ser).unwrap();
1655                    }
1656
1657                    _ => unreachable!(),
1658                }
1659            }
1660
1661            let mut smv: Vec<_> = sm.values().collect();
1662            let mut hmv: Vec<_> = hm.values().collect();
1663            smv.sort();
1664            hmv.sort();
1665            smv == hmv
1666        }
1667
1668        #[cfg(feature = "serde")]
1669        fn qc_slotmap_equiv_no_serde(operations: Vec<(u8, u32)>) -> quickcheck::TestResult {
1670            use quickcheck::TestResult;
1671            let mut sm2 = HopSlotMap::new();
1672            let mut sm2_keys = Vec::new();
1673            let mut sm = HopSlotMap::new();
1674            let mut sm_keys = Vec::new();
1675
1676            let num_ops = 4;
1677
1678            for (op, val) in operations {
1679                match op % num_ops {
1680                    // Insert.
1681                    0 => {
1682                        sm_keys.push(sm.insert(val));
1683                        sm2_keys.push(sm2.insert(val));
1684                    }
1685
1686                    // Delete.
1687                    1 => {
1688                        // 10% of the time test clear.
1689                        if val % 10 == 0 {
1690                            let sm2vals: HashSet<_> = sm2.drain().map(|(_, v)| v).collect();
1691                            let smvals: HashSet<_> = sm.drain().map(|(_, v)| v).collect();
1692                            if sm2vals != smvals {
1693                                return TestResult::failed();
1694                            }
1695                        }
1696                        if sm2_keys.is_empty() { continue; }
1697
1698                        let idx = val as usize % sm2_keys.len();
1699                        if sm2.remove(sm2_keys[idx]) != sm.remove(sm_keys[idx]) {
1700                            return TestResult::failed();
1701                        }
1702                    }
1703
1704                    // Access.
1705                    2 => {
1706                        if sm2_keys.is_empty() { continue; }
1707                        let idx = val as usize % sm2_keys.len();
1708                        let (hm_key, sm_key) = (sm2_keys[idx], sm_keys[idx]);
1709
1710                        if sm2.contains_key(hm_key) != sm.contains_key(sm_key) ||
1711                            sm2.get(hm_key) != sm.get(sm_key) {
1712                            return TestResult::failed();
1713                        }
1714                    }
1715
1716                    // Serde round-trip.
1717                    #[cfg(feature = "serde")]
1718                    3 => {
1719                        let ser = serde_json::to_string(&sm).unwrap();
1720
1721                        //sm = serde_json::from_str(&ser).unwrap();
1722                        match serde_json::from_str(&ser) {
1723                            Ok(x) => sm = x,
1724                            Err(e) => return TestResult::error(format!("{} | {}", e, &ser)),
1725                        };
1726                    }
1727
1728                    _ => unreachable!(),
1729                }
1730            }
1731
1732            if sm.slots.len() != sm2.slots.len() {
1733                return TestResult::error(format!("slot count differ {} vs {}", sm.slots.len(), sm2.slots.len()));
1734            }
1735
1736            for (i, (slota, slotb)) in sm.slots.iter().zip(sm2.slots.iter()).enumerate() {
1737                if slota.version != slotb.version {
1738                    return TestResult::error(format!("slots differ in version {} vs {}", slota.version, slotb.version));
1739                }
1740                match slota.version % 2 {
1741                    0 => unsafe {
1742                        let fa = slota.u.free;
1743                        let fb = slotb.u.free;
1744                        if (fa.next, fa.other_end, fa.prev) != (fb.next, fb.other_end, fb.prev) {
1745                            return TestResult::error(format!("slots differ in free list {:?} vs {:?} at idx {}", fa, fb, i));
1746                        }
1747                    }
1748                    1 => unsafe {
1749                        if slota.u.value != slotb.u.value {
1750                            return TestResult::error(format!("slots differ in value {:?} vs {:?} at idx {}", slota.u.value, slotb.u.value, i));
1751                        }
1752                        continue
1753                    }
1754                    _ => unreachable!(),
1755                }
1756            }
1757
1758            TestResult::passed()
1759        }
1760    }
1761
1762    #[cfg(feature = "serde")]
1763    #[test]
1764    fn slotmap_serde() {
1765        let mut sm = HopSlotMap::new();
1766        // Self-referential structure.
1767        let first = sm.insert_with_key(|k| (k, 23i32));
1768        let second = sm.insert((first, 42));
1769
1770        // Make some empty slots.
1771        let empties = vec![sm.insert((first, 0)), sm.insert((first, 0))];
1772        empties.iter().for_each(|k| {
1773            sm.remove(*k);
1774        });
1775
1776        let third = sm.insert((second, 0));
1777        sm[first].0 = third;
1778
1779        let ser = serde_json::to_string_pretty(&sm).unwrap();
1780        let de: HopSlotMap<DefaultKey, (DefaultKey, i32)> = serde_json::from_str(&ser).unwrap();
1781        assert_eq!(de.len(), sm.len());
1782
1783        let mut smkv: Vec<_> = sm.iter().collect();
1784        let mut dekv: Vec<_> = de.iter().collect();
1785        smkv.sort();
1786        dekv.sort();
1787        assert_eq!(smkv, dekv);
1788    }
1789
1790    #[cfg(feature = "serde")]
1791    #[test]
1792    fn slotmap_serde_freelist() {
1793        let mut sm = HopSlotMap::new();
1794        let k = sm.insert(0i32);
1795        let k2 = sm.insert(0i32);
1796        sm.insert(0i32);
1797        sm.remove(k2);
1798        sm.remove(k);
1799
1800        let ser = serde_json::to_string_pretty(&sm).unwrap();
1801        let mut de: HopSlotMap<DefaultKey, i32> = serde_json::from_str(&ser).unwrap();
1802
1803        de.insert(0);
1804        de.insert(1);
1805        de.insert(2);
1806        assert_eq!(de.len(), 4);
1807    }
1808}