scc2/
hash_index.rs

1//! [`HashIndex`] is a read-optimized concurrent and asynchronous hash map.
2
3use super::ebr::{AtomicShared, Guard, Shared};
4use super::hash_table::bucket::{Bucket, EntryPtr, Locker, OPTIMISTIC};
5use super::hash_table::bucket_array::BucketArray;
6use super::hash_table::{HashTable, LockedEntry};
7use super::wait_queue::AsyncWait;
8use super::Equivalent;
9use std::collections::hash_map::RandomState;
10use std::fmt::{self, Debug};
11use std::hash::{BuildHasher, Hash};
12use std::iter::FusedIterator;
13use std::ops::{Deref, RangeInclusive};
14use std::panic::UnwindSafe;
15use std::pin::Pin;
16use std::ptr;
17use std::sync::atomic::AtomicUsize;
18use std::sync::atomic::Ordering::{Acquire, Relaxed};
19
20/// Scalable concurrent hash index.
21///
22/// [`HashIndex`] is a concurrent and asynchronous hash map data structure optimized for parallel
23/// read operations. The key characteristics of [`HashIndex`] are similar to that of
24/// [`HashMap`](super::HashMap) except its read operations are lock-free.
25///
26/// ## The key differences between [`HashIndex`] and [`HashMap`](crate::HashMap).
27///
28/// * Lock-free-read: read and scan operations are never blocked and do not modify shared data.
29/// * Immutability: the data in the container is immutable until it becomes unreachable.
30/// * Linearizability: linearizability of read operations relies on the CPU architecture.
31///
32/// ## The key statistics for [`HashIndex`]
33///
34/// * The expected size of metadata for a single key-value pair: 2-byte.
35/// * The expected number of atomic write operations required for an operation on a single key: 2.
36/// * The expected number of atomic variables accessed during a single key operation: 2.
37/// * The number of entries managed by a single bucket without a linked list: 32.
38/// * The expected maximum linked list length when resize is triggered: log(capacity) / 8.
39///
40/// ### Unwind safety
41///
42/// [`HashIndex`] is impervious to out-of-memory errors and panics in user-specified code on one
43/// condition; `H::Hasher::hash`, `K::drop` and `V::drop` must not panic.
44pub struct HashIndex<K, V, H = RandomState>
45where
46    H: BuildHasher,
47{
48    array: AtomicShared<BucketArray<K, V, (), OPTIMISTIC>>,
49    minimum_capacity: AtomicUsize,
50    build_hasher: H,
51}
52
53/// [`Entry`] represents a single entry in a [`HashIndex`].
54pub enum Entry<'h, K, V, H = RandomState>
55where
56    H: BuildHasher,
57{
58    /// An occupied entry.
59    Occupied(OccupiedEntry<'h, K, V, H>),
60
61    /// A vacant entry.
62    Vacant(VacantEntry<'h, K, V, H>),
63}
64
65/// [`OccupiedEntry`] is a view into an occupied entry in a [`HashIndex`].
66pub struct OccupiedEntry<'h, K, V, H = RandomState>
67where
68    H: BuildHasher,
69{
70    hashindex: &'h HashIndex<K, V, H>,
71    locked_entry: LockedEntry<'h, K, V, (), OPTIMISTIC>,
72}
73
74/// [`VacantEntry`] is a view into a vacant entry in a [`HashIndex`].
75pub struct VacantEntry<'h, K, V, H = RandomState>
76where
77    H: BuildHasher,
78{
79    hashindex: &'h HashIndex<K, V, H>,
80    key: K,
81    hash: u64,
82    locked_entry: LockedEntry<'h, K, V, (), OPTIMISTIC>,
83}
84
85/// [`Reserve`] keeps the capacity of the associated [`HashIndex`] higher than a certain level.
86///
87/// The [`HashIndex`] does not shrink the capacity below the reserved capacity.
88pub struct Reserve<'h, K, V, H = RandomState>
89where
90    K: 'static + Clone + Eq + Hash,
91    V: 'static + Clone,
92    H: BuildHasher,
93{
94    hashindex: &'h HashIndex<K, V, H>,
95    additional: usize,
96}
97
98/// An iterator over the entries of a [`HashIndex`].
99///
100/// An [`Iter`] iterates over all the entries that survive the [`Iter`].
101pub struct Iter<'h, 'g, K, V, H = RandomState>
102where
103    H: BuildHasher,
104{
105    hashindex: &'h HashIndex<K, V, H>,
106    current_array: Option<&'g BucketArray<K, V, (), OPTIMISTIC>>,
107    current_index: usize,
108    current_bucket: Option<&'g Bucket<K, V, (), OPTIMISTIC>>,
109    current_entry_ptr: EntryPtr<'g, K, V, OPTIMISTIC>,
110    guard: &'g Guard,
111}
112
113impl<K, V, H> HashIndex<K, V, H>
114where
115    H: BuildHasher,
116{
117    /// Creates an empty [`HashIndex`] with the given [`BuildHasher`].
118    ///
119    /// # Examples
120    ///
121    /// ```
122    /// use scc2::HashIndex;
123    /// use std::collections::hash_map::RandomState;
124    ///
125    /// let hashindex: HashIndex<u64, u32, RandomState> =
126    ///     HashIndex::with_hasher(RandomState::new());
127    /// ```
128    #[cfg(not(feature = "loom"))]
129    #[inline]
130    pub const fn with_hasher(build_hasher: H) -> Self {
131        Self {
132            array: AtomicShared::null(),
133            minimum_capacity: AtomicUsize::new(0),
134            build_hasher,
135        }
136    }
137
138    /// Creates an empty [`HashIndex`] with the given [`BuildHasher`].
139    #[cfg(feature = "loom")]
140    #[inline]
141    pub fn with_hasher(build_hasher: H) -> Self {
142        Self {
143            array: AtomicShared::null(),
144            minimum_capacity: AtomicUsize::new(0),
145            build_hasher,
146        }
147    }
148
149    /// Creates an empty [`HashIndex`] with the specified capacity and [`BuildHasher`].
150    ///
151    /// The actual capacity is equal to or greater than the specified capacity.
152    ///
153    /// # Examples
154    ///
155    /// ```
156    /// use scc2::HashIndex;
157    /// use std::collections::hash_map::RandomState;
158    ///
159    /// let hashindex: HashIndex<u64, u32, RandomState> =
160    ///     HashIndex::with_capacity_and_hasher(1000, RandomState::new());
161    ///
162    /// let result = hashindex.capacity();
163    /// assert_eq!(result, 1024);
164    /// ```
165    #[inline]
166    pub fn with_capacity_and_hasher(capacity: usize, build_hasher: H) -> Self {
167        let (array, minimum_capacity) = if capacity == 0 {
168            (AtomicShared::null(), AtomicUsize::new(0))
169        } else {
170            let array = unsafe {
171                Shared::new_unchecked(BucketArray::<K, V, (), OPTIMISTIC>::new(
172                    capacity,
173                    AtomicShared::null(),
174                ))
175            };
176            let minimum_capacity = array.num_entries();
177            (
178                AtomicShared::from(array),
179                AtomicUsize::new(minimum_capacity),
180            )
181        };
182        Self {
183            array,
184            minimum_capacity,
185            build_hasher,
186        }
187    }
188}
189
190impl<K, V, H> HashIndex<K, V, H>
191where
192    K: 'static + Clone + Eq + Hash,
193    V: 'static + Clone,
194    H: BuildHasher,
195{
196    /// Temporarily increases the minimum capacity of the [`HashIndex`].
197    ///
198    /// A [`Reserve`] is returned if the [`HashIndex`] could increase the minimum capacity while
199    /// the increased capacity is not exclusively owned by the returned [`Reserve`], allowing
200    /// others to benefit from it. The memory for the additional space may not be immediately
201    /// allocated if the [`HashIndex`] is empty or currently being resized, however once the memory
202    /// is reserved eventually, the capacity will not shrink below the additional capacity until
203    /// the returned [`Reserve`] is dropped.
204    ///
205    /// # Errors
206    ///
207    /// Returns `None` if a too large number is given.
208    ///
209    /// # Examples
210    ///
211    /// ```
212    /// use scc2::HashIndex;
213    ///
214    /// let hashindex: HashIndex<usize, usize> = HashIndex::with_capacity(1000);
215    /// assert_eq!(hashindex.capacity(), 1024);
216    ///
217    /// let reserved = hashindex.reserve(10000);
218    /// assert!(reserved.is_some());
219    /// assert_eq!(hashindex.capacity(), 16384);
220    ///
221    /// assert!(hashindex.reserve(usize::MAX).is_none());
222    /// assert_eq!(hashindex.capacity(), 16384);
223    ///
224    /// for i in 0..16 {
225    ///     assert!(hashindex.insert(i, i).is_ok());
226    /// }
227    /// drop(reserved);
228    ///
229    /// assert_eq!(hashindex.capacity(), 1024);
230    /// ```
231    #[inline]
232    pub fn reserve(&self, additional_capacity: usize) -> Option<Reserve<K, V, H>> {
233        let additional = self.reserve_capacity(additional_capacity);
234        if additional == 0 {
235            None
236        } else {
237            Some(Reserve {
238                hashindex: self,
239                additional,
240            })
241        }
242    }
243
244    /// Gets the entry associated with the given key in the map for in-place manipulation.
245    ///
246    /// # Examples
247    ///
248    /// ```
249    /// use scc2::HashIndex;
250    ///
251    /// let hashindex: HashIndex<char, u32> = HashIndex::default();
252    ///
253    /// for ch in "a short treatise on fungi".chars() {
254    ///     unsafe {
255    ///         hashindex.entry(ch).and_modify(|counter| *counter += 1).or_insert(1);
256    ///     }
257    /// }
258    ///
259    /// assert_eq!(hashindex.peek_with(&'s', |_, v| *v), Some(2));
260    /// assert_eq!(hashindex.peek_with(&'t', |_, v| *v), Some(3));
261    /// assert!(hashindex.peek_with(&'y', |_, v| *v).is_none());
262    /// ```
263    #[inline]
264    pub fn entry(&self, key: K) -> Entry<K, V, H> {
265        let guard = Guard::new();
266        let hash = self.hash(&key);
267        let locked_entry = unsafe {
268            self.reserve_entry(&key, hash, &mut (), self.prolonged_guard_ref(&guard))
269                .ok()
270                .unwrap_unchecked()
271        };
272        if locked_entry.entry_ptr.is_valid() {
273            Entry::Occupied(OccupiedEntry {
274                hashindex: self,
275                locked_entry,
276            })
277        } else {
278            Entry::Vacant(VacantEntry {
279                hashindex: self,
280                key,
281                hash,
282                locked_entry,
283            })
284        }
285    }
286
287    /// Gets the entry associated with the given key in the map for in-place manipulation.
288    ///
289    /// It is an asynchronous method returning an `impl Future` for the caller to await.
290    ///
291    /// # Examples
292    ///
293    /// ```
294    /// use scc2::HashIndex;
295    ///
296    /// let hashindex: HashIndex<char, u32> = HashIndex::default();
297    ///
298    /// let future_entry = hashindex.entry_async('b');
299    /// ```
300    #[inline]
301    pub async fn entry_async(&self, key: K) -> Entry<K, V, H> {
302        let hash = self.hash(&key);
303        loop {
304            let mut async_wait = AsyncWait::default();
305            let mut async_wait_pinned = Pin::new(&mut async_wait);
306            {
307                let guard = Guard::new();
308                if let Ok(locked_entry) = self.reserve_entry(
309                    &key,
310                    hash,
311                    &mut async_wait_pinned,
312                    self.prolonged_guard_ref(&guard),
313                ) {
314                    if locked_entry.entry_ptr.is_valid() {
315                        return Entry::Occupied(OccupiedEntry {
316                            hashindex: self,
317                            locked_entry,
318                        });
319                    }
320                    return Entry::Vacant(VacantEntry {
321                        hashindex: self,
322                        key,
323                        hash,
324                        locked_entry,
325                    });
326                }
327            }
328            async_wait_pinned.await;
329        }
330    }
331
332    /// Gets the first occupied entry for in-place manipulation.
333    ///
334    /// The returned [`OccupiedEntry`] in combination with [`OccupiedEntry::next`] or
335    /// [`OccupiedEntry::next_async`] can act as a mutable iterator over entries.
336    ///
337    /// # Examples
338    ///
339    /// ```
340    /// use scc2::HashIndex;
341    ///
342    /// let hashindex: HashIndex<u64, u32> = HashIndex::default();
343    ///
344    /// assert!(hashindex.insert(1, 0).is_ok());
345    ///
346    /// let mut first_entry = hashindex.first_entry().unwrap();
347    /// unsafe {
348    ///     *first_entry.get_mut() = 2;
349    /// }
350    ///
351    /// assert!(first_entry.next().is_none());
352    /// assert_eq!(hashindex.peek_with(&1, |_, v| *v), Some(2));
353    /// ```
354    #[inline]
355    pub fn first_entry(&self) -> Option<OccupiedEntry<K, V, H>> {
356        let guard = Guard::new();
357        let prolonged_guard = self.prolonged_guard_ref(&guard);
358        if let Some(locked_entry) = self.lock_first_entry(prolonged_guard) {
359            return Some(OccupiedEntry {
360                hashindex: self,
361                locked_entry,
362            });
363        }
364        None
365    }
366
367    /// Gets the first occupied entry for in-place manipulation.
368    ///
369    /// The returned [`OccupiedEntry`] in combination with [`OccupiedEntry::next`] or
370    /// [`OccupiedEntry::next_async`] can act as a mutable iterator over entries.
371    ///
372    /// It is an asynchronous method returning an `impl Future` for the caller to await.
373    ///
374    /// # Examples
375    ///
376    /// ```
377    /// use scc2::HashIndex;
378    ///
379    /// let hashindex: HashIndex<char, u32> = HashIndex::default();
380    ///
381    /// let future_entry = hashindex.first_entry_async();
382    /// ```
383    #[inline]
384    pub async fn first_entry_async(&self) -> Option<OccupiedEntry<K, V, H>> {
385        if let Some(locked_entry) = LockedEntry::first_entry_async(self).await {
386            return Some(OccupiedEntry {
387                hashindex: self,
388                locked_entry,
389            });
390        }
391        None
392    }
393
394    /// Finds any entry satisfying the supplied predicate for in-place manipulation.
395    ///
396    /// The returned [`OccupiedEntry`] in combination with [`OccupiedEntry::next`] or
397    /// [`OccupiedEntry::next_async`] can act as a mutable iterator over entries.
398    ///
399    /// # Examples
400    ///
401    /// ```
402    /// use scc2::HashIndex;
403    ///
404    /// let hashindex: HashIndex<u64, u32> = HashIndex::default();
405    ///
406    /// assert!(hashindex.insert(1, 0).is_ok());
407    /// assert!(hashindex.insert(2, 3).is_ok());
408    ///
409    /// let mut entry = hashindex.any_entry(|k, _| *k == 2).unwrap();
410    /// assert_eq!(*entry.get(), 3);
411    /// ```
412    #[inline]
413    pub fn any_entry<P: FnMut(&K, &V) -> bool>(&self, pred: P) -> Option<OccupiedEntry<K, V, H>> {
414        let guard = Guard::new();
415        let prolonged_guard = self.prolonged_guard_ref(&guard);
416        let locked_entry = self.find_entry(pred, prolonged_guard)?;
417        Some(OccupiedEntry {
418            hashindex: self,
419            locked_entry,
420        })
421    }
422
423    /// Finds any entry satisfying the supplied predicate for in-place manipulation.
424    ///
425    /// The returned [`OccupiedEntry`] in combination with [`OccupiedEntry::next`] or
426    /// [`OccupiedEntry::next_async`] can act as a mutable iterator over entries.
427    ///
428    /// It is an asynchronous method returning an `impl Future` for the caller to await.
429    ///
430    /// # Examples
431    ///
432    /// ```
433    /// use scc2::HashIndex;
434    ///
435    /// let hashindex: HashIndex<u64, u32> = HashIndex::default();
436    ///
437    /// let future_entry = hashindex.any_entry_async(|k, _| *k == 2);
438    /// ```
439    #[inline]
440    pub async fn any_entry_async<P: FnMut(&K, &V) -> bool>(
441        &self,
442        mut pred: P,
443    ) -> Option<OccupiedEntry<K, V, H>> {
444        if let Some(locked_entry) = LockedEntry::first_entry_async(self).await {
445            let mut entry = OccupiedEntry {
446                hashindex: self,
447                locked_entry,
448            };
449            loop {
450                if pred(entry.key(), entry.get()) {
451                    return Some(entry);
452                }
453                entry = entry.next()?;
454            }
455        }
456        None
457    }
458
459    /// Inserts a key-value pair into the [`HashIndex`].
460    ///
461    /// # Errors
462    ///
463    /// Returns an error along with the supplied key-value pair if the key exists.
464    ///
465    /// # Examples
466    ///
467    /// ```
468    /// use scc2::HashIndex;
469    ///
470    /// let hashindex: HashIndex<u64, u32> = HashIndex::default();
471    ///
472    /// assert!(hashindex.insert(1, 0).is_ok());
473    /// assert_eq!(hashindex.insert(1, 1).unwrap_err(), (1, 1));
474    /// ```
475    #[inline]
476    pub fn insert(&self, key: K, val: V) -> Result<(), (K, V)> {
477        let guard = Guard::new();
478        let hash = self.hash(&key);
479        if let Ok(Some((k, v))) = self.insert_entry(key, val, hash, &mut (), &guard) {
480            Err((k, v))
481        } else {
482            Ok(())
483        }
484    }
485
486    /// Inserts a key-value pair into the [`HashIndex`].
487    ///
488    /// It is an asynchronous method returning an `impl Future` for the caller to await.
489    ///
490    /// # Errors
491    ///
492    /// Returns an error along with the supplied key-value pair if the key exists.
493    ///
494    /// # Examples
495    ///
496    /// ```
497    /// use scc2::HashIndex;
498    ///
499    /// let hashindex: HashIndex<u64, u32> = HashIndex::default();
500    /// let future_insert = hashindex.insert_async(11, 17);
501    /// ```
502    #[inline]
503    pub async fn insert_async(&self, mut key: K, mut val: V) -> Result<(), (K, V)> {
504        let hash = self.hash(&key);
505        loop {
506            let mut async_wait = AsyncWait::default();
507            let mut async_wait_pinned = Pin::new(&mut async_wait);
508            match self.insert_entry(key, val, hash, &mut async_wait_pinned, &Guard::new()) {
509                Ok(Some(returned)) => return Err(returned),
510                Ok(None) => return Ok(()),
511                Err(returned) => {
512                    key = returned.0;
513                    val = returned.1;
514                }
515            }
516            async_wait_pinned.await;
517        }
518    }
519
520    /// Removes a key-value pair if the key exists.
521    ///
522    /// Returns `false` if the key does not exist.
523    ///
524    /// Returns `true` if the key existed and the condition was met after marking the entry
525    /// unreachable; the memory will be reclaimed later.
526    ///
527    /// # Examples
528    ///
529    /// ```
530    /// use scc2::HashIndex;
531    ///
532    /// let hashindex: HashIndex<u64, u32> = HashIndex::default();
533    ///
534    /// assert!(!hashindex.remove(&1));
535    /// assert!(hashindex.insert(1, 0).is_ok());
536    /// assert!(hashindex.remove(&1));
537    /// ```
538    #[inline]
539    pub fn remove<Q>(&self, key: &Q) -> bool
540    where
541        Q: Equivalent<K> + Hash + ?Sized,
542    {
543        self.remove_if(key, |_| true)
544    }
545
546    /// Removes a key-value pair if the key exists.
547    ///
548    /// Returns `false` if the key does not exist. It is an asynchronous method returning an
549    /// `impl Future` for the caller to await.
550    ///
551    /// Returns `true` if the key existed and the condition was met after marking the entry
552    /// unreachable; the memory will be reclaimed later.
553    ///
554    /// # Examples
555    ///
556    /// ```
557    /// use scc2::HashIndex;
558    ///
559    /// let hashindex: HashIndex<u64, u32> = HashIndex::default();
560    /// let future_insert = hashindex.insert_async(11, 17);
561    /// let future_remove = hashindex.remove_async(&11);
562    /// ```
563    #[inline]
564    pub async fn remove_async<Q>(&self, key: &Q) -> bool
565    where
566        Q: Equivalent<K> + Hash + ?Sized,
567    {
568        self.remove_if_async(key, |_| true).await
569    }
570
571    /// Removes a key-value pair if the key exists and the given condition is met.
572    ///
573    /// Returns `false` if the key does not exist or the condition was not met.
574    ///
575    /// Returns `true` if the key existed and the condition was met after marking the entry
576    /// unreachable; the memory will be reclaimed later.
577    ///
578    /// # Examples
579    ///
580    /// ```
581    /// use scc2::HashIndex;
582    ///
583    /// let hashindex: HashIndex<u64, u32> = HashIndex::default();
584    ///
585    /// assert!(hashindex.insert(1, 0).is_ok());
586    /// assert!(!hashindex.remove_if(&1, |v| *v == 1));
587    /// assert!(hashindex.remove_if(&1, |v| *v == 0));
588    /// ```
589    #[inline]
590    pub fn remove_if<Q, F: FnOnce(&V) -> bool>(&self, key: &Q, condition: F) -> bool
591    where
592        Q: Equivalent<K> + Hash + ?Sized,
593    {
594        self.remove_entry(
595            key,
596            self.hash(key),
597            |v: &mut V| condition(v),
598            |r| r.is_some(),
599            &mut (),
600            &Guard::new(),
601        )
602        .ok()
603        .map_or(false, |r| r)
604    }
605
606    /// Removes a key-value pair if the key exists and the given condition is met.
607    ///
608    /// Returns `false` if the key does not exist or the condition was not met. It is an
609    /// asynchronous method returning an `impl Future` for the caller to await.
610    ///
611    /// Returns `true` if the key existed and the condition was met after marking the entry
612    /// unreachable; the memory will be reclaimed later.
613    ///
614    /// # Examples
615    ///
616    /// ```
617    /// use scc2::HashIndex;
618    ///
619    /// let hashindex: HashIndex<u64, u32> = HashIndex::default();
620    /// let future_insert = hashindex.insert_async(11, 17);
621    /// let future_remove = hashindex.remove_if_async(&11, |_| true);
622    /// ```
623    #[inline]
624    pub async fn remove_if_async<Q, F: FnOnce(&V) -> bool>(&self, key: &Q, condition: F) -> bool
625    where
626        Q: Equivalent<K> + Hash + ?Sized,
627    {
628        let hash = self.hash(key);
629        let mut condition = |v: &mut V| condition(v);
630        loop {
631            let mut async_wait = AsyncWait::default();
632            let mut async_wait_pinned = Pin::new(&mut async_wait);
633            match self.remove_entry(
634                key,
635                hash,
636                condition,
637                |r| r.is_some(),
638                &mut async_wait_pinned,
639                &Guard::new(),
640            ) {
641                Ok(r) => return r,
642                Err(c) => condition = c,
643            }
644            async_wait_pinned.await;
645        }
646    }
647
648    /// Gets an [`OccupiedEntry`] corresponding to the key for in-place modification.
649    ///
650    /// [`OccupiedEntry`] exclusively owns the entry, preventing others from gaining access to it:
651    /// use [`peek`](Self::peek) if read-only access is sufficient.
652    ///
653    /// Returns `None` if the key does not exist.
654    ///
655    /// # Examples
656    ///
657    /// ```
658    /// use scc2::HashIndex;
659    ///
660    /// let hashindex: HashIndex<u64, u32> = HashIndex::default();
661    ///
662    /// assert!(hashindex.get(&1).is_none());
663    /// assert!(hashindex.insert(1, 10).is_ok());
664    /// assert_eq!(*hashindex.get(&1).unwrap().get(), 10);
665    /// assert_eq!(*hashindex.get(&1).unwrap(), 10);
666    /// ```
667    #[inline]
668    pub fn get<Q>(&self, key: &Q) -> Option<OccupiedEntry<K, V, H>>
669    where
670        Q: Equivalent<K> + Hash + ?Sized,
671    {
672        let guard = Guard::new();
673        let locked_entry = self
674            .get_entry(
675                key,
676                self.hash(key),
677                &mut (),
678                self.prolonged_guard_ref(&guard),
679            )
680            .ok()
681            .flatten()?;
682        Some(OccupiedEntry {
683            hashindex: self,
684            locked_entry,
685        })
686    }
687
688    /// Gets an [`OccupiedEntry`] corresponding to the key for in-place modification.
689    ///
690    /// [`OccupiedEntry`] exclusively owns the entry, preventing others from gaining access to it:
691    /// use [`peek`](Self::peek) if read-only access is sufficient.
692    ///
693    /// Returns `None` if the key does not exist. It is an asynchronous method returning an
694    /// `impl Future` for the caller to await.
695    ///
696    /// # Examples
697    ///
698    /// ```
699    /// use scc2::HashIndex;
700    ///
701    /// let hashindex: HashIndex<u64, u32> = HashIndex::default();
702    /// let future_insert = hashindex.insert_async(11, 17);
703    /// let future_get = hashindex.get_async(&11);
704    /// ```
705    #[inline]
706    pub async fn get_async<Q>(&self, key: &Q) -> Option<OccupiedEntry<K, V, H>>
707    where
708        Q: Equivalent<K> + Hash + ?Sized,
709    {
710        let hash = self.hash(key);
711        loop {
712            let mut async_wait = AsyncWait::default();
713            let mut async_wait_pinned = Pin::new(&mut async_wait);
714            if let Ok(result) = self.get_entry(
715                key,
716                hash,
717                &mut async_wait_pinned,
718                self.prolonged_guard_ref(&Guard::new()),
719            ) {
720                if let Some(locked_entry) = result {
721                    return Some(OccupiedEntry {
722                        hashindex: self,
723                        locked_entry,
724                    });
725                }
726                return None;
727            }
728            async_wait_pinned.await;
729        }
730    }
731
732    /// Returns a guarded reference to the value for the specified key without acquiring locks.
733    ///
734    /// Returns `None` if the key does not exist. The returned reference can survive as long as the
735    /// associated [`Guard`] is alive.
736    ///
737    /// # Examples
738    ///
739    /// ```
740    /// use scc2::ebr::Guard;
741    /// use scc2::HashIndex;
742    ///
743    /// let hashindex: HashIndex<u64, u32> = HashIndex::default();
744    ///
745    /// assert!(hashindex.insert(1, 10).is_ok());
746    ///
747    /// let guard = Guard::new();
748    /// let value_ref = hashindex.peek(&1, &guard).unwrap();
749    /// assert_eq!(*value_ref, 10);
750    /// ```
751    #[inline]
752    pub fn peek<'g, Q>(&self, key: &Q, guard: &'g Guard) -> Option<&'g V>
753    where
754        Q: Equivalent<K> + Hash + ?Sized,
755    {
756        self.peek_entry(key, self.hash(key), guard).map(|(_, v)| v)
757    }
758
759    /// Peeks a key-value pair without acquiring locks.
760    ///
761    /// Returns `None` if the key does not exist.
762    ///
763    /// # Examples
764    ///
765    /// ```
766    /// use scc2::HashIndex;
767    ///
768    /// let hashindex: HashIndex<u64, u32> = HashIndex::default();
769    ///
770    /// assert!(hashindex.peek_with(&1, |_, v| *v).is_none());
771    /// assert!(hashindex.insert(1, 10).is_ok());
772    /// assert_eq!(hashindex.peek_with(&1, |_, v| *v).unwrap(), 10);
773    /// ```
774    #[inline]
775    pub fn peek_with<Q, R, F: FnOnce(&K, &V) -> R>(&self, key: &Q, reader: F) -> Option<R>
776    where
777        Q: Equivalent<K> + Hash + ?Sized,
778    {
779        let guard = Guard::new();
780        self.peek_entry(key, self.hash(key), &guard)
781            .map(|(k, v)| reader(k, v))
782    }
783
784    /// Returns `true` if the [`HashIndex`] contains a value for the specified key.
785    ///
786    /// # Examples
787    ///
788    /// ```
789    /// use scc2::HashIndex;
790    ///
791    /// let hashindex: HashIndex<u64, u32> = HashIndex::default();
792    ///
793    /// assert!(!hashindex.contains(&1));
794    /// assert!(hashindex.insert(1, 0).is_ok());
795    /// assert!(hashindex.contains(&1));
796    /// ```
797    #[inline]
798    pub fn contains<Q>(&self, key: &Q) -> bool
799    where
800        Q: Equivalent<K> + Hash + ?Sized,
801    {
802        self.peek_with(key, |_, _| ()).is_some()
803    }
804
805    /// Retains the entries specified by the predicate.
806    ///
807    /// Entries that have existed since the invocation of the method are guaranteed to be visited
808    /// if they are not removed, however the same entry can be visited more than once if the
809    /// [`HashIndex`] gets resized by another thread.
810    ///
811    /// # Examples
812    ///
813    /// ```
814    /// use scc2::HashIndex;
815    ///
816    /// let hashindex: HashIndex<u64, u32> = HashIndex::default();
817    ///
818    /// assert!(hashindex.insert(1, 0).is_ok());
819    /// assert!(hashindex.insert(2, 1).is_ok());
820    /// assert!(hashindex.insert(3, 2).is_ok());
821    ///
822    /// hashindex.retain(|k, v| *k == 1 && *v == 0);
823    ///
824    /// assert!(hashindex.contains(&1));
825    /// assert!(!hashindex.contains(&2));
826    /// assert!(!hashindex.contains(&3));
827    /// ```
828    #[inline]
829    pub fn retain<F: FnMut(&K, &V) -> bool>(&self, mut pred: F) {
830        self.retain_entries(|k, v| pred(k, v));
831    }
832
833    /// Retains the entries specified by the predicate.
834    ///
835    /// Entries that have existed since the invocation of the method are guaranteed to be visited
836    /// if they are not removed, however the same entry can be visited more than once if the
837    /// [`HashIndex`] gets resized by another thread.
838    ///
839    /// It is an asynchronous method returning an `impl Future` for the caller to await.
840    ///
841    /// # Examples
842    ///
843    /// ```
844    /// use scc2::HashIndex;
845    ///
846    /// let hashindex: HashIndex<u64, u32> = HashIndex::default();
847    ///
848    /// let future_insert = hashindex.insert_async(1, 0);
849    /// let future_retain = hashindex.retain_async(|k, v| *k == 1);
850    /// ```
851    #[inline]
852    pub async fn retain_async<F: FnMut(&K, &V) -> bool>(&self, mut pred: F) {
853        let mut removed = false;
854        let mut current_array_holder = self.array.get_shared(Acquire, &Guard::new());
855        while let Some(current_array) = current_array_holder.take() {
856            self.cleanse_old_array_async(&current_array).await;
857            for index in 0..current_array.num_buckets() {
858                loop {
859                    let mut async_wait = AsyncWait::default();
860                    let mut async_wait_pinned = Pin::new(&mut async_wait);
861                    {
862                        let guard = Guard::new();
863                        let bucket = current_array.bucket_mut(index);
864                        if let Ok(locker) =
865                            Locker::try_lock_or_wait(bucket, &mut async_wait_pinned, &guard)
866                        {
867                            if let Some(mut locker) = locker {
868                                let data_block_mut = current_array.data_block_mut(index);
869                                let mut entry_ptr = EntryPtr::new(&guard);
870                                while entry_ptr.move_to_next(&locker, &guard) {
871                                    let (k, v) = entry_ptr.get(data_block_mut);
872                                    if !pred(k, v) {
873                                        locker.mark_removed(&mut entry_ptr, &guard);
874                                        removed = true;
875                                    }
876                                }
877                            }
878                            break;
879                        };
880                    }
881                    async_wait_pinned.await;
882                }
883            }
884
885            if let Some(new_current_array) = self.array.get_shared(Acquire, &Guard::new()) {
886                if new_current_array.as_ptr() == current_array.as_ptr() {
887                    break;
888                }
889                current_array_holder.replace(new_current_array);
890                continue;
891            }
892            break;
893        }
894
895        if removed {
896            self.try_resize(0, &Guard::new());
897        }
898    }
899
900    /// Clears the [`HashIndex`] by removing all key-value pairs.
901    ///
902    /// # Examples
903    ///
904    /// ```
905    /// use scc2::HashIndex;
906    ///
907    /// let hashindex: HashIndex<u64, u32> = HashIndex::default();
908    ///
909    /// assert!(hashindex.insert(1, 0).is_ok());
910    /// hashindex.clear();
911    ///
912    /// assert!(!hashindex.contains(&1));
913    /// ```
914    pub fn clear(&self) {
915        self.retain(|_, _| false);
916    }
917
918    /// Clears the [`HashIndex`] by removing all key-value pairs.
919    ///
920    /// It is an asynchronous method returning an `impl Future` for the caller to await.
921    ///
922    /// # Examples
923    ///
924    /// ```
925    /// use scc2::HashIndex;
926    ///
927    /// let hashindex: HashIndex<u64, u32> = HashIndex::default();
928    ///
929    /// let future_insert = hashindex.insert_async(1, 0);
930    /// let future_retain = hashindex.clear_async();
931    /// ```
932    pub async fn clear_async(&self) {
933        self.retain_async(|_, _| false).await;
934    }
935
936    /// Returns the number of entries in the [`HashIndex`].
937    ///
938    /// It reads the entire metadata area of the bucket array to calculate the number of valid
939    /// entries, making its time complexity `O(N)`. Furthermore, it may overcount entries if an old
940    /// bucket array has yet to be dropped.
941    ///
942    /// # Examples
943    ///
944    /// ```
945    /// use scc2::HashIndex;
946    ///
947    /// let hashindex: HashIndex<u64, u32> = HashIndex::default();
948    ///
949    /// assert!(hashindex.insert(1, 0).is_ok());
950    /// assert_eq!(hashindex.len(), 1);
951    /// ```
952    #[inline]
953    pub fn len(&self) -> usize {
954        self.num_entries(&Guard::new())
955    }
956
957    /// Returns `true` if the [`HashIndex`] is empty.
958    ///
959    /// # Examples
960    ///
961    /// ```
962    /// use scc2::HashIndex;
963    ///
964    /// let hashindex: HashIndex<u64, u32> = HashIndex::default();
965    ///
966    /// assert!(hashindex.is_empty());
967    /// assert!(hashindex.insert(1, 0).is_ok());
968    /// assert!(!hashindex.is_empty());
969    /// ```
970    #[inline]
971    pub fn is_empty(&self) -> bool {
972        !self.has_entry(&Guard::new())
973    }
974
975    /// Returns the capacity of the [`HashIndex`].
976    ///
977    /// # Examples
978    ///
979    /// ```
980    /// use scc2::HashIndex;
981    ///
982    /// let hashindex_default: HashIndex<u64, u32> = HashIndex::default();
983    /// assert_eq!(hashindex_default.capacity(), 0);
984    ///
985    /// assert!(hashindex_default.insert(1, 0).is_ok());
986    /// assert_eq!(hashindex_default.capacity(), 64);
987    ///
988    /// let hashindex: HashIndex<u64, u32> = HashIndex::with_capacity(1000);
989    /// assert_eq!(hashindex.capacity(), 1024);
990    /// ```
991    #[inline]
992    pub fn capacity(&self) -> usize {
993        self.num_slots(&Guard::new())
994    }
995
996    /// Returns the current capacity range of the [`HashIndex`].
997    ///
998    /// # Examples
999    ///
1000    /// ```
1001    /// use scc2::HashIndex;
1002    ///
1003    /// let hashindex: HashIndex<u64, u32> = HashIndex::default();
1004    ///
1005    /// assert_eq!(hashindex.capacity_range(), 0..=(1_usize << (usize::BITS - 1)));
1006    ///
1007    /// let reserved = hashindex.reserve(1000);
1008    /// assert_eq!(hashindex.capacity_range(), 1000..=(1_usize << (usize::BITS - 1)));
1009    /// ```
1010    #[inline]
1011    pub fn capacity_range(&self) -> RangeInclusive<usize> {
1012        self.minimum_capacity.load(Relaxed)..=self.maximum_capacity()
1013    }
1014
1015    /// Returns the index of the bucket that may contain the key.
1016    ///
1017    /// The method returns the index of the bucket associated with the key. The number of buckets
1018    /// can be calculated by dividing `32` into the capacity.
1019    ///
1020    /// # Examples
1021    ///
1022    /// ```
1023    /// use scc2::HashIndex;
1024    ///
1025    /// let hashindex: HashIndex<u64, u32> = HashIndex::with_capacity(1024);
1026    ///
1027    /// let bucket_index = hashindex.bucket_index(&11);
1028    /// assert!(bucket_index < hashindex.capacity() / 32);
1029    /// ```
1030    #[inline]
1031    pub fn bucket_index<Q>(&self, key: &Q) -> usize
1032    where
1033        Q: Equivalent<K> + Hash + ?Sized,
1034    {
1035        self.calculate_bucket_index(key)
1036    }
1037
1038    /// Returns an [`Iter`].
1039    ///
1040    /// It is guaranteed to go through all the key-value pairs pertaining in the [`HashIndex`]
1041    /// at the moment, however the same key-value pair can be visited more than once if the
1042    /// [`HashIndex`] is being resized.
1043    ///
1044    /// It requires the user to supply a reference to a [`Guard`].
1045    ///
1046    /// # Examples
1047    ///
1048    /// ```
1049    /// use scc2::ebr::Guard;
1050    /// use scc2::HashIndex;
1051    ///
1052    /// let hashindex: HashIndex<u64, u32> = HashIndex::default();
1053    ///
1054    /// assert!(hashindex.insert(1, 0).is_ok());
1055    ///
1056    /// let guard = Guard::new();
1057    ///
1058    /// let mut iter = hashindex.iter(&guard);
1059    /// let entry_ref = iter.next().unwrap();
1060    /// assert_eq!(iter.next(), None);
1061    ///
1062    /// for iter in hashindex.iter(&guard) {
1063    ///     assert_eq!(iter, (&1, &0));
1064    /// }
1065    ///
1066    /// drop(hashindex);
1067    ///
1068    /// assert_eq!(entry_ref, (&1, &0));
1069    /// ```
1070    #[inline]
1071    pub fn iter<'h, 'g>(&'h self, guard: &'g Guard) -> Iter<'h, 'g, K, V, H> {
1072        Iter {
1073            hashindex: self,
1074            current_array: None,
1075            current_index: 0,
1076            current_bucket: None,
1077            current_entry_ptr: EntryPtr::new(guard),
1078            guard,
1079        }
1080    }
1081
1082    /// Clears the old array asynchronously.
1083    async fn cleanse_old_array_async(&self, current_array: &BucketArray<K, V, (), OPTIMISTIC>) {
1084        while current_array.has_old_array() {
1085            let mut async_wait = AsyncWait::default();
1086            let mut async_wait_pinned = Pin::new(&mut async_wait);
1087            if self.incremental_rehash::<K, _, false>(
1088                current_array,
1089                &mut async_wait_pinned,
1090                &Guard::new(),
1091            ) == Ok(true)
1092            {
1093                break;
1094            }
1095            async_wait_pinned.await;
1096        }
1097    }
1098}
1099
1100impl<K, V, H> Clone for HashIndex<K, V, H>
1101where
1102    K: 'static + Clone + Eq + Hash,
1103    V: 'static + Clone,
1104    H: BuildHasher + Clone,
1105{
1106    #[inline]
1107    fn clone(&self) -> Self {
1108        let self_clone = Self::with_capacity_and_hasher(self.capacity(), self.hasher().clone());
1109        for (k, v) in self.iter(&Guard::new()) {
1110            let _reuslt = self_clone.insert(k.clone(), v.clone());
1111        }
1112        self_clone
1113    }
1114}
1115
1116impl<K, V, H> Debug for HashIndex<K, V, H>
1117where
1118    K: 'static + Clone + Debug + Eq + Hash,
1119    V: 'static + Clone + Debug,
1120    H: BuildHasher,
1121{
1122    #[inline]
1123    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1124        let guard = Guard::new();
1125        f.debug_map().entries(self.iter(&guard)).finish()
1126    }
1127}
1128
1129impl<K, V> HashIndex<K, V, RandomState>
1130where
1131    K: 'static + Clone + Eq + Hash,
1132    V: 'static + Clone,
1133{
1134    /// Creates an empty default [`HashIndex`].
1135    ///
1136    /// # Examples
1137    ///
1138    /// ```
1139    /// use scc2::HashIndex;
1140    ///
1141    /// let hashindex: HashIndex<u64, u32> = HashIndex::new();
1142    ///
1143    /// let result = hashindex.capacity();
1144    /// assert_eq!(result, 0);
1145    /// ```
1146    #[inline]
1147    #[must_use]
1148    pub fn new() -> Self {
1149        Self::default()
1150    }
1151
1152    /// Creates an empty [`HashIndex`] with the specified capacity.
1153    ///
1154    /// The actual capacity is equal to or greater than the specified capacity.
1155    ///
1156    /// # Examples
1157    ///
1158    /// ```
1159    /// use scc2::HashIndex;
1160    ///
1161    /// let hashindex: HashIndex<u64, u32> = HashIndex::with_capacity(1000);
1162    ///
1163    /// let result = hashindex.capacity();
1164    /// assert_eq!(result, 1024);
1165    /// ```
1166    #[inline]
1167    #[must_use]
1168    pub fn with_capacity(capacity: usize) -> Self {
1169        Self::with_capacity_and_hasher(capacity, RandomState::new())
1170    }
1171}
1172
1173impl<K, V, H> Default for HashIndex<K, V, H>
1174where
1175    K: 'static,
1176    V: 'static,
1177    H: BuildHasher + Default,
1178{
1179    /// Creates an empty default [`HashIndex`].
1180    ///
1181    /// The default capacity is `64`.
1182    ///
1183    /// # Examples
1184    ///
1185    /// ```
1186    /// use scc2::HashIndex;
1187    ///
1188    /// let hashindex: HashIndex<u64, u32> = HashIndex::default();
1189    ///
1190    /// let result = hashindex.capacity();
1191    /// assert_eq!(result, 0);
1192    /// ```
1193    #[inline]
1194    fn default() -> Self {
1195        Self::with_hasher(H::default())
1196    }
1197}
1198
1199impl<K, V, H> FromIterator<(K, V)> for HashIndex<K, V, H>
1200where
1201    K: 'static + Clone + Eq + Hash,
1202    V: 'static + Clone,
1203    H: BuildHasher + Default,
1204{
1205    #[inline]
1206    fn from_iter<T: IntoIterator<Item = (K, V)>>(iter: T) -> Self {
1207        let into_iter = iter.into_iter();
1208        let hashindex = Self::with_capacity_and_hasher(
1209            Self::capacity_from_size_hint(into_iter.size_hint()),
1210            H::default(),
1211        );
1212        into_iter.for_each(|e| {
1213            let _result = hashindex.insert(e.0, e.1);
1214        });
1215        hashindex
1216    }
1217}
1218
1219impl<K, V, H> HashTable<K, V, H, (), OPTIMISTIC> for HashIndex<K, V, H>
1220where
1221    K: 'static + Clone + Eq + Hash,
1222    V: 'static + Clone,
1223    H: BuildHasher,
1224{
1225    #[inline]
1226    fn hasher(&self) -> &H {
1227        &self.build_hasher
1228    }
1229    #[inline]
1230    fn try_clone(entry: &(K, V)) -> Option<(K, V)> {
1231        Some((entry.0.clone(), entry.1.clone()))
1232    }
1233    #[inline]
1234    fn bucket_array(&self) -> &AtomicShared<BucketArray<K, V, (), OPTIMISTIC>> {
1235        &self.array
1236    }
1237    #[inline]
1238    fn minimum_capacity(&self) -> &AtomicUsize {
1239        &self.minimum_capacity
1240    }
1241    #[inline]
1242    fn maximum_capacity(&self) -> usize {
1243        1_usize << (usize::BITS - 1)
1244    }
1245}
1246
1247impl<K, V, H> PartialEq for HashIndex<K, V, H>
1248where
1249    K: 'static + Clone + Eq + Hash,
1250    V: 'static + Clone + PartialEq,
1251    H: BuildHasher,
1252{
1253    #[inline]
1254    fn eq(&self, other: &Self) -> bool {
1255        let guard = Guard::new();
1256        if !self
1257            .iter(&guard)
1258            .any(|(k, v)| other.peek_with(k, |_, ov| v == ov) != Some(true))
1259        {
1260            return !other
1261                .iter(&guard)
1262                .any(|(k, v)| self.peek_with(k, |_, sv| v == sv) != Some(true));
1263        }
1264        false
1265    }
1266}
1267
1268impl<'h, K, V, H> Entry<'h, K, V, H>
1269where
1270    K: 'static + Clone + Eq + Hash,
1271    V: 'static + Clone,
1272    H: BuildHasher,
1273{
1274    /// Ensures a value is in the entry by inserting the supplied instance if empty.
1275    ///
1276    /// # Examples
1277    ///
1278    /// ```
1279    /// use scc2::HashIndex;
1280    ///
1281    /// let hashindex: HashIndex<u64, u32> = HashIndex::default();
1282    ///
1283    /// hashindex.entry(3).or_insert(7);
1284    /// assert_eq!(hashindex.peek_with(&3, |_, v| *v), Some(7));
1285    /// ```
1286    #[inline]
1287    pub fn or_insert(self, val: V) -> OccupiedEntry<'h, K, V, H> {
1288        self.or_insert_with(|| val)
1289    }
1290
1291    /// Ensures a value is in the entry by inserting the result of the supplied closure if empty.
1292    ///
1293    /// # Examples
1294    ///
1295    /// ```
1296    /// use scc2::HashIndex;
1297    ///
1298    /// let hashindex: HashIndex<u64, u32> = HashIndex::default();
1299    ///
1300    /// hashindex.entry(19).or_insert_with(|| 5);
1301    /// assert_eq!(hashindex.peek_with(&19, |_, v| *v), Some(5));
1302    /// ```
1303    #[inline]
1304    pub fn or_insert_with<F: FnOnce() -> V>(self, constructor: F) -> OccupiedEntry<'h, K, V, H> {
1305        self.or_insert_with_key(|_| constructor())
1306    }
1307
1308    /// Ensures a value is in the entry by inserting the result of the supplied closure if empty.
1309    ///
1310    /// The reference to the moved key is provided, therefore cloning or copying the key is
1311    /// unnecessary.
1312    ///
1313    /// # Examples
1314    ///
1315    /// ```
1316    /// use scc2::HashIndex;
1317    ///
1318    /// let hashindex: HashIndex<u64, u32> = HashIndex::default();
1319    ///
1320    /// hashindex.entry(11).or_insert_with_key(|k| if *k == 11 { 7 } else { 3 });
1321    /// assert_eq!(hashindex.peek_with(&11, |_, v| *v), Some(7));
1322    /// ```
1323    #[inline]
1324    pub fn or_insert_with_key<F: FnOnce(&K) -> V>(
1325        self,
1326        constructor: F,
1327    ) -> OccupiedEntry<'h, K, V, H> {
1328        match self {
1329            Self::Occupied(o) => o,
1330            Self::Vacant(v) => {
1331                let val = constructor(v.key());
1332                v.insert_entry(val)
1333            }
1334        }
1335    }
1336
1337    /// Returns a reference to the key of this entry.
1338    ///
1339    /// # Examples
1340    ///
1341    /// ```
1342    /// use scc2::HashIndex;
1343    ///
1344    /// let hashindex: HashIndex<u64, u32> = HashIndex::default();
1345    /// assert_eq!(hashindex.entry(31).key(), &31);
1346    /// ```
1347    #[inline]
1348    pub fn key(&self) -> &K {
1349        match self {
1350            Self::Occupied(o) => o.key(),
1351            Self::Vacant(v) => v.key(),
1352        }
1353    }
1354
1355    /// Provides in-place mutable access to an occupied entry.
1356    ///
1357    /// # Safety
1358    ///
1359    /// The caller has to make sure that there are no readers of the entry, e.g., a reader keeping
1360    /// a reference to the entry via [`HashIndex::iter`], [`HashIndex::peek`], or
1361    /// [`HashIndex::peek_with`], unless an instance of `V` can be safely read when there is a
1362    /// single writer, e.g., `V = [u8; 32]`.
1363    ///
1364    /// # Examples
1365    ///
1366    /// ```
1367    /// use scc2::HashIndex;
1368    ///
1369    /// let hashindex: HashIndex<u64, u32> = HashIndex::default();
1370    ///
1371    /// unsafe {
1372    ///     hashindex.entry(37).and_modify(|v| { *v += 1 }).or_insert(47);
1373    /// }
1374    /// assert_eq!(hashindex.peek_with(&37, |_, v| *v), Some(47));
1375    ///
1376    /// unsafe {
1377    ///     hashindex.entry(37).and_modify(|v| { *v += 1 }).or_insert(3);
1378    /// }
1379    /// assert_eq!(hashindex.peek_with(&37, |_, v| *v), Some(48));
1380    /// ```
1381    #[inline]
1382    #[must_use]
1383    pub unsafe fn and_modify<F>(self, f: F) -> Self
1384    where
1385        F: FnOnce(&mut V),
1386    {
1387        match self {
1388            Self::Occupied(mut o) => {
1389                f(o.get_mut());
1390                Self::Occupied(o)
1391            }
1392            Self::Vacant(_) => self,
1393        }
1394    }
1395}
1396
1397impl<'h, K, V, H> Entry<'h, K, V, H>
1398where
1399    K: 'static + Clone + Eq + Hash,
1400    V: 'static + Clone + Default,
1401    H: BuildHasher,
1402{
1403    /// Ensures a value is in the entry by inserting the default value if empty.
1404    ///
1405    /// # Examples
1406    ///
1407    /// ```
1408    /// use scc2::HashIndex;
1409    ///
1410    /// let hashindex: HashIndex<u64, u32> = HashIndex::default();
1411    /// hashindex.entry(11).or_default();
1412    /// assert_eq!(hashindex.peek_with(&11, |_, v| *v), Some(0));
1413    /// ```
1414    #[inline]
1415    pub fn or_default(self) -> OccupiedEntry<'h, K, V, H> {
1416        match self {
1417            Self::Occupied(o) => o,
1418            Self::Vacant(v) => v.insert_entry(Default::default()),
1419        }
1420    }
1421}
1422
1423impl<K, V, H> Debug for Entry<'_, K, V, H>
1424where
1425    K: 'static + Clone + Debug + Eq + Hash,
1426    V: 'static + Clone + Debug,
1427    H: BuildHasher,
1428{
1429    #[inline]
1430    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1431        match self {
1432            Self::Vacant(v) => f.debug_tuple("Entry").field(v).finish(),
1433            Self::Occupied(o) => f.debug_tuple("Entry").field(o).finish(),
1434        }
1435    }
1436}
1437
1438impl<'h, K, V, H> OccupiedEntry<'h, K, V, H>
1439where
1440    K: 'static + Clone + Eq + Hash,
1441    V: 'static + Clone,
1442    H: BuildHasher,
1443{
1444    /// Gets a reference to the key in the entry.
1445    ///
1446    /// # Examples
1447    ///
1448    /// ```
1449    /// use scc2::HashIndex;
1450    ///
1451    /// let hashindex: HashIndex<u64, u32> = HashIndex::default();
1452    ///
1453    /// assert_eq!(hashindex.entry(29).or_default().key(), &29);
1454    /// ```
1455    #[inline]
1456    #[must_use]
1457    pub fn key(&self) -> &K {
1458        &self
1459            .locked_entry
1460            .entry_ptr
1461            .get(self.locked_entry.data_block_mut)
1462            .0
1463    }
1464
1465    /// Marks that the entry is removed from the [`HashIndex`].
1466    ///
1467    /// # Examples
1468    ///
1469    /// ```
1470    /// use scc2::HashIndex;
1471    /// use scc2::hash_index::Entry;
1472    ///
1473    /// let hashindex: HashIndex<u64, u32> = HashIndex::default();
1474    ///
1475    /// hashindex.entry(11).or_insert(17);
1476    ///
1477    /// if let Entry::Occupied(o) = hashindex.entry(11) {
1478    ///     o.remove_entry();
1479    /// };
1480    /// assert_eq!(hashindex.peek_with(&11, |_, v| *v), None);
1481    /// ```
1482    #[inline]
1483    pub fn remove_entry(mut self) {
1484        let guard = Guard::new();
1485        self.locked_entry.locker.mark_removed(
1486            &mut self.locked_entry.entry_ptr,
1487            self.hashindex.prolonged_guard_ref(&guard),
1488        );
1489        if self.locked_entry.locker.num_entries() <= 1 || self.locked_entry.locker.need_rebuild() {
1490            let hashindex = self.hashindex;
1491            if let Some(current_array) = hashindex.bucket_array().load(Acquire, &guard).as_ref() {
1492                if !current_array.has_old_array() {
1493                    let index = self.locked_entry.index;
1494                    if current_array.within_sampling_range(index) {
1495                        drop(self);
1496                        hashindex.try_shrink_or_rebuild(current_array, index, &guard);
1497                    }
1498                }
1499            }
1500        }
1501    }
1502
1503    /// Gets a reference to the value in the entry.
1504    ///
1505    /// # Examples
1506    ///
1507    /// ```
1508    /// use scc2::HashIndex;
1509    /// use scc2::hash_index::Entry;
1510    ///
1511    /// let hashindex: HashIndex<u64, u32> = HashIndex::default();
1512    ///
1513    /// hashindex.entry(19).or_insert(11);
1514    ///
1515    /// if let Entry::Occupied(o) = hashindex.entry(19) {
1516    ///     assert_eq!(o.get(), &11);
1517    /// };
1518    /// ```
1519    #[inline]
1520    #[must_use]
1521    pub fn get(&self) -> &V {
1522        &self
1523            .locked_entry
1524            .entry_ptr
1525            .get(self.locked_entry.data_block_mut)
1526            .1
1527    }
1528
1529    /// Gets a mutable reference to the value in the entry.
1530    ///
1531    /// # Safety
1532    ///
1533    /// The caller has to make sure that there are no readers of the entry, e.g., a reader keeping
1534    /// a reference to the entry via [`HashIndex::iter`], [`HashIndex::peek`], or
1535    /// [`HashIndex::peek_with`], unless an instance of `V` can be safely read when there is a
1536    /// single writer, e.g., `V = [u8; 32]`.
1537    ///
1538    /// # Examples
1539    ///
1540    /// ```
1541    /// use scc2::HashIndex;
1542    /// use scc2::hash_index::Entry;
1543    ///
1544    /// let hashindex: HashIndex<u64, u32> = HashIndex::default();
1545    ///
1546    /// hashindex.entry(37).or_insert(11);
1547    ///
1548    /// if let Entry::Occupied(mut o) = hashindex.entry(37) {
1549    ///     // Safety: `u32` can be safely read while being modified.
1550    ///     unsafe { *o.get_mut() += 18; }
1551    ///     assert_eq!(*o.get(), 29);
1552    /// }
1553    ///
1554    /// assert_eq!(hashindex.peek_with(&37, |_, v| *v), Some(29));
1555    /// ```
1556    #[inline]
1557    pub unsafe fn get_mut(&mut self) -> &mut V {
1558        &mut self
1559            .locked_entry
1560            .entry_ptr
1561            .get_mut(
1562                self.locked_entry.data_block_mut,
1563                &mut self.locked_entry.locker,
1564            )
1565            .1
1566    }
1567
1568    /// Updates the entry by inserting a new entry and marking the existing entry removed.
1569    ///
1570    /// # Examples
1571    ///
1572    /// ```
1573    /// use scc2::HashIndex;
1574    /// use scc2::hash_index::Entry;
1575    ///
1576    /// let hashindex: HashIndex<u64, u32> = HashIndex::default();
1577    ///
1578    /// hashindex.entry(37).or_insert(11);
1579    ///
1580    /// if let Entry::Occupied(mut o) = hashindex.entry(37) {
1581    ///     o.update(29);
1582    /// }
1583    ///
1584    /// assert_eq!(hashindex.peek_with(&37, |_, v| *v), Some(29));
1585    /// ```
1586    #[inline]
1587    pub fn update(mut self, val: V) {
1588        let key = self.key().clone();
1589        let partial_hash = self
1590            .locked_entry
1591            .entry_ptr
1592            .partial_hash(&self.locked_entry.locker);
1593        let guard = Guard::new();
1594        self.locked_entry.locker.insert_with(
1595            self.locked_entry.data_block_mut,
1596            partial_hash,
1597            || (key, val),
1598            self.hashindex.prolonged_guard_ref(&guard),
1599        );
1600        self.locked_entry.locker.mark_removed(
1601            &mut self.locked_entry.entry_ptr,
1602            self.hashindex.prolonged_guard_ref(&guard),
1603        );
1604    }
1605
1606    /// Gets the next closest occupied entry.
1607    ///
1608    /// [`HashIndex::first_entry`], [`HashIndex::first_entry_async`], and this method together
1609    /// enables the [`OccupiedEntry`] to effectively act as a mutable iterator over entries. The
1610    /// method never acquires more than one lock even when it searches other buckets for the next
1611    /// closest occupied entry.
1612    ///
1613    /// # Examples
1614    ///
1615    /// ```
1616    /// use scc2::HashIndex;
1617    /// use scc2::hash_index::Entry;
1618    ///
1619    /// let hashindex: HashIndex<u64, u32> = HashIndex::default();
1620    ///
1621    /// assert!(hashindex.insert(1, 0).is_ok());
1622    /// assert!(hashindex.insert(2, 0).is_ok());
1623    ///
1624    /// let first_entry = hashindex.first_entry().unwrap();
1625    /// let first_key = *first_entry.key();
1626    /// let second_entry = first_entry.next().unwrap();
1627    /// let second_key = *second_entry.key();
1628    ///
1629    /// assert!(second_entry.next().is_none());
1630    /// assert_eq!(first_key + second_key, 3);
1631    /// ```
1632    #[inline]
1633    #[must_use]
1634    pub fn next(self) -> Option<Self> {
1635        let hashindex = self.hashindex;
1636        if let Some(locked_entry) = self.locked_entry.next(hashindex) {
1637            return Some(OccupiedEntry {
1638                hashindex,
1639                locked_entry,
1640            });
1641        }
1642        None
1643    }
1644
1645    /// Gets the next closest occupied entry.
1646    ///
1647    /// [`HashIndex::first_entry`], [`HashIndex::first_entry_async`], and this method together
1648    /// enables the [`OccupiedEntry`] to effectively act as a mutable iterator over entries. The
1649    /// method never acquires more than one lock even when it searches other buckets for the next
1650    /// closest occupied entry.
1651    ///
1652    /// It is an asynchronous method returning an `impl Future` for the caller to await.
1653    ///
1654    /// # Examples
1655    ///
1656    /// ```
1657    /// use scc2::HashIndex;
1658    /// use scc2::hash_index::Entry;
1659    ///
1660    /// let hashindex: HashIndex<u64, u32> = HashIndex::default();
1661    ///
1662    /// assert!(hashindex.insert(1, 0).is_ok());
1663    /// assert!(hashindex.insert(2, 0).is_ok());
1664    ///
1665    /// let second_entry_future = hashindex.first_entry().unwrap().next_async();
1666    /// ```
1667    #[inline]
1668    pub async fn next_async(self) -> Option<OccupiedEntry<'h, K, V, H>> {
1669        let hashindex = self.hashindex;
1670        if let Some(locked_entry) = self.locked_entry.next_async(hashindex).await {
1671            return Some(OccupiedEntry {
1672                hashindex,
1673                locked_entry,
1674            });
1675        }
1676        None
1677    }
1678}
1679
1680impl<K, V, H> Debug for OccupiedEntry<'_, K, V, H>
1681where
1682    K: 'static + Clone + Debug + Eq + Hash,
1683    V: 'static + Clone + Debug,
1684    H: BuildHasher,
1685{
1686    #[inline]
1687    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1688        f.debug_struct("OccupiedEntry")
1689            .field("key", self.key())
1690            .field("value", self.get())
1691            .finish_non_exhaustive()
1692    }
1693}
1694
1695impl<K, V, H> Deref for OccupiedEntry<'_, K, V, H>
1696where
1697    K: 'static + Clone + Debug + Eq + Hash,
1698    V: 'static + Clone + Debug,
1699    H: BuildHasher,
1700{
1701    type Target = V;
1702
1703    #[inline]
1704    fn deref(&self) -> &Self::Target {
1705        self.get()
1706    }
1707}
1708
1709impl<'h, K, V, H> VacantEntry<'h, K, V, H>
1710where
1711    K: 'static + Clone + Eq + Hash,
1712    V: 'static + Clone,
1713    H: BuildHasher,
1714{
1715    /// Gets a reference to the key.
1716    ///
1717    /// # Examples
1718    ///
1719    /// ```
1720    /// use scc2::HashIndex;
1721    ///
1722    /// let hashindex: HashIndex<u64, u32> = HashIndex::default();
1723    /// assert_eq!(hashindex.entry(11).key(), &11);
1724    /// ```
1725    #[inline]
1726    pub fn key(&self) -> &K {
1727        &self.key
1728    }
1729
1730    /// Takes ownership of the key.
1731    ///
1732    /// # Examples
1733    ///
1734    /// ```
1735    /// use scc2::HashIndex;
1736    /// use scc2::hash_index::Entry;
1737    ///
1738    /// let hashindex: HashIndex<u64, u32> = HashIndex::default();
1739    ///
1740    /// if let Entry::Vacant(v) = hashindex.entry(17) {
1741    ///     assert_eq!(v.into_key(), 17);
1742    /// };
1743    /// ```
1744    #[inline]
1745    pub fn into_key(self) -> K {
1746        self.key
1747    }
1748
1749    /// Sets the value of the entry with its key, and returns an [`OccupiedEntry`].
1750    ///
1751    /// # Examples
1752    ///
1753    /// ```
1754    /// use scc2::HashIndex;
1755    /// use scc2::hash_index::Entry;
1756    ///
1757    /// let hashindex: HashIndex<u64, u32> = HashIndex::default();
1758    ///
1759    /// if let Entry::Vacant(o) = hashindex.entry(19) {
1760    ///     o.insert_entry(29);
1761    /// }
1762    ///
1763    /// assert_eq!(hashindex.peek_with(&19, |_, v| *v), Some(29));
1764    /// ```
1765    #[inline]
1766    pub fn insert_entry(mut self, val: V) -> OccupiedEntry<'h, K, V, H> {
1767        let guard = Guard::new();
1768        let entry_ptr = self.locked_entry.locker.insert_with(
1769            self.locked_entry.data_block_mut,
1770            BucketArray::<K, V, (), OPTIMISTIC>::partial_hash(self.hash),
1771            || (self.key, val),
1772            self.hashindex.prolonged_guard_ref(&guard),
1773        );
1774        OccupiedEntry {
1775            hashindex: self.hashindex,
1776            locked_entry: LockedEntry {
1777                index: self.locked_entry.index,
1778                data_block_mut: self.locked_entry.data_block_mut,
1779                locker: self.locked_entry.locker,
1780                entry_ptr,
1781            },
1782        }
1783    }
1784}
1785
1786impl<K, V, H> Debug for VacantEntry<'_, K, V, H>
1787where
1788    K: 'static + Clone + Debug + Eq + Hash,
1789    V: 'static + Clone + Debug,
1790    H: BuildHasher,
1791{
1792    #[inline]
1793    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1794        f.debug_tuple("VacantEntry").field(self.key()).finish()
1795    }
1796}
1797
1798impl<K, V, H> Reserve<'_, K, V, H>
1799where
1800    K: 'static + Clone + Eq + Hash,
1801    V: 'static + Clone,
1802    H: BuildHasher,
1803{
1804    /// Returns the number of reserved slots.
1805    #[inline]
1806    #[must_use]
1807    pub fn additional_capacity(&self) -> usize {
1808        self.additional
1809    }
1810}
1811
1812impl<K, V, H> AsRef<HashIndex<K, V, H>> for Reserve<'_, K, V, H>
1813where
1814    K: 'static + Clone + Eq + Hash,
1815    V: 'static + Clone,
1816    H: BuildHasher,
1817{
1818    #[inline]
1819    fn as_ref(&self) -> &HashIndex<K, V, H> {
1820        self.hashindex
1821    }
1822}
1823
1824impl<K, V, H> Debug for Reserve<'_, K, V, H>
1825where
1826    K: 'static + Clone + Eq + Hash,
1827    V: 'static + Clone,
1828    H: BuildHasher,
1829{
1830    #[inline]
1831    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1832        f.debug_tuple("Reserve").field(&self.additional).finish()
1833    }
1834}
1835
1836impl<K, V, H> Deref for Reserve<'_, K, V, H>
1837where
1838    K: 'static + Clone + Eq + Hash,
1839    V: 'static + Clone,
1840    H: BuildHasher,
1841{
1842    type Target = HashIndex<K, V, H>;
1843
1844    #[inline]
1845    fn deref(&self) -> &Self::Target {
1846        self.hashindex
1847    }
1848}
1849
1850impl<K, V, H> Drop for Reserve<'_, K, V, H>
1851where
1852    K: 'static + Clone + Eq + Hash,
1853    V: 'static + Clone,
1854    H: BuildHasher,
1855{
1856    #[inline]
1857    fn drop(&mut self) {
1858        let result = self
1859            .hashindex
1860            .minimum_capacity
1861            .fetch_sub(self.additional, Relaxed);
1862        self.hashindex.try_resize(0, &Guard::new());
1863        debug_assert!(result >= self.additional);
1864    }
1865}
1866
1867impl<K, V, H> Debug for Iter<'_, '_, K, V, H>
1868where
1869    K: 'static + Clone + Eq + Hash,
1870    V: 'static + Clone,
1871    H: BuildHasher,
1872{
1873    #[inline]
1874    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1875        f.debug_struct("Iter")
1876            .field("current_index", &self.current_index)
1877            .field("current_entry_ptr", &self.current_entry_ptr)
1878            .finish()
1879    }
1880}
1881
1882impl<'g, K, V, H> Iterator for Iter<'_, 'g, K, V, H>
1883where
1884    K: 'static + Clone + Eq + Hash,
1885    V: 'static + Clone,
1886    H: BuildHasher,
1887{
1888    type Item = (&'g K, &'g V);
1889
1890    #[inline]
1891    fn next(&mut self) -> Option<Self::Item> {
1892        let mut array = if let Some(array) = self.current_array.as_ref().copied() {
1893            array
1894        } else {
1895            // Start scanning.
1896            let current_array = self
1897                .hashindex
1898                .bucket_array()
1899                .load(Acquire, self.guard)
1900                .as_ref()?;
1901            let old_array_ptr = current_array.old_array(self.guard);
1902            let array = if let Some(old_array) = old_array_ptr.as_ref() {
1903                old_array
1904            } else {
1905                current_array
1906            };
1907            self.current_array.replace(array);
1908            self.current_bucket.replace(array.bucket(0));
1909            self.current_entry_ptr = EntryPtr::new(self.guard);
1910            array
1911        };
1912
1913        // Go to the next bucket.
1914        loop {
1915            if let Some(bucket) = self.current_bucket.take() {
1916                // Go to the next entry in the bucket.
1917                if self.current_entry_ptr.move_to_next(bucket, self.guard) {
1918                    let (k, v) = self
1919                        .current_entry_ptr
1920                        .get(array.data_block(self.current_index));
1921                    self.current_bucket.replace(bucket);
1922                    return Some((k, v));
1923                }
1924            }
1925            self.current_index += 1;
1926            if self.current_index == array.num_buckets() {
1927                let current_array = self
1928                    .hashindex
1929                    .bucket_array()
1930                    .load(Acquire, self.guard)
1931                    .as_ref()?;
1932                if self
1933                    .current_array
1934                    .as_ref()
1935                    .copied()
1936                    .map_or(false, |a| ptr::eq(a, current_array))
1937                {
1938                    // Finished scanning the entire array.
1939                    break;
1940                }
1941                let old_array_ptr = current_array.old_array(self.guard);
1942                if self
1943                    .current_array
1944                    .as_ref()
1945                    .copied()
1946                    .map_or(false, |a| ptr::eq(a, old_array_ptr.as_ptr()))
1947                {
1948                    // Start scanning the current array.
1949                    array = current_array;
1950                    self.current_array.replace(array);
1951                    self.current_index = 0;
1952                    self.current_bucket.replace(array.bucket(0));
1953                    self.current_entry_ptr = EntryPtr::new(self.guard);
1954                    continue;
1955                }
1956
1957                // Start from the very beginning.
1958                array = if let Some(old_array) = old_array_ptr.as_ref() {
1959                    old_array
1960                } else {
1961                    current_array
1962                };
1963                self.current_array.replace(array);
1964                self.current_index = 0;
1965                self.current_bucket.replace(array.bucket(0));
1966                self.current_entry_ptr = EntryPtr::new(self.guard);
1967                continue;
1968            }
1969            self.current_bucket
1970                .replace(array.bucket(self.current_index));
1971            self.current_entry_ptr = EntryPtr::new(self.guard);
1972        }
1973        None
1974    }
1975}
1976
1977impl<K, V, H> FusedIterator for Iter<'_, '_, K, V, H>
1978where
1979    K: 'static + Clone + Eq + Hash,
1980    V: 'static + Clone,
1981    H: BuildHasher,
1982{
1983}
1984
1985impl<K, V, H> UnwindSafe for Iter<'_, '_, K, V, H>
1986where
1987    K: 'static + Clone + Eq + Hash + UnwindSafe,
1988    V: 'static + Clone + UnwindSafe,
1989    H: BuildHasher + UnwindSafe,
1990{
1991}