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