scc2/hash_map.rs
1//! [`HashMap`] is a concurrent and asynchronous hash map.
2
3use super::ebr::{AtomicShared, Guard, Shared, Tag};
4use super::hash_table::bucket::{EntryPtr, Locker, Reader, SEQUENTIAL};
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::mem::replace;
13use std::ops::{Deref, DerefMut, RangeInclusive};
14use std::pin::Pin;
15use std::sync::atomic::AtomicUsize;
16use std::sync::atomic::Ordering::{Acquire, Relaxed};
17
18/// Scalable concurrent hash map.
19///
20/// [`HashMap`] is a concurrent and asynchronous hash map data structure optimized for highly
21/// concurrent workloads. [`HashMap`] has a dynamically sized array of buckets where a bucket is a
22/// fixed-size hash table with linear probing that can be expanded by allocating a linked list of
23/// smaller buckets when it is full.
24///
25/// ## The key features of [`HashMap`]
26///
27/// * Non-sharded: the data is stored in a single array of entry buckets.
28/// * Non-blocking resizing: resizing does not block other threads or tasks.
29/// * Automatic resizing: it automatically grows or shrinks.
30/// * Incremental resizing: entries in the old bucket array are incrementally relocated.
31/// * No busy waiting: no spin-locks or hot loops to wait for desired resources.
32/// * Linearizability: [`HashMap`] manipulation methods are linearizable.
33///
34/// ## The key statistics for [`HashMap`]
35///
36/// * The expected size of metadata for a single entry: 2-byte.
37/// * The expected number of atomic write operations required for an operation on a single key: 2.
38/// * The expected number of atomic variables accessed during a single key operation: 2.
39/// * The number of entries managed by a single bucket without a linked list: 32.
40/// * The expected maximum linked list length when a resize is triggered: log(capacity) / 8.
41///
42/// ## Locking behavior
43///
44/// ### Bucket access
45///
46/// Bucket arrays are protected by [`ebr`](super::ebr), thus allowing lock-free access to them.
47///
48/// ### Entry access
49///
50/// Each read/write access to an entry is serialized by the read-write lock in the bucket containing
51/// the entry. There are no container-level locks, therefore, the larger the [`HashMap`] gets, the
52/// lower the chance that the bucket-level lock is being contended.
53///
54/// ### Resize
55///
56/// Resizing of the [`HashMap`] is non-blocking and lock-free; resizing does not block any other
57/// read/write access to the [`HashMap`] or resizing attempts. Resizing is analogous to pushing a
58/// new bucket array into a lock-free stack. Each entry in the old bucket array will be
59/// incrementally relocated to the new bucket array on future access to the [`HashMap`], and the old
60/// bucket array gets dropped when it becomes empty and unreachable.
61///
62/// ### Unwind safety
63///
64/// [`HashMap`] is impervious to out-of-memory errors and panics in user-specified code on one
65/// condition; `H::Hasher::hash`, `K::drop` and `V::drop` must not panic.
66pub struct HashMap<K, V, H = RandomState>
67where
68 H: BuildHasher,
69{
70 array: AtomicShared<BucketArray<K, V, (), SEQUENTIAL>>,
71 minimum_capacity: AtomicUsize,
72 build_hasher: H,
73}
74
75/// [`Entry`] represents a single entry in a [`HashMap`].
76pub enum Entry<'h, K, V, H = RandomState>
77where
78 H: BuildHasher,
79{
80 /// An occupied entry.
81 Occupied(OccupiedEntry<'h, K, V, H>),
82
83 /// A vacant entry.
84 Vacant(VacantEntry<'h, K, V, H>),
85}
86
87/// [`OccupiedEntry`] is a view into an occupied entry in a [`HashMap`].
88pub struct OccupiedEntry<'h, K, V, H = RandomState>
89where
90 H: BuildHasher,
91{
92 hashmap: &'h HashMap<K, V, H>,
93 locked_entry: LockedEntry<'h, K, V, (), SEQUENTIAL>,
94}
95
96/// [`VacantEntry`] is a view into a vacant entry in a [`HashMap`].
97pub struct VacantEntry<'h, K, V, H = RandomState>
98where
99 H: BuildHasher,
100{
101 hashmap: &'h HashMap<K, V, H>,
102 key: K,
103 hash: u64,
104 locked_entry: LockedEntry<'h, K, V, (), SEQUENTIAL>,
105}
106
107/// [`Reserve`] keeps the capacity of the associated [`HashMap`] higher than a certain level.
108///
109/// The [`HashMap`] does not shrink the capacity below the reserved capacity.
110pub struct Reserve<'h, K, V, H = RandomState>
111where
112 K: Eq + Hash,
113 H: BuildHasher,
114{
115 hashmap: &'h HashMap<K, V, H>,
116 additional: usize,
117}
118
119impl<K, V, H> HashMap<K, V, H>
120where
121 H: BuildHasher,
122{
123 /// Creates an empty [`HashMap`] with the given [`BuildHasher`].
124 ///
125 /// # Examples
126 ///
127 /// ```
128 /// use scc2::HashMap;
129 /// use std::collections::hash_map::RandomState;
130 ///
131 /// let hashmap: HashMap<u64, u32, RandomState> = HashMap::with_hasher(RandomState::new());
132 /// ```
133 #[cfg(not(feature = "loom"))]
134 #[inline]
135 pub const fn with_hasher(build_hasher: H) -> Self {
136 Self {
137 array: AtomicShared::null(),
138 minimum_capacity: AtomicUsize::new(0),
139 build_hasher,
140 }
141 }
142
143 /// Creates an empty [`HashMap`] with the given [`BuildHasher`].
144 #[cfg(feature = "loom")]
145 #[inline]
146 pub fn with_hasher(build_hasher: H) -> Self {
147 Self {
148 array: AtomicShared::null(),
149 minimum_capacity: AtomicUsize::new(0),
150 build_hasher,
151 }
152 }
153
154 /// Creates an empty [`HashMap`] with the specified capacity and [`BuildHasher`].
155 ///
156 /// The actual capacity is equal to or greater than the specified capacity.
157 ///
158 /// # Examples
159 ///
160 /// ```
161 /// use scc2::HashMap;
162 /// use std::collections::hash_map::RandomState;
163 ///
164 /// let hashmap: HashMap<u64, u32, RandomState> =
165 /// HashMap::with_capacity_and_hasher(1000, RandomState::new());
166 ///
167 /// let result = hashmap.capacity();
168 /// assert_eq!(result, 1024);
169 /// ```
170 #[inline]
171 pub fn with_capacity_and_hasher(capacity: usize, build_hasher: H) -> Self {
172 let (array, minimum_capacity) = if capacity == 0 {
173 (AtomicShared::null(), AtomicUsize::new(0))
174 } else {
175 let array = unsafe {
176 Shared::new_unchecked(BucketArray::<K, V, (), SEQUENTIAL>::new(
177 capacity,
178 AtomicShared::null(),
179 ))
180 };
181 let minimum_capacity = array.num_entries();
182 (
183 AtomicShared::from(array),
184 AtomicUsize::new(minimum_capacity),
185 )
186 };
187 Self {
188 array,
189 minimum_capacity,
190 build_hasher,
191 }
192 }
193}
194
195impl<K, V, H> HashMap<K, V, H>
196where
197 K: Eq + Hash,
198 H: BuildHasher,
199{
200 /// Temporarily increases the minimum capacity of the [`HashMap`].
201 ///
202 /// A [`Reserve`] is returned if the [`HashMap`] could increase the minimum capacity while the
203 /// increased capacity is not exclusively owned by the returned [`Reserve`], allowing others to
204 /// benefit from it. The memory for the additional space may not be immediately allocated if
205 /// the [`HashMap`] is empty or currently being resized, however once the memory is reserved
206 /// eventually, the capacity will not shrink below the additional capacity until the returned
207 /// [`Reserve`] is dropped.
208 ///
209 /// # Errors
210 ///
211 /// Returns `None` if a too large number is given.
212 ///
213 /// # Examples
214 ///
215 /// ```
216 /// use scc2::HashMap;
217 ///
218 /// let hashmap: HashMap<usize, usize> = HashMap::with_capacity(1000);
219 /// assert_eq!(hashmap.capacity(), 1024);
220 ///
221 /// let reserved = hashmap.reserve(10000);
222 /// assert!(reserved.is_some());
223 /// assert_eq!(hashmap.capacity(), 16384);
224 ///
225 /// assert!(hashmap.reserve(usize::MAX).is_none());
226 /// assert_eq!(hashmap.capacity(), 16384);
227 ///
228 /// for i in 0..16 {
229 /// assert!(hashmap.insert(i, i).is_ok());
230 /// }
231 /// drop(reserved);
232 ///
233 /// assert_eq!(hashmap.capacity(), 1024);
234 /// ```
235 #[inline]
236 pub fn reserve(&self, additional_capacity: usize) -> Option<Reserve<K, V, H>> {
237 let additional = self.reserve_capacity(additional_capacity);
238 if additional == 0 {
239 None
240 } else {
241 Some(Reserve {
242 hashmap: self,
243 additional,
244 })
245 }
246 }
247
248 /// Gets the entry associated with the given key in the map for in-place manipulation.
249 ///
250 /// # Examples
251 ///
252 /// ```
253 /// use scc2::HashMap;
254 ///
255 /// let hashmap: HashMap<char, u32> = HashMap::default();
256 ///
257 /// for ch in "a short treatise on fungi".chars() {
258 /// hashmap.entry(ch).and_modify(|counter| *counter += 1).or_insert(1);
259 /// }
260 ///
261 /// assert_eq!(hashmap.read(&'s', |_, v| *v), Some(2));
262 /// assert_eq!(hashmap.read(&'t', |_, v| *v), Some(3));
263 /// assert!(hashmap.read(&'y', |_, v| *v).is_none());
264 /// ```
265 #[inline]
266 pub fn entry(&self, key: K) -> Entry<K, V, H> {
267 let guard = Guard::new();
268 let hash = self.hash(&key);
269 let locked_entry = unsafe {
270 self.reserve_entry(&key, hash, &mut (), self.prolonged_guard_ref(&guard))
271 .ok()
272 .unwrap_unchecked()
273 };
274 if locked_entry.entry_ptr.is_valid() {
275 Entry::Occupied(OccupiedEntry {
276 hashmap: self,
277 locked_entry,
278 })
279 } else {
280 Entry::Vacant(VacantEntry {
281 hashmap: self,
282 key,
283 hash,
284 locked_entry,
285 })
286 }
287 }
288
289 /// Gets the entry associated with the given key in the map for in-place manipulation.
290 ///
291 /// It is an asynchronous method returning an `impl Future` for the caller to await.
292 ///
293 /// # Examples
294 ///
295 /// ```
296 /// use scc2::HashMap;
297 ///
298 /// let hashmap: HashMap<char, u32> = HashMap::default();
299 ///
300 /// let future_entry = hashmap.entry_async('b');
301 /// ```
302 #[inline]
303 pub async fn entry_async(&self, key: K) -> Entry<K, V, H> {
304 let hash = self.hash(&key);
305 loop {
306 let mut async_wait = AsyncWait::default();
307 let mut async_wait_pinned = Pin::new(&mut async_wait);
308 {
309 let guard = Guard::new();
310 if let Ok(locked_entry) = self.reserve_entry(
311 &key,
312 hash,
313 &mut async_wait_pinned,
314 self.prolonged_guard_ref(&guard),
315 ) {
316 if locked_entry.entry_ptr.is_valid() {
317 return Entry::Occupied(OccupiedEntry {
318 hashmap: self,
319 locked_entry,
320 });
321 }
322 return Entry::Vacant(VacantEntry {
323 hashmap: self,
324 key,
325 hash,
326 locked_entry,
327 });
328 }
329 }
330 async_wait_pinned.await;
331 }
332 }
333
334 /// Gets the first occupied entry for in-place manipulation.
335 ///
336 /// The returned [`OccupiedEntry`] in combination with [`OccupiedEntry::next`] or
337 /// [`OccupiedEntry::next_async`] can act as a mutable iterator over entries.
338 ///
339 /// # Examples
340 ///
341 /// ```
342 /// use scc2::HashMap;
343 ///
344 /// let hashmap: HashMap<u64, u32> = HashMap::default();
345 ///
346 /// assert!(hashmap.insert(1, 0).is_ok());
347 ///
348 /// let mut first_entry = hashmap.first_entry().unwrap();
349 /// *first_entry.get_mut() = 2;
350 ///
351 /// assert!(first_entry.next().is_none());
352 /// assert_eq!(hashmap.read(&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 hashmap: 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::HashMap;
378 ///
379 /// let hashmap: HashMap<char, u32> = HashMap::default();
380 ///
381 /// let future_entry = hashmap.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 hashmap: 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::HashMap;
403 ///
404 /// let hashmap: HashMap<u64, u32> = HashMap::default();
405 ///
406 /// assert!(hashmap.insert(1, 0).is_ok());
407 /// assert!(hashmap.insert(2, 3).is_ok());
408 ///
409 /// let mut entry = hashmap.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 hashmap: 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::HashMap;
434 ///
435 /// let hashmap: HashMap<u64, u32> = HashMap::default();
436 ///
437 /// let future_entry = hashmap.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 hashmap: 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 [`HashMap`].
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::HashMap;
469 ///
470 /// let hashmap: HashMap<u64, u32> = HashMap::default();
471 ///
472 /// assert!(hashmap.insert(1, 0).is_ok());
473 /// assert_eq!(hashmap.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 [`HashMap`].
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::HashMap;
498 ///
499 /// let hashmap: HashMap<u64, u32> = HashMap::default();
500 /// let future_insert = hashmap.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 /// Upserts a key-value pair into the [`HashMap`].
521 ///
522 /// Returns the old value if the [`HashMap`] has this key present, or returns `None`.
523 ///
524 /// # Examples
525 ///
526 /// ```
527 /// use scc2::HashMap;
528 ///
529 /// let hashmap: HashMap<u64, u32> = HashMap::default();
530 ///
531 /// assert!(hashmap.upsert(1, 0).is_none());
532 /// assert_eq!(hashmap.upsert(1, 1).unwrap(), 0);
533 /// assert_eq!(hashmap.read(&1, |_, v| *v).unwrap(), 1);
534 /// ```
535 #[inline]
536 pub fn upsert(&self, key: K, val: V) -> Option<V> {
537 match self.entry(key) {
538 Entry::Occupied(mut o) => Some(replace(o.get_mut(), val)),
539 Entry::Vacant(v) => {
540 v.insert_entry(val);
541 None
542 }
543 }
544 }
545
546 /// Upserts a key-value pair into the [`HashMap`].
547 ///
548 /// Returns the old value if the [`HashMap`] has this key present, or returns `None`. It is an
549 /// asynchronous method returning an `impl Future` for the caller to await.
550 ///
551 /// # Examples
552 ///
553 /// ```
554 /// use scc2::HashMap;
555 ///
556 /// let hashmap: HashMap<u64, u32> = HashMap::default();
557 /// let future_upsert = hashmap.upsert_async(11, 17);
558 /// ```
559 #[inline]
560 pub async fn upsert_async(&self, key: K, val: V) -> Option<V> {
561 match self.entry_async(key).await {
562 Entry::Occupied(mut o) => Some(replace(o.get_mut(), val)),
563 Entry::Vacant(v) => {
564 v.insert_entry(val);
565 None
566 }
567 }
568 }
569
570 /// Updates an existing key-value pair in-place.
571 ///
572 /// Returns `None` if the key does not exist.
573 ///
574 /// # Examples
575 ///
576 /// ```
577 /// use scc2::HashMap;
578 ///
579 /// let hashmap: HashMap<u64, u32> = HashMap::default();
580 ///
581 /// assert!(hashmap.update(&1, |_, _| true).is_none());
582 /// assert!(hashmap.insert(1, 0).is_ok());
583 /// assert_eq!(hashmap.update(&1, |_, v| { *v = 2; *v }).unwrap(), 2);
584 /// assert_eq!(hashmap.read(&1, |_, v| *v).unwrap(), 2);
585 /// ```
586 #[inline]
587 pub fn update<Q, U, R>(&self, key: &Q, updater: U) -> Option<R>
588 where
589 Q: Equivalent<K> + Hash + ?Sized,
590 U: FnOnce(&K, &mut V) -> R,
591 {
592 let guard = Guard::new();
593 let LockedEntry {
594 mut locker,
595 data_block_mut,
596 mut entry_ptr,
597 index: _,
598 } = self
599 .get_entry(key, self.hash(key), &mut (), &guard)
600 .ok()
601 .flatten()?;
602 let (k, v) = entry_ptr.get_mut(data_block_mut, &mut locker);
603 Some(updater(k, v))
604 }
605
606 /// Updates an existing key-value pair in-place.
607 ///
608 /// Returns `None` if the key does not exist. It is an asynchronous method returning an
609 /// `impl Future` for the caller to await.
610 ///
611 /// # Examples
612 ///
613 /// ```
614 /// use scc2::HashMap;
615 ///
616 /// let hashmap: HashMap<u64, u32> = HashMap::default();
617 ///
618 /// assert!(hashmap.insert(1, 0).is_ok());
619 /// let future_update = hashmap.update_async(&1, |_, v| { *v = 2; *v });
620 /// ```
621 #[inline]
622 pub async fn update_async<Q, U, R>(&self, key: &Q, updater: U) -> Option<R>
623 where
624 Q: Equivalent<K> + Hash + ?Sized,
625 U: FnOnce(&K, &mut V) -> R,
626 {
627 let hash = self.hash(key);
628 loop {
629 let mut async_wait = AsyncWait::default();
630 let mut async_wait_pinned = Pin::new(&mut async_wait);
631 if let Ok(result) = self.get_entry(key, hash, &mut async_wait_pinned, &Guard::new()) {
632 if let Some(LockedEntry {
633 mut locker,
634 data_block_mut,
635 mut entry_ptr,
636 index: _,
637 }) = result
638 {
639 let (k, v) = entry_ptr.get_mut(data_block_mut, &mut locker);
640 return Some(updater(k, v));
641 }
642 return None;
643 }
644 async_wait_pinned.await;
645 }
646 }
647
648 /// Removes a key-value pair if the key exists.
649 ///
650 /// Returns `None` if the key does not exist.
651 ///
652 /// # Examples
653 ///
654 /// ```
655 /// use scc2::HashMap;
656 ///
657 /// let hashmap: HashMap<u64, u32> = HashMap::default();
658 ///
659 /// assert!(hashmap.remove(&1).is_none());
660 /// assert!(hashmap.insert(1, 0).is_ok());
661 /// assert_eq!(hashmap.remove(&1).unwrap(), (1, 0));
662 /// ```
663 #[inline]
664 pub fn remove<Q>(&self, key: &Q) -> Option<(K, V)>
665 where
666 Q: Equivalent<K> + Hash + ?Sized,
667 {
668 self.remove_if(key, |_| true)
669 }
670
671 /// Removes a key-value pair if the key exists.
672 ///
673 /// Returns `None` if the key does not exist. It is an asynchronous method returning an
674 /// `impl Future` for the caller to await.
675 ///
676 /// # Examples
677 ///
678 /// ```
679 /// use scc2::HashMap;
680 ///
681 /// let hashmap: HashMap<u64, u32> = HashMap::default();
682 /// let future_insert = hashmap.insert_async(11, 17);
683 /// let future_remove = hashmap.remove_async(&11);
684 /// ```
685 #[inline]
686 pub async fn remove_async<Q>(&self, key: &Q) -> Option<(K, V)>
687 where
688 Q: Equivalent<K> + Hash + ?Sized,
689 {
690 self.remove_if_async(key, |_| true).await
691 }
692
693 /// Removes a key-value pair if the key exists and the given condition is met.
694 ///
695 /// Returns `None` if the key does not exist or the condition was not met.
696 ///
697 /// # Examples
698 ///
699 /// ```
700 /// use scc2::HashMap;
701 ///
702 /// let hashmap: HashMap<u64, u32> = HashMap::default();
703 ///
704 /// assert!(hashmap.insert(1, 0).is_ok());
705 /// assert!(hashmap.remove_if(&1, |v| { *v += 1; false }).is_none());
706 /// assert_eq!(hashmap.remove_if(&1, |v| *v == 1).unwrap(), (1, 1));
707 /// ```
708 #[inline]
709 pub fn remove_if<Q, F: FnOnce(&mut V) -> bool>(&self, key: &Q, condition: F) -> Option<(K, V)>
710 where
711 Q: Equivalent<K> + Hash + ?Sized,
712 {
713 self.remove_entry(
714 key,
715 self.hash(key),
716 condition,
717 Option::flatten,
718 &mut (),
719 &Guard::new(),
720 )
721 .ok()
722 .flatten()
723 }
724
725 /// Removes a key-value pair if the key exists and the given condition is met.
726 ///
727 /// Returns `None` if the key does not exist or the condition was not met. It is an
728 /// asynchronous method returning an `impl Future` for the caller to await.
729 ///
730 /// # Examples
731 ///
732 /// ```
733 /// use scc2::HashMap;
734 ///
735 /// let hashmap: HashMap<u64, u32> = HashMap::default();
736 /// let future_insert = hashmap.insert_async(11, 17);
737 /// let future_remove = hashmap.remove_if_async(&11, |_| true);
738 /// ```
739 #[inline]
740 pub async fn remove_if_async<Q, F: FnOnce(&mut V) -> bool>(
741 &self,
742 key: &Q,
743 mut condition: F,
744 ) -> Option<(K, V)>
745 where
746 Q: Equivalent<K> + Hash + ?Sized,
747 {
748 let hash = self.hash(key);
749 loop {
750 let mut async_wait = AsyncWait::default();
751 let mut async_wait_pinned = Pin::new(&mut async_wait);
752 match self.remove_entry(
753 key,
754 hash,
755 condition,
756 Option::flatten,
757 &mut async_wait_pinned,
758 &Guard::new(),
759 ) {
760 Ok(r) => return r,
761 Err(c) => condition = c,
762 }
763 async_wait_pinned.await;
764 }
765 }
766
767 /// Gets an [`OccupiedEntry`] corresponding to the key for in-place modification.
768 ///
769 /// [`OccupiedEntry`] exclusively owns the entry, preventing others from gaining access to it:
770 /// use [`read`](Self::read) if read-only access is sufficient.
771 ///
772 /// Returns `None` if the key does not exist.
773 ///
774 /// # Examples
775 ///
776 /// ```
777 /// use scc2::HashMap;
778 ///
779 /// let hashmap: HashMap<u64, u32> = HashMap::default();
780 ///
781 /// assert!(hashmap.get(&1).is_none());
782 /// assert!(hashmap.insert(1, 10).is_ok());
783 /// assert_eq!(*hashmap.get(&1).unwrap().get(), 10);
784 ///
785 /// *hashmap.get(&1).unwrap() = 11;
786 /// assert_eq!(*hashmap.get(&1).unwrap(), 11);
787 /// ```
788 #[inline]
789 pub fn get<Q>(&self, key: &Q) -> Option<OccupiedEntry<K, V, H>>
790 where
791 Q: Equivalent<K> + Hash + ?Sized,
792 {
793 let guard = Guard::new();
794 let locked_entry = self
795 .get_entry(
796 key,
797 self.hash(key),
798 &mut (),
799 self.prolonged_guard_ref(&guard),
800 )
801 .ok()
802 .flatten()?;
803 Some(OccupiedEntry {
804 hashmap: self,
805 locked_entry,
806 })
807 }
808
809 /// Gets an [`OccupiedEntry`] corresponding to the key for in-place modification.
810 ///
811 /// [`OccupiedEntry`] exclusively owns the entry, preventing others from gaining access to it:
812 /// use [`read_async`](Self::read_async) if read-only access is sufficient.
813 ///
814 /// Returns `None` if the key does not exist. It is an asynchronous method returning an
815 /// `impl Future` for the caller to await.
816 ///
817 /// # Examples
818 ///
819 /// ```
820 /// use scc2::HashMap;
821 ///
822 /// let hashmap: HashMap<u64, u32> = HashMap::default();
823 /// let future_insert = hashmap.insert_async(11, 17);
824 /// let future_get = hashmap.get_async(&11);
825 /// ```
826 #[inline]
827 pub async fn get_async<Q>(&self, key: &Q) -> Option<OccupiedEntry<K, V, H>>
828 where
829 Q: Equivalent<K> + Hash + ?Sized,
830 {
831 let hash = self.hash(key);
832 loop {
833 let mut async_wait = AsyncWait::default();
834 let mut async_wait_pinned = Pin::new(&mut async_wait);
835 if let Ok(result) = self.get_entry(
836 key,
837 hash,
838 &mut async_wait_pinned,
839 self.prolonged_guard_ref(&Guard::new()),
840 ) {
841 if let Some(locked_entry) = result {
842 return Some(OccupiedEntry {
843 hashmap: self,
844 locked_entry,
845 });
846 }
847 return None;
848 }
849 async_wait_pinned.await;
850 }
851 }
852
853 /// Reads a key-value pair.
854 ///
855 /// Returns `None` if the key does not exist.
856 ///
857 /// # Examples
858 ///
859 /// ```
860 /// use scc2::HashMap;
861 ///
862 /// let hashmap: HashMap<u64, u32> = HashMap::default();
863 ///
864 /// assert!(hashmap.read(&1, |_, v| *v).is_none());
865 /// assert!(hashmap.insert(1, 10).is_ok());
866 /// assert_eq!(hashmap.read(&1, |_, v| *v).unwrap(), 10);
867 /// ```
868 #[inline]
869 pub fn read<Q, R, F: FnOnce(&K, &V) -> R>(&self, key: &Q, reader: F) -> Option<R>
870 where
871 Q: Equivalent<K> + Hash + ?Sized,
872 {
873 self.read_entry(key, self.hash(key), reader, &mut (), &Guard::new())
874 .ok()
875 .flatten()
876 }
877
878 /// Reads a key-value pair.
879 ///
880 /// Returns `None` if the key does not exist. It is an asynchronous method returning an
881 /// `impl Future` for the caller to await.
882 ///
883 /// # Examples
884 ///
885 /// ```
886 /// use scc2::HashMap;
887 ///
888 /// let hashmap: HashMap<u64, u32> = HashMap::default();
889 /// let future_insert = hashmap.insert_async(11, 17);
890 /// let future_read = hashmap.read_async(&11, |_, v| *v);
891 /// ```
892 #[inline]
893 pub async fn read_async<Q, R, F: FnOnce(&K, &V) -> R>(
894 &self,
895 key: &Q,
896 mut reader: F,
897 ) -> Option<R>
898 where
899 Q: Equivalent<K> + Hash + ?Sized,
900 {
901 let hash = self.hash(key);
902 loop {
903 let mut async_wait = AsyncWait::default();
904 let mut async_wait_pinned = Pin::new(&mut async_wait);
905 match self.read_entry(key, hash, reader, &mut async_wait_pinned, &Guard::new()) {
906 Ok(result) => return result,
907 Err(f) => reader = f,
908 }
909
910 async_wait_pinned.await;
911 }
912 }
913
914 /// Returns `true` if the [`HashMap`] contains a value for the specified key.
915 ///
916 /// # Examples
917 ///
918 /// ```
919 /// use scc2::HashMap;
920 ///
921 /// let hashmap: HashMap<u64, u32> = HashMap::default();
922 ///
923 /// assert!(!hashmap.contains(&1));
924 /// assert!(hashmap.insert(1, 0).is_ok());
925 /// assert!(hashmap.contains(&1));
926 /// ```
927 #[inline]
928 pub fn contains<Q>(&self, key: &Q) -> bool
929 where
930 Q: Equivalent<K> + Hash + ?Sized,
931 {
932 self.read(key, |_, _| ()).is_some()
933 }
934
935 /// Returns `true` if the [`HashMap`] contains a value for the specified key.
936 ///
937 /// It is an asynchronous method returning an `impl Future` for the caller to await.
938 ///
939 /// # Examples
940 ///
941 /// ```
942 /// use scc2::HashMap;
943 ///
944 /// let hashmap: HashMap<u64, u32> = HashMap::default();
945 ///
946 /// let future_contains = hashmap.contains_async(&1);
947 /// ```
948 #[inline]
949 pub async fn contains_async<Q>(&self, key: &Q) -> bool
950 where
951 Q: Equivalent<K> + Hash + ?Sized,
952 {
953 self.read_async(key, |_, _| ()).await.is_some()
954 }
955
956 /// Scans all the entries.
957 ///
958 /// Key-value pairs that have existed since the invocation of the method are guaranteed to be
959 /// visited if they are not removed, however the same key-value pair can be visited more than
960 /// once if the [`HashMap`] gets resized by another thread.
961 ///
962 /// # Examples
963 ///
964 /// ```
965 /// use scc2::HashMap;
966 ///
967 /// let hashmap: HashMap<usize, usize> = HashMap::default();
968 ///
969 /// assert!(hashmap.insert(1, 0).is_ok());
970 /// assert!(hashmap.insert(2, 1).is_ok());
971 ///
972 /// let mut sum = 0;
973 /// hashmap.scan(|k, v| { sum += *k + *v; });
974 /// assert_eq!(sum, 4);
975 /// ```
976 #[inline]
977 pub fn scan<F: FnMut(&K, &V)>(&self, mut scanner: F) {
978 self.any(|k, v| {
979 scanner(k, v);
980 false
981 });
982 }
983
984 /// Scans all the entries.
985 ///
986 /// Key-value pairs that have existed since the invocation of the method are guaranteed to be
987 /// visited if they are not removed, however the same key-value pair can be visited more than
988 /// once if the [`HashMap`] gets resized by another task.
989 ///
990 /// # Examples
991 ///
992 /// ```
993 /// use scc2::HashMap;
994 ///
995 /// let hashmap: HashMap<usize, usize> = HashMap::default();
996 ///
997 /// let future_insert = hashmap.insert_async(1, 0);
998 /// let future_scan = hashmap.scan_async(|k, v| println!("{k} {v}"));
999 /// ```
1000 #[inline]
1001 pub async fn scan_async<F: FnMut(&K, &V)>(&self, mut scanner: F) {
1002 self.any_async(|k, v| {
1003 scanner(k, v);
1004 false
1005 })
1006 .await;
1007 }
1008
1009 /// Searches for any entry that satisfies the given predicate.
1010 ///
1011 /// Key-value pairs that have existed since the invocation of the method are guaranteed to be
1012 /// visited if they are not removed, however the same key-value pair can be visited more than
1013 /// once if the [`HashMap`] gets resized by another thread.
1014 ///
1015 /// Returns `true` as soon as an entry satisfying the predicate is found.
1016 ///
1017 /// # Examples
1018 ///
1019 /// ```
1020 /// use scc2::HashMap;
1021 ///
1022 /// let hashmap: HashMap<u64, u32> = HashMap::default();
1023 ///
1024 /// assert!(hashmap.insert(1, 0).is_ok());
1025 /// assert!(hashmap.insert(2, 1).is_ok());
1026 /// assert!(hashmap.insert(3, 2).is_ok());
1027 ///
1028 /// assert!(hashmap.any(|k, v| *k == 1 && *v == 0));
1029 /// assert!(!hashmap.any(|k, v| *k == 2 && *v == 0));
1030 /// ```
1031 #[inline]
1032 pub fn any<P: FnMut(&K, &V) -> bool>(&self, pred: P) -> bool {
1033 self.contains_entry(pred)
1034 }
1035
1036 /// Searches for any entry that satisfies the given predicate.
1037 ///
1038 /// Key-value pairs that have existed since the invocation of the method are guaranteed to be
1039 /// visited if they are not removed, however the same key-value pair can be visited more than
1040 /// once if the [`HashMap`] gets resized by another task.
1041 ///
1042 /// It is an asynchronous method returning an `impl Future` for the caller to await.
1043 ///
1044 /// Returns `true` as soon as an entry satisfying the predicate is found.
1045 ///
1046 /// # Examples
1047 ///
1048 /// ```
1049 /// use scc2::HashMap;
1050 ///
1051 /// let hashmap: HashMap<u64, u32> = HashMap::default();
1052 ///
1053 /// let future_insert = hashmap.insert_async(1, 0);
1054 /// let future_any = hashmap.any_async(|k, _| *k == 1);
1055 /// ```
1056 #[inline]
1057 pub async fn any_async<P: FnMut(&K, &V) -> bool>(&self, mut pred: P) -> bool {
1058 let mut current_array_holder = self.array.get_shared(Acquire, &Guard::new());
1059 while let Some(current_array) = current_array_holder.take() {
1060 self.cleanse_old_array_async(¤t_array).await;
1061 for index in 0..current_array.num_buckets() {
1062 loop {
1063 let mut async_wait = AsyncWait::default();
1064 let mut async_wait_pinned = Pin::new(&mut async_wait);
1065 {
1066 let guard = Guard::new();
1067 let bucket = current_array.bucket(index);
1068 if let Ok(reader) =
1069 Reader::try_lock_or_wait(bucket, &mut async_wait_pinned, &guard)
1070 {
1071 if let Some(reader) = reader {
1072 let data_block = current_array.data_block(index);
1073 let mut entry_ptr = EntryPtr::new(&guard);
1074 while entry_ptr.move_to_next(*reader, &guard) {
1075 let (k, v) = entry_ptr.get(data_block);
1076 if pred(k, v) {
1077 // Found one entry satisfying the predicate.
1078 return true;
1079 }
1080 }
1081 }
1082 break;
1083 };
1084 }
1085 async_wait_pinned.await;
1086 }
1087 }
1088
1089 if let Some(new_current_array) = self.array.get_shared(Acquire, &Guard::new()) {
1090 if new_current_array.as_ptr() == current_array.as_ptr() {
1091 break;
1092 }
1093 current_array_holder.replace(new_current_array);
1094 continue;
1095 }
1096 break;
1097 }
1098
1099 false
1100 }
1101
1102 /// Retains the entries specified by the predicate.
1103 ///
1104 /// This method allows the predicate closure to modify the value field.
1105 ///
1106 /// Entries that have existed since the invocation of the method are guaranteed to be visited
1107 /// if they are not removed, however the same entry can be visited more than once if the
1108 /// [`HashMap`] gets resized by another thread.
1109 ///
1110 /// # Examples
1111 ///
1112 /// ```
1113 /// use scc2::HashMap;
1114 ///
1115 /// let hashmap: HashMap<u64, u32> = HashMap::default();
1116 ///
1117 /// assert!(hashmap.insert(1, 0).is_ok());
1118 /// assert!(hashmap.insert(2, 1).is_ok());
1119 /// assert!(hashmap.insert(3, 2).is_ok());
1120 ///
1121 /// hashmap.retain(|k, v| *k == 1 && *v == 0);
1122 ///
1123 /// assert!(hashmap.contains(&1));
1124 /// assert!(!hashmap.contains(&2));
1125 /// assert!(!hashmap.contains(&3));
1126 /// ```
1127 #[inline]
1128 pub fn retain<F: FnMut(&K, &mut V) -> bool>(&self, pred: F) {
1129 self.retain_entries(pred);
1130 }
1131
1132 /// Retains the entries specified by the predicate.
1133 ///
1134 /// This method allows the predicate closure to modify the value field.
1135 ///
1136 /// Entries that have existed since the invocation of the method are guaranteed to be visited
1137 /// if they are not removed, however the same entry can be visited more than once if the
1138 /// [`HashMap`] gets resized by another thread.
1139 ///
1140 /// It is an asynchronous method returning an `impl Future` for the caller to await.
1141 ///
1142 /// # Examples
1143 ///
1144 /// ```
1145 /// use scc2::HashMap;
1146 ///
1147 /// let hashmap: HashMap<u64, u32> = HashMap::default();
1148 ///
1149 /// let future_insert = hashmap.insert_async(1, 0);
1150 /// let future_retain = hashmap.retain_async(|k, v| *k == 1);
1151 /// ```
1152 #[inline]
1153 pub async fn retain_async<F: FnMut(&K, &mut V) -> bool>(&self, mut pred: F) {
1154 let mut removed = false;
1155 let mut current_array_holder = self.array.get_shared(Acquire, &Guard::new());
1156 while let Some(current_array) = current_array_holder.take() {
1157 self.cleanse_old_array_async(¤t_array).await;
1158 for index in 0..current_array.num_buckets() {
1159 loop {
1160 let mut async_wait = AsyncWait::default();
1161 let mut async_wait_pinned = Pin::new(&mut async_wait);
1162 {
1163 let guard = Guard::new();
1164 let bucket = current_array.bucket_mut(index);
1165 if let Ok(locker) =
1166 Locker::try_lock_or_wait(bucket, &mut async_wait_pinned, &guard)
1167 {
1168 if let Some(mut locker) = locker {
1169 let data_block_mut = current_array.data_block_mut(index);
1170 let mut entry_ptr = EntryPtr::new(&guard);
1171 while entry_ptr.move_to_next(&locker, &guard) {
1172 let (k, v) = entry_ptr.get_mut(data_block_mut, &mut locker);
1173 if !pred(k, v) {
1174 locker.remove(data_block_mut, &mut entry_ptr, &guard);
1175 removed = true;
1176 }
1177 }
1178 }
1179 break;
1180 };
1181 }
1182 async_wait_pinned.await;
1183 }
1184 }
1185
1186 if let Some(new_current_array) = self.array.get_shared(Acquire, &Guard::new()) {
1187 if new_current_array.as_ptr() == current_array.as_ptr() {
1188 break;
1189 }
1190 current_array_holder.replace(new_current_array);
1191 continue;
1192 }
1193 break;
1194 }
1195
1196 if removed {
1197 self.try_resize(0, &Guard::new());
1198 }
1199 }
1200
1201 /// Prunes the entries specified by the predicate.
1202 ///
1203 /// If the value is consumed by the predicate, in other words, if the predicate returns `None`,
1204 /// the entry is removed, otherwise the entry is retained.
1205 ///
1206 /// Entries that have existed since the invocation of the method are guaranteed to be visited
1207 /// if they are not removed, however the same entry can be visited more than once if the
1208 /// [`HashMap`] gets resized by another thread.
1209 ///
1210 /// # Examples
1211 ///
1212 /// ```
1213 /// use scc2::HashMap;
1214 ///
1215 /// let hashmap: HashMap<u64, String> = HashMap::default();
1216 ///
1217 /// assert!(hashmap.insert(1, String::from("1")).is_ok());
1218 /// assert!(hashmap.insert(2, String::from("2")).is_ok());
1219 /// assert!(hashmap.insert(3, String::from("3")).is_ok());
1220 ///
1221 /// hashmap.prune(|k, v| if *k == 1 { Some(v) } else { None });
1222 /// assert_eq!(hashmap.len(), 1);
1223 /// ```
1224 #[inline]
1225 pub fn prune<F: FnMut(&K, V) -> Option<V>>(&self, pred: F) {
1226 self.prune_entries(pred);
1227 }
1228
1229 /// Prunes the entries specified by the predicate.
1230 ///
1231 /// If the value is consumed by the predicate, in other words, if the predicate returns `None`,
1232 /// the entry is removed, otherwise the entry is retained.
1233 ///
1234 /// Entries that have existed since the invocation of the method are guaranteed to be visited
1235 /// if they are not removed, however the same entry can be visited more than once if the
1236 /// [`HashMap`] gets resized by another thread.
1237 ///
1238 /// It is an asynchronous method returning an `impl Future` for the caller to await.
1239 ///
1240 /// # Examples
1241 ///
1242 /// ```
1243 /// use scc2::HashMap;
1244 ///
1245 /// let hashmap: HashMap<u64, u32> = HashMap::default();
1246 ///
1247 /// let future_insert = hashmap.insert_async(1, 0);
1248 /// let future_prune = hashmap.prune_async(|k, v| if *k == 1 { Some(v) } else { None });
1249 /// ```
1250 #[inline]
1251 pub async fn prune_async<F: FnMut(&K, V) -> Option<V>>(&self, mut pred: F) {
1252 let mut removed = false;
1253 let mut current_array_holder = self.array.get_shared(Acquire, &Guard::new());
1254 while let Some(current_array) = current_array_holder.take() {
1255 self.cleanse_old_array_async(¤t_array).await;
1256 for index in 0..current_array.num_buckets() {
1257 loop {
1258 let mut async_wait = AsyncWait::default();
1259 let mut async_wait_pinned = Pin::new(&mut async_wait);
1260 {
1261 let guard = Guard::new();
1262 let bucket = current_array.bucket_mut(index);
1263 if let Ok(locker) =
1264 Locker::try_lock_or_wait(bucket, &mut async_wait_pinned, &guard)
1265 {
1266 if let Some(mut locker) = locker {
1267 let data_block_mut = current_array.data_block_mut(index);
1268 let mut entry_ptr = EntryPtr::new(&guard);
1269 while entry_ptr.move_to_next(&locker, &guard) {
1270 if locker.keep_or_consume(
1271 data_block_mut,
1272 &mut entry_ptr,
1273 &mut pred,
1274 &guard,
1275 ) {
1276 removed = true;
1277 }
1278 }
1279 }
1280 break;
1281 };
1282 }
1283 async_wait_pinned.await;
1284 }
1285 }
1286
1287 if let Some(new_current_array) = self.array.get_shared(Acquire, &Guard::new()) {
1288 if new_current_array.as_ptr() == current_array.as_ptr() {
1289 break;
1290 }
1291 current_array_holder.replace(new_current_array);
1292 continue;
1293 }
1294 break;
1295 }
1296
1297 if removed {
1298 self.try_resize(0, &Guard::new());
1299 }
1300 }
1301
1302 /// Clears the [`HashMap`] by removing all key-value pairs.
1303 ///
1304 /// # Examples
1305 ///
1306 /// ```
1307 /// use scc2::HashMap;
1308 ///
1309 /// let hashmap: HashMap<u64, u32> = HashMap::default();
1310 ///
1311 /// assert!(hashmap.insert(1, 0).is_ok());
1312 /// hashmap.clear();
1313 ///
1314 /// assert!(!hashmap.contains(&1));
1315 /// ```
1316 #[inline]
1317 pub fn clear(&self) {
1318 self.retain(|_, _| false);
1319 }
1320
1321 /// Clears the [`HashMap`] by removing all key-value pairs.
1322 ///
1323 /// It is an asynchronous method returning an `impl Future` for the caller to await.
1324 ///
1325 /// # Examples
1326 ///
1327 /// ```
1328 /// use scc2::HashMap;
1329 ///
1330 /// let hashmap: HashMap<u64, u32> = HashMap::default();
1331 ///
1332 /// let future_insert = hashmap.insert_async(1, 0);
1333 /// let future_clear = hashmap.clear_async();
1334 /// ```
1335 #[inline]
1336 pub async fn clear_async(&self) {
1337 self.retain_async(|_, _| false).await;
1338 }
1339
1340 /// Returns the number of entries in the [`HashMap`].
1341 ///
1342 /// It reads the entire metadata area of the bucket array to calculate the number of valid
1343 /// entries, making its time complexity `O(N)`. Furthermore, it may overcount entries if an old
1344 /// bucket array has yet to be dropped.
1345 ///
1346 /// # Examples
1347 ///
1348 /// ```
1349 /// use scc2::HashMap;
1350 ///
1351 /// let hashmap: HashMap<u64, u32> = HashMap::default();
1352 ///
1353 /// assert!(hashmap.insert(1, 0).is_ok());
1354 /// assert_eq!(hashmap.len(), 1);
1355 /// ```
1356 #[inline]
1357 pub fn len(&self) -> usize {
1358 self.num_entries(&Guard::new())
1359 }
1360
1361 /// Returns `true` if the [`HashMap`] is empty.
1362 ///
1363 /// # Examples
1364 ///
1365 /// ```
1366 /// use scc2::HashMap;
1367 ///
1368 /// let hashmap: HashMap<u64, u32> = HashMap::default();
1369 ///
1370 /// assert!(hashmap.is_empty());
1371 /// assert!(hashmap.insert(1, 0).is_ok());
1372 /// assert!(!hashmap.is_empty());
1373 /// ```
1374 #[inline]
1375 pub fn is_empty(&self) -> bool {
1376 !self.has_entry(&Guard::new())
1377 }
1378
1379 /// Returns the capacity of the [`HashMap`].
1380 ///
1381 /// # Examples
1382 ///
1383 /// ```
1384 /// use scc2::HashMap;
1385 ///
1386 /// let hashmap_default: HashMap<u64, u32> = HashMap::default();
1387 /// assert_eq!(hashmap_default.capacity(), 0);
1388 ///
1389 /// assert!(hashmap_default.insert(1, 0).is_ok());
1390 /// assert_eq!(hashmap_default.capacity(), 64);
1391 ///
1392 /// let hashmap: HashMap<u64, u32> = HashMap::with_capacity(1000);
1393 /// assert_eq!(hashmap.capacity(), 1024);
1394 /// ```
1395 #[inline]
1396 pub fn capacity(&self) -> usize {
1397 self.num_slots(&Guard::new())
1398 }
1399
1400 /// Returns the current capacity range of the [`HashMap`].
1401 ///
1402 /// # Examples
1403 ///
1404 /// ```
1405 /// use scc2::HashMap;
1406 ///
1407 /// let hashmap: HashMap<u64, u32> = HashMap::default();
1408 ///
1409 /// assert_eq!(hashmap.capacity_range(), 0..=(1_usize << (usize::BITS - 1)));
1410 ///
1411 /// let reserved = hashmap.reserve(1000);
1412 /// assert_eq!(hashmap.capacity_range(), 1000..=(1_usize << (usize::BITS - 1)));
1413 /// ```
1414 #[inline]
1415 pub fn capacity_range(&self) -> RangeInclusive<usize> {
1416 self.minimum_capacity.load(Relaxed)..=self.maximum_capacity()
1417 }
1418
1419 /// Returns the index of the bucket that may contain the key.
1420 ///
1421 /// The method returns the index of the bucket associated with the key. The number of buckets
1422 /// can be calculated by dividing `32` into the capacity.
1423 ///
1424 /// # Examples
1425 ///
1426 /// ```
1427 /// use scc2::HashMap;
1428 ///
1429 /// let hashmap: HashMap<u64, u32> = HashMap::with_capacity(1024);
1430 ///
1431 /// let bucket_index = hashmap.bucket_index(&11);
1432 /// assert!(bucket_index < hashmap.capacity() / 32);
1433 /// ```
1434 #[inline]
1435 pub fn bucket_index<Q>(&self, key: &Q) -> usize
1436 where
1437 Q: Equivalent<K> + Hash + ?Sized,
1438 {
1439 self.calculate_bucket_index(key)
1440 }
1441
1442 /// Clears the old array asynchronously.
1443 async fn cleanse_old_array_async(&self, current_array: &BucketArray<K, V, (), SEQUENTIAL>) {
1444 while current_array.has_old_array() {
1445 let mut async_wait = AsyncWait::default();
1446 let mut async_wait_pinned = Pin::new(&mut async_wait);
1447 if self.incremental_rehash::<K, _, false>(
1448 current_array,
1449 &mut async_wait_pinned,
1450 &Guard::new(),
1451 ) == Ok(true)
1452 {
1453 break;
1454 }
1455 async_wait_pinned.await;
1456 }
1457 }
1458}
1459
1460impl<K, V> HashMap<K, V, RandomState>
1461where
1462 K: Eq + Hash,
1463{
1464 /// Creates an empty default [`HashMap`].
1465 ///
1466 /// # Examples
1467 ///
1468 /// ```
1469 /// use scc2::HashMap;
1470 ///
1471 /// let hashmap: HashMap<u64, u32> = HashMap::new();
1472 ///
1473 /// let result = hashmap.capacity();
1474 /// assert_eq!(result, 0);
1475 /// ```
1476 #[inline]
1477 #[must_use]
1478 pub fn new() -> Self {
1479 Self::default()
1480 }
1481
1482 /// Creates an empty [`HashMap`] with the specified capacity.
1483 ///
1484 /// The actual capacity is equal to or greater than the specified capacity.
1485 ///
1486 /// # Examples
1487 ///
1488 /// ```
1489 /// use scc2::HashMap;
1490 ///
1491 /// let hashmap: HashMap<u64, u32> = HashMap::with_capacity(1000);
1492 ///
1493 /// let result = hashmap.capacity();
1494 /// assert_eq!(result, 1024);
1495 /// ```
1496 #[inline]
1497 #[must_use]
1498 pub fn with_capacity(capacity: usize) -> Self {
1499 Self::with_capacity_and_hasher(capacity, RandomState::new())
1500 }
1501}
1502
1503impl<K, V, H> Clone for HashMap<K, V, H>
1504where
1505 K: Clone + Eq + Hash,
1506 V: Clone,
1507 H: BuildHasher + Clone,
1508{
1509 #[inline]
1510 fn clone(&self) -> Self {
1511 let self_clone = Self::with_capacity_and_hasher(self.capacity(), self.hasher().clone());
1512 self.scan(|k, v| {
1513 let _reuslt = self_clone.insert(k.clone(), v.clone());
1514 });
1515 self_clone
1516 }
1517}
1518
1519impl<K, V, H> Debug for HashMap<K, V, H>
1520where
1521 K: Debug + Eq + Hash,
1522 V: Debug,
1523 H: BuildHasher,
1524{
1525 /// Iterates over all the entries in the [`HashMap`] to print them.
1526 ///
1527 /// ## Locking behavior
1528 ///
1529 /// Shared locks on buckets are acquired during iteration, therefore any [`Entry`],
1530 /// [`OccupiedEntry`] or [`VacantEntry`] owned by the current thread will lead to a deadlock.
1531 #[inline]
1532 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1533 let mut d = f.debug_map();
1534 self.scan(|k, v| {
1535 d.entry(k, v);
1536 });
1537 d.finish()
1538 }
1539}
1540
1541impl<K, V, H> Default for HashMap<K, V, H>
1542where
1543 H: BuildHasher + Default,
1544{
1545 /// Creates an empty default [`HashMap`].
1546 ///
1547 /// # Examples
1548 ///
1549 /// ```
1550 /// use scc2::HashMap;
1551 ///
1552 /// let hashmap: HashMap<u64, u32> = HashMap::default();
1553 ///
1554 /// let result = hashmap.capacity();
1555 /// assert_eq!(result, 0);
1556 /// ```
1557 #[inline]
1558 fn default() -> Self {
1559 Self::with_hasher(H::default())
1560 }
1561}
1562
1563impl<K, V, H> Drop for HashMap<K, V, H>
1564where
1565 H: BuildHasher,
1566{
1567 #[inline]
1568 fn drop(&mut self) {
1569 self.array
1570 .swap((None, Tag::None), Relaxed)
1571 .0
1572 .map(|a| unsafe {
1573 // The entire array does not need to wait for an epoch change as no references will
1574 // remain outside the lifetime of the `HashMap`.
1575 a.drop_in_place()
1576 });
1577 }
1578}
1579
1580impl<K, V, H> FromIterator<(K, V)> for HashMap<K, V, H>
1581where
1582 K: Eq + Hash,
1583 H: BuildHasher + Default,
1584{
1585 #[inline]
1586 fn from_iter<T: IntoIterator<Item = (K, V)>>(iter: T) -> Self {
1587 let into_iter = iter.into_iter();
1588 let hashmap = Self::with_capacity_and_hasher(
1589 Self::capacity_from_size_hint(into_iter.size_hint()),
1590 H::default(),
1591 );
1592 into_iter.for_each(|e| {
1593 hashmap.upsert(e.0, e.1);
1594 });
1595 hashmap
1596 }
1597}
1598
1599impl<K, V, H> HashTable<K, V, H, (), SEQUENTIAL> for HashMap<K, V, H>
1600where
1601 K: Eq + Hash,
1602 H: BuildHasher,
1603{
1604 #[inline]
1605 fn hasher(&self) -> &H {
1606 &self.build_hasher
1607 }
1608 #[inline]
1609 fn try_clone(_: &(K, V)) -> Option<(K, V)> {
1610 None
1611 }
1612 #[inline]
1613 fn bucket_array(&self) -> &AtomicShared<BucketArray<K, V, (), SEQUENTIAL>> {
1614 &self.array
1615 }
1616 #[inline]
1617 fn minimum_capacity(&self) -> &AtomicUsize {
1618 &self.minimum_capacity
1619 }
1620 #[inline]
1621 fn maximum_capacity(&self) -> usize {
1622 1_usize << (usize::BITS - 1)
1623 }
1624}
1625
1626impl<K, V, H> PartialEq for HashMap<K, V, H>
1627where
1628 K: Eq + Hash,
1629 V: PartialEq,
1630 H: BuildHasher,
1631{
1632 /// Compares two [`HashMap`] instances.
1633 ///
1634 /// ## Locking behavior
1635 ///
1636 /// Shared locks on buckets are acquired when comparing two instances of [`HashMap`], therefore
1637 /// it may lead to a deadlock if the instances are being modified by another thread.
1638 #[inline]
1639 fn eq(&self, other: &Self) -> bool {
1640 if !self.any(|k, v| other.read(k, |_, ov| v == ov) != Some(true)) {
1641 return !other.any(|k, v| self.read(k, |_, sv| v == sv) != Some(true));
1642 }
1643 false
1644 }
1645}
1646
1647impl<'h, K, V, H> Entry<'h, K, V, H>
1648where
1649 K: Eq + Hash,
1650 H: BuildHasher,
1651{
1652 /// Ensures a value is in the entry by inserting the supplied instance if empty.
1653 ///
1654 /// # Examples
1655 ///
1656 /// ```
1657 /// use scc2::HashMap;
1658 ///
1659 /// let hashmap: HashMap<u64, u32> = HashMap::default();
1660 ///
1661 /// hashmap.entry(3).or_insert(7);
1662 /// assert_eq!(hashmap.read(&3, |_, v| *v), Some(7));
1663 /// ```
1664 #[inline]
1665 pub fn or_insert(self, val: V) -> OccupiedEntry<'h, K, V, H> {
1666 self.or_insert_with(|| val)
1667 }
1668
1669 /// Ensures a value is in the entry by inserting the result of the supplied closure if empty.
1670 ///
1671 /// # Examples
1672 ///
1673 /// ```
1674 /// use scc2::HashMap;
1675 ///
1676 /// let hashmap: HashMap<u64, u32> = HashMap::default();
1677 ///
1678 /// hashmap.entry(19).or_insert_with(|| 5);
1679 /// assert_eq!(hashmap.read(&19, |_, v| *v), Some(5));
1680 /// ```
1681 #[inline]
1682 pub fn or_insert_with<F: FnOnce() -> V>(self, constructor: F) -> OccupiedEntry<'h, K, V, H> {
1683 self.or_insert_with_key(|_| constructor())
1684 }
1685
1686 /// Ensures a value is in the entry by inserting the result of the supplied closure if empty.
1687 ///
1688 /// The reference to the moved key is provided, therefore cloning or copying the key is
1689 /// unnecessary.
1690 ///
1691 /// # Examples
1692 ///
1693 /// ```
1694 /// use scc2::HashMap;
1695 ///
1696 /// let hashmap: HashMap<u64, u32> = HashMap::default();
1697 ///
1698 /// hashmap.entry(11).or_insert_with_key(|k| if *k == 11 { 7 } else { 3 });
1699 /// assert_eq!(hashmap.read(&11, |_, v| *v), Some(7));
1700 /// ```
1701 #[inline]
1702 pub fn or_insert_with_key<F: FnOnce(&K) -> V>(
1703 self,
1704 constructor: F,
1705 ) -> OccupiedEntry<'h, K, V, H> {
1706 match self {
1707 Self::Occupied(o) => o,
1708 Self::Vacant(v) => {
1709 let val = constructor(v.key());
1710 v.insert_entry(val)
1711 }
1712 }
1713 }
1714
1715 /// Returns a reference to the key of this entry.
1716 ///
1717 /// # Examples
1718 ///
1719 /// ```
1720 /// use scc2::HashMap;
1721 ///
1722 /// let hashmap: HashMap<u64, u32> = HashMap::default();
1723 /// assert_eq!(hashmap.entry(31).key(), &31);
1724 /// ```
1725 #[inline]
1726 pub fn key(&self) -> &K {
1727 match self {
1728 Self::Occupied(o) => o.key(),
1729 Self::Vacant(v) => v.key(),
1730 }
1731 }
1732
1733 /// Provides in-place mutable access to an occupied entry.
1734 ///
1735 /// # Examples
1736 ///
1737 /// ```
1738 /// use scc2::HashMap;
1739 ///
1740 /// let hashmap: HashMap<u64, u32> = HashMap::default();
1741 ///
1742 /// hashmap.entry(37).and_modify(|v| { *v += 1 }).or_insert(47);
1743 /// assert_eq!(hashmap.read(&37, |_, v| *v), Some(47));
1744 ///
1745 /// hashmap.entry(37).and_modify(|v| { *v += 1 }).or_insert(3);
1746 /// assert_eq!(hashmap.read(&37, |_, v| *v), Some(48));
1747 /// ```
1748 #[inline]
1749 #[must_use]
1750 pub fn and_modify<F>(self, f: F) -> Self
1751 where
1752 F: FnOnce(&mut V),
1753 {
1754 match self {
1755 Self::Occupied(mut o) => {
1756 f(o.get_mut());
1757 Self::Occupied(o)
1758 }
1759 Self::Vacant(_) => self,
1760 }
1761 }
1762
1763 /// Sets the value of the entry.
1764 ///
1765 /// # Examples
1766 ///
1767 /// ```
1768 /// use scc2::HashMap;
1769 ///
1770 /// let hashmap: HashMap<u64, u32> = HashMap::default();
1771 /// let entry = hashmap.entry(11).insert_entry(17);
1772 /// assert_eq!(entry.key(), &11);
1773 /// ```
1774 #[inline]
1775 pub fn insert_entry(self, val: V) -> OccupiedEntry<'h, K, V, H> {
1776 match self {
1777 Self::Occupied(mut o) => {
1778 o.insert(val);
1779 o
1780 }
1781 Self::Vacant(v) => v.insert_entry(val),
1782 }
1783 }
1784}
1785
1786impl<'h, K, V, H> Entry<'h, K, V, H>
1787where
1788 K: Eq + Hash,
1789 V: Default,
1790 H: BuildHasher,
1791{
1792 /// Ensures a value is in the entry by inserting the default value if empty.
1793 ///
1794 /// # Examples
1795 ///
1796 /// ```
1797 /// use scc2::HashMap;
1798 ///
1799 /// let hashmap: HashMap<u64, u32> = HashMap::default();
1800 /// hashmap.entry(11).or_default();
1801 /// assert_eq!(hashmap.read(&11, |_, v| *v), Some(0));
1802 /// ```
1803 #[inline]
1804 pub fn or_default(self) -> OccupiedEntry<'h, K, V, H> {
1805 match self {
1806 Self::Occupied(o) => o,
1807 Self::Vacant(v) => v.insert_entry(Default::default()),
1808 }
1809 }
1810}
1811
1812impl<K, V, H> Debug for Entry<'_, K, V, H>
1813where
1814 K: Debug + Eq + Hash,
1815 V: Debug,
1816 H: BuildHasher,
1817{
1818 #[inline]
1819 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1820 match self {
1821 Self::Vacant(v) => f.debug_tuple("Entry").field(v).finish(),
1822 Self::Occupied(o) => f.debug_tuple("Entry").field(o).finish(),
1823 }
1824 }
1825}
1826
1827impl<'h, K, V, H> OccupiedEntry<'h, K, V, H>
1828where
1829 K: Eq + Hash,
1830 H: BuildHasher,
1831{
1832 /// Gets a reference to the key in the entry.
1833 ///
1834 /// # Examples
1835 ///
1836 /// ```
1837 /// use scc2::HashMap;
1838 ///
1839 /// let hashmap: HashMap<u64, u32> = HashMap::default();
1840 ///
1841 /// assert_eq!(hashmap.entry(29).or_default().key(), &29);
1842 /// ```
1843 #[inline]
1844 #[must_use]
1845 pub fn key(&self) -> &K {
1846 &self
1847 .locked_entry
1848 .entry_ptr
1849 .get(self.locked_entry.data_block_mut)
1850 .0
1851 }
1852
1853 /// Takes ownership of the key and value from the [`HashMap`].
1854 ///
1855 /// # Examples
1856 ///
1857 /// ```
1858 /// use scc2::HashMap;
1859 /// use scc2::hash_map::Entry;
1860 ///
1861 /// let hashmap: HashMap<u64, u32> = HashMap::default();
1862 ///
1863 /// hashmap.entry(11).or_insert(17);
1864 ///
1865 /// if let Entry::Occupied(o) = hashmap.entry(11) {
1866 /// assert_eq!(o.remove_entry(), (11, 17));
1867 /// };
1868 /// ```
1869 #[inline]
1870 #[must_use]
1871 pub fn remove_entry(mut self) -> (K, V) {
1872 let guard = Guard::new();
1873 let entry = self.locked_entry.locker.remove(
1874 self.locked_entry.data_block_mut,
1875 &mut self.locked_entry.entry_ptr,
1876 self.hashmap.prolonged_guard_ref(&guard),
1877 );
1878 if self.locked_entry.locker.num_entries() <= 1 || self.locked_entry.locker.need_rebuild() {
1879 let hashmap = self.hashmap;
1880 if let Some(current_array) = hashmap.bucket_array().load(Acquire, &guard).as_ref() {
1881 if !current_array.has_old_array() {
1882 let index = self.locked_entry.index;
1883 if current_array.within_sampling_range(index) {
1884 drop(self);
1885 hashmap.try_shrink_or_rebuild(current_array, index, &guard);
1886 }
1887 }
1888 }
1889 }
1890 entry
1891 }
1892
1893 /// Gets a reference to the value in the entry.
1894 ///
1895 /// # Examples
1896 ///
1897 /// ```
1898 /// use scc2::HashMap;
1899 /// use scc2::hash_map::Entry;
1900 ///
1901 /// let hashmap: HashMap<u64, u32> = HashMap::default();
1902 ///
1903 /// hashmap.entry(19).or_insert(11);
1904 ///
1905 /// if let Entry::Occupied(o) = hashmap.entry(19) {
1906 /// assert_eq!(o.get(), &11);
1907 /// };
1908 /// ```
1909 #[inline]
1910 #[must_use]
1911 pub fn get(&self) -> &V {
1912 &self
1913 .locked_entry
1914 .entry_ptr
1915 .get(self.locked_entry.data_block_mut)
1916 .1
1917 }
1918
1919 /// Gets a mutable reference to the value in the entry.
1920 ///
1921 /// # Examples
1922 ///
1923 /// ```
1924 /// use scc2::HashMap;
1925 /// use scc2::hash_map::Entry;
1926 ///
1927 /// let hashmap: HashMap<u64, u32> = HashMap::default();
1928 ///
1929 /// hashmap.entry(37).or_insert(11);
1930 ///
1931 /// if let Entry::Occupied(mut o) = hashmap.entry(37) {
1932 /// *o.get_mut() += 18;
1933 /// assert_eq!(*o.get(), 29);
1934 /// }
1935 ///
1936 /// assert_eq!(hashmap.read(&37, |_, v| *v), Some(29));
1937 /// ```
1938 #[inline]
1939 pub fn get_mut(&mut self) -> &mut V {
1940 &mut self
1941 .locked_entry
1942 .entry_ptr
1943 .get_mut(
1944 self.locked_entry.data_block_mut,
1945 &mut self.locked_entry.locker,
1946 )
1947 .1
1948 }
1949
1950 /// Sets the value of the entry, and returns the old value.
1951 ///
1952 /// # Examples
1953 ///
1954 /// ```
1955 /// use scc2::HashMap;
1956 /// use scc2::hash_map::Entry;
1957 ///
1958 /// let hashmap: HashMap<u64, u32> = HashMap::default();
1959 ///
1960 /// hashmap.entry(37).or_insert(11);
1961 ///
1962 /// if let Entry::Occupied(mut o) = hashmap.entry(37) {
1963 /// assert_eq!(o.insert(17), 11);
1964 /// }
1965 ///
1966 /// assert_eq!(hashmap.read(&37, |_, v| *v), Some(17));
1967 /// ```
1968 #[inline]
1969 pub fn insert(&mut self, val: V) -> V {
1970 replace(self.get_mut(), val)
1971 }
1972
1973 /// Takes the value out of the entry, and returns it.
1974 ///
1975 /// # Examples
1976 ///
1977 /// ```
1978 /// use scc2::HashMap;
1979 /// use scc2::hash_map::Entry;
1980 ///
1981 /// let hashmap: HashMap<u64, u32> = HashMap::default();
1982 ///
1983 /// hashmap.entry(11).or_insert(17);
1984 ///
1985 /// if let Entry::Occupied(o) = hashmap.entry(11) {
1986 /// assert_eq!(o.remove(), 17);
1987 /// };
1988 /// ```
1989 #[inline]
1990 #[must_use]
1991 pub fn remove(self) -> V {
1992 self.remove_entry().1
1993 }
1994
1995 /// Gets the next closest occupied entry.
1996 ///
1997 /// [`HashMap::first_entry`], [`HashMap::first_entry_async`], and this method together enables
1998 /// the [`OccupiedEntry`] to effectively act as a mutable iterator over entries. The method
1999 /// never acquires more than one lock even when it searches other buckets for the next closest
2000 /// occupied entry.
2001 ///
2002 /// # Examples
2003 ///
2004 /// ```
2005 /// use scc2::HashMap;
2006 /// use scc2::hash_map::Entry;
2007 ///
2008 /// let hashmap: HashMap<u64, u32> = HashMap::default();
2009 ///
2010 /// assert!(hashmap.insert(1, 0).is_ok());
2011 /// assert!(hashmap.insert(2, 0).is_ok());
2012 ///
2013 /// let first_entry = hashmap.first_entry().unwrap();
2014 /// let first_key = *first_entry.key();
2015 /// let second_entry = first_entry.next().unwrap();
2016 /// let second_key = *second_entry.key();
2017 ///
2018 /// assert!(second_entry.next().is_none());
2019 /// assert_eq!(first_key + second_key, 3);
2020 /// ```
2021 #[inline]
2022 #[must_use]
2023 pub fn next(self) -> Option<Self> {
2024 let hashmap = self.hashmap;
2025 if let Some(locked_entry) = self.locked_entry.next(hashmap) {
2026 return Some(OccupiedEntry {
2027 hashmap,
2028 locked_entry,
2029 });
2030 }
2031 None
2032 }
2033
2034 /// Gets the next closest occupied entry.
2035 ///
2036 /// [`HashMap::first_entry`], [`HashMap::first_entry_async`], and this method together enables
2037 /// the [`OccupiedEntry`] to effectively act as a mutable iterator over entries. The method
2038 /// never acquires more than one lock even when it searches other buckets for the next closest
2039 /// occupied entry.
2040 ///
2041 /// It is an asynchronous method returning an `impl Future` for the caller to await.
2042 ///
2043 /// # Examples
2044 ///
2045 /// ```
2046 /// use scc2::HashMap;
2047 /// use scc2::hash_map::Entry;
2048 ///
2049 /// let hashmap: HashMap<u64, u32> = HashMap::default();
2050 ///
2051 /// assert!(hashmap.insert(1, 0).is_ok());
2052 /// assert!(hashmap.insert(2, 0).is_ok());
2053 ///
2054 /// let second_entry_future = hashmap.first_entry().unwrap().next_async();
2055 /// ```
2056 #[inline]
2057 pub async fn next_async(self) -> Option<OccupiedEntry<'h, K, V, H>> {
2058 let hashmap = self.hashmap;
2059 if let Some(locked_entry) = self.locked_entry.next_async(hashmap).await {
2060 return Some(OccupiedEntry {
2061 hashmap,
2062 locked_entry,
2063 });
2064 }
2065 None
2066 }
2067}
2068
2069impl<K, V, H> Debug for OccupiedEntry<'_, K, V, H>
2070where
2071 K: Debug + Eq + Hash,
2072 V: Debug,
2073 H: BuildHasher,
2074{
2075 #[inline]
2076 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
2077 f.debug_struct("OccupiedEntry")
2078 .field("key", self.key())
2079 .field("value", self.get())
2080 .finish_non_exhaustive()
2081 }
2082}
2083
2084impl<K, V, H> Deref for OccupiedEntry<'_, K, V, H>
2085where
2086 K: Eq + Hash,
2087 H: BuildHasher,
2088{
2089 type Target = V;
2090
2091 #[inline]
2092 fn deref(&self) -> &Self::Target {
2093 self.get()
2094 }
2095}
2096
2097impl<K, V, H> DerefMut for OccupiedEntry<'_, K, V, H>
2098where
2099 K: Eq + Hash,
2100 H: BuildHasher,
2101{
2102 #[inline]
2103 fn deref_mut(&mut self) -> &mut Self::Target {
2104 self.get_mut()
2105 }
2106}
2107
2108impl<'h, K, V, H> VacantEntry<'h, K, V, H>
2109where
2110 K: Eq + Hash,
2111 H: BuildHasher,
2112{
2113 /// Gets a reference to the key.
2114 ///
2115 /// # Examples
2116 ///
2117 /// ```
2118 /// use scc2::HashMap;
2119 ///
2120 /// let hashmap: HashMap<u64, u32> = HashMap::default();
2121 /// assert_eq!(hashmap.entry(11).key(), &11);
2122 /// ```
2123 #[inline]
2124 pub fn key(&self) -> &K {
2125 &self.key
2126 }
2127
2128 /// Takes ownership of the key.
2129 ///
2130 /// # Examples
2131 ///
2132 /// ```
2133 /// use scc2::HashMap;
2134 /// use scc2::hash_map::Entry;
2135 ///
2136 /// let hashmap: HashMap<u64, u32> = HashMap::default();
2137 ///
2138 /// if let Entry::Vacant(v) = hashmap.entry(17) {
2139 /// assert_eq!(v.into_key(), 17);
2140 /// };
2141 /// ```
2142 #[inline]
2143 pub fn into_key(self) -> K {
2144 self.key
2145 }
2146
2147 /// Sets the value of the entry with its key, and returns an [`OccupiedEntry`].
2148 ///
2149 /// # Examples
2150 ///
2151 /// ```
2152 /// use scc2::HashMap;
2153 /// use scc2::hash_map::Entry;
2154 ///
2155 /// let hashmap: HashMap<u64, u32> = HashMap::default();
2156 ///
2157 /// if let Entry::Vacant(o) = hashmap.entry(19) {
2158 /// o.insert_entry(29);
2159 /// }
2160 ///
2161 /// assert_eq!(hashmap.read(&19, |_, v| *v), Some(29));
2162 /// ```
2163 #[inline]
2164 pub fn insert_entry(mut self, val: V) -> OccupiedEntry<'h, K, V, H> {
2165 let guard = Guard::new();
2166 let entry_ptr = self.locked_entry.locker.insert_with(
2167 self.locked_entry.data_block_mut,
2168 BucketArray::<K, V, (), SEQUENTIAL>::partial_hash(self.hash),
2169 || (self.key, val),
2170 self.hashmap.prolonged_guard_ref(&guard),
2171 );
2172 OccupiedEntry {
2173 hashmap: self.hashmap,
2174 locked_entry: LockedEntry {
2175 index: self.locked_entry.index,
2176 data_block_mut: self.locked_entry.data_block_mut,
2177 locker: self.locked_entry.locker,
2178 entry_ptr,
2179 },
2180 }
2181 }
2182}
2183
2184impl<K, V, H> Debug for VacantEntry<'_, K, V, H>
2185where
2186 K: Debug + Eq + Hash,
2187 V: Debug,
2188 H: BuildHasher,
2189{
2190 #[inline]
2191 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
2192 f.debug_tuple("VacantEntry").field(self.key()).finish()
2193 }
2194}
2195
2196impl<K, V, H> Reserve<'_, K, V, H>
2197where
2198 K: Eq + Hash,
2199 H: BuildHasher,
2200{
2201 /// Returns the number of reserved slots.
2202 #[inline]
2203 #[must_use]
2204 pub fn additional_capacity(&self) -> usize {
2205 self.additional
2206 }
2207}
2208
2209impl<K, V, H> AsRef<HashMap<K, V, H>> for Reserve<'_, K, V, H>
2210where
2211 K: Eq + Hash,
2212 H: BuildHasher,
2213{
2214 #[inline]
2215 fn as_ref(&self) -> &HashMap<K, V, H> {
2216 self.hashmap
2217 }
2218}
2219
2220impl<K, V, H> Debug for Reserve<'_, K, V, H>
2221where
2222 K: Eq + Hash,
2223 H: BuildHasher,
2224{
2225 #[inline]
2226 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
2227 f.debug_tuple("Reserve").field(&self.additional).finish()
2228 }
2229}
2230
2231impl<K, V, H> Deref for Reserve<'_, K, V, H>
2232where
2233 K: Eq + Hash,
2234 H: BuildHasher,
2235{
2236 type Target = HashMap<K, V, H>;
2237
2238 #[inline]
2239 fn deref(&self) -> &Self::Target {
2240 self.hashmap
2241 }
2242}
2243
2244impl<K, V, H> Drop for Reserve<'_, K, V, H>
2245where
2246 K: Eq + Hash,
2247 H: BuildHasher,
2248{
2249 #[inline]
2250 fn drop(&mut self) {
2251 let result = self
2252 .hashmap
2253 .minimum_capacity
2254 .fetch_sub(self.additional, Relaxed);
2255 self.hashmap.try_resize(0, &Guard::new());
2256 debug_assert!(result >= self.additional);
2257 }
2258}