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