dashmap/
lib.rs

1#![allow(clippy::type_complexity)]
2
3#[cfg(feature = "arbitrary")]
4mod arbitrary;
5pub mod iter;
6pub mod iter_set;
7mod lock;
8pub mod mapref;
9mod read_only;
10#[cfg(feature = "serde")]
11mod serde;
12mod set;
13pub mod setref;
14mod t;
15pub mod try_result;
16mod util;
17
18#[cfg(feature = "rayon")]
19pub mod rayon {
20    pub mod map;
21    pub mod read_only;
22    pub mod set;
23}
24
25#[cfg(not(feature = "raw-api"))]
26use crate::lock::{RwLock, RwLockReadGuard, RwLockWriteGuard};
27
28#[cfg(feature = "raw-api")]
29pub use crate::lock::{RawRwLock, RwLock, RwLockReadGuard, RwLockWriteGuard};
30
31use cfg_if::cfg_if;
32use core::borrow::Borrow;
33use core::fmt;
34use core::hash::{BuildHasher, Hash, Hasher};
35use core::iter::FromIterator;
36use core::ops::{BitAnd, BitOr, Shl, Shr, Sub};
37use iter::{Iter, IterMut, OwningIter};
38use mapref::entry::{Entry, OccupiedEntry, VacantEntry};
39use mapref::multiple::RefMulti;
40use mapref::one::{Ref, RefMut};
41use once_cell::sync::OnceCell;
42pub use read_only::ReadOnlyView;
43pub use set::DashSet;
44use std::collections::hash_map::RandomState;
45pub use t::Map;
46use try_result::TryResult;
47
48cfg_if! {
49    if #[cfg(feature = "raw-api")] {
50        pub use util::SharedValue;
51    } else {
52        use util::SharedValue;
53    }
54}
55
56pub(crate) type HashMap<K, V, S> = hashbrown::HashMap<K, SharedValue<V>, S>;
57
58// Temporary reimplementation of [`std::collections::TryReserveError`]
59// util [`std::collections::TryReserveError`] stabilises.
60// We cannot easily create `std::collections` error type from `hashbrown` error type
61// without access to `TryReserveError::kind` method.
62#[non_exhaustive]
63#[derive(Clone, PartialEq, Eq, Debug)]
64pub struct TryReserveError {}
65
66fn default_shard_amount() -> usize {
67    static DEFAULT_SHARD_AMOUNT: OnceCell<usize> = OnceCell::new();
68    *DEFAULT_SHARD_AMOUNT.get_or_init(|| {
69        (std::thread::available_parallelism().map_or(1, usize::from) * 4).next_power_of_two()
70    })
71}
72
73fn ncb(shard_amount: usize) -> usize {
74    shard_amount.trailing_zeros() as usize
75}
76
77/// DashMap is an implementation of a concurrent associative array/hashmap in Rust.
78///
79/// DashMap tries to implement an easy to use API similar to `std::collections::HashMap`
80/// with some slight changes to handle concurrency.
81///
82/// DashMap tries to be very simple to use and to be a direct replacement for `RwLock<HashMap<K, V, S>>`.
83/// To accomplish this, all methods take `&self` instead of modifying methods taking `&mut self`.
84/// This allows you to put a DashMap in an `Arc<T>` and share it between threads while being able to modify it.
85///
86/// Documentation mentioning locking behaviour acts in the reference frame of the calling thread.
87/// This means that it is safe to ignore it across multiple threads.
88pub struct DashMap<K, V, S = RandomState> {
89    shift: usize,
90    shards: Box<[RwLock<HashMap<K, V, S>>]>,
91    hasher: S,
92}
93
94impl<K: Eq + Hash + Clone, V: Clone, S: Clone> Clone for DashMap<K, V, S> {
95    fn clone(&self) -> Self {
96        let mut inner_shards = Vec::new();
97
98        for shard in self.shards.iter() {
99            let shard = shard.read();
100
101            inner_shards.push(RwLock::new((*shard).clone()));
102        }
103
104        Self {
105            shift: self.shift,
106            shards: inner_shards.into_boxed_slice(),
107            hasher: self.hasher.clone(),
108        }
109    }
110}
111
112impl<K, V, S> Default for DashMap<K, V, S>
113where
114    K: Eq + Hash,
115    S: Default + BuildHasher + Clone,
116{
117    fn default() -> Self {
118        Self::with_hasher(Default::default())
119    }
120}
121
122impl<'a, K: 'a + Eq + Hash, V: 'a> DashMap<K, V, RandomState> {
123    /// Creates a new DashMap with a capacity of 0.
124    ///
125    /// # Examples
126    ///
127    /// ```
128    /// use dashmap::DashMap;
129    ///
130    /// let reviews = DashMap::new();
131    /// reviews.insert("Veloren", "What a fantastic game!");
132    /// ```
133    pub fn new() -> Self {
134        DashMap::with_hasher(RandomState::default())
135    }
136
137    /// Creates a new DashMap with a specified starting capacity.
138    ///
139    /// # Examples
140    ///
141    /// ```
142    /// use dashmap::DashMap;
143    ///
144    /// let mappings = DashMap::with_capacity(2);
145    /// mappings.insert(2, 4);
146    /// mappings.insert(8, 16);
147    /// ```
148    pub fn with_capacity(capacity: usize) -> Self {
149        DashMap::with_capacity_and_hasher(capacity, RandomState::default())
150    }
151
152    /// Creates a new DashMap with a specified shard amount
153    ///
154    /// shard_amount should greater than 0 and be a power of two.
155    /// If a shard_amount which is not a power of two is provided, the function will panic.
156    ///
157    /// # Examples
158    ///
159    /// ```
160    /// use dashmap::DashMap;
161    ///
162    /// let mappings = DashMap::with_shard_amount(32);
163    /// mappings.insert(2, 4);
164    /// mappings.insert(8, 16);
165    /// ```
166    pub fn with_shard_amount(shard_amount: usize) -> Self {
167        Self::with_capacity_and_hasher_and_shard_amount(0, RandomState::default(), shard_amount)
168    }
169
170    /// Creates a new DashMap with a specified capacity and shard amount.
171    ///
172    /// shard_amount should greater than 0 and be a power of two.
173    /// If a shard_amount which is not a power of two is provided, the function will panic.
174    ///
175    /// # Examples
176    ///
177    /// ```
178    /// use dashmap::DashMap;
179    ///
180    /// let mappings = DashMap::with_capacity_and_shard_amount(32, 32);
181    /// mappings.insert(2, 4);
182    /// mappings.insert(8, 16);
183    /// ```
184    pub fn with_capacity_and_shard_amount(capacity: usize, shard_amount: usize) -> Self {
185        Self::with_capacity_and_hasher_and_shard_amount(
186            capacity,
187            RandomState::default(),
188            shard_amount,
189        )
190    }
191}
192
193impl<'a, K: 'a + Eq + Hash, V: 'a, S: BuildHasher + Clone> DashMap<K, V, S> {
194    /// Wraps this `DashMap` into a read-only view. This view allows to obtain raw references to the stored values.
195    pub fn into_read_only(self) -> ReadOnlyView<K, V, S> {
196        ReadOnlyView::new(self)
197    }
198
199    /// Creates a new DashMap with a capacity of 0 and the provided hasher.
200    ///
201    /// # Examples
202    ///
203    /// ```
204    /// use dashmap::DashMap;
205    /// use std::collections::hash_map::RandomState;
206    ///
207    /// let s = RandomState::new();
208    /// let reviews = DashMap::with_hasher(s);
209    /// reviews.insert("Veloren", "What a fantastic game!");
210    /// ```
211    pub fn with_hasher(hasher: S) -> Self {
212        Self::with_capacity_and_hasher(0, hasher)
213    }
214
215    /// Creates a new DashMap with a specified starting capacity and hasher.
216    ///
217    /// # Examples
218    ///
219    /// ```
220    /// use dashmap::DashMap;
221    /// use std::collections::hash_map::RandomState;
222    ///
223    /// let s = RandomState::new();
224    /// let mappings = DashMap::with_capacity_and_hasher(2, s);
225    /// mappings.insert(2, 4);
226    /// mappings.insert(8, 16);
227    /// ```
228    pub fn with_capacity_and_hasher(capacity: usize, hasher: S) -> Self {
229        Self::with_capacity_and_hasher_and_shard_amount(capacity, hasher, default_shard_amount())
230    }
231
232    /// Creates a new DashMap with a specified hasher and shard amount
233    ///
234    /// shard_amount should be greater than 0 and a power of two.
235    /// If a shard_amount which is not a power of two is provided, the function will panic.
236    ///
237    /// # Examples
238    ///
239    /// ```
240    /// use dashmap::DashMap;
241    /// use std::collections::hash_map::RandomState;
242    ///
243    /// let s = RandomState::new();
244    /// let mappings = DashMap::with_hasher_and_shard_amount(s, 32);
245    /// mappings.insert(2, 4);
246    /// mappings.insert(8, 16);
247    /// ```
248    pub fn with_hasher_and_shard_amount(hasher: S, shard_amount: usize) -> Self {
249        Self::with_capacity_and_hasher_and_shard_amount(0, hasher, shard_amount)
250    }
251
252    /// Creates a new DashMap with a specified starting capacity, hasher and shard_amount.
253    ///
254    /// shard_amount should greater than 0 and be a power of two.
255    /// If a shard_amount which is not a power of two is provided, the function will panic.
256    ///
257    /// # Examples
258    ///
259    /// ```
260    /// use dashmap::DashMap;
261    /// use std::collections::hash_map::RandomState;
262    ///
263    /// let s = RandomState::new();
264    /// let mappings = DashMap::with_capacity_and_hasher_and_shard_amount(2, s, 32);
265    /// mappings.insert(2, 4);
266    /// mappings.insert(8, 16);
267    /// ```
268    pub fn with_capacity_and_hasher_and_shard_amount(
269        mut capacity: usize,
270        hasher: S,
271        shard_amount: usize,
272    ) -> Self {
273        assert!(shard_amount > 1);
274        assert!(shard_amount.is_power_of_two());
275
276        let shift = util::ptr_size_bits() - ncb(shard_amount);
277
278        if capacity != 0 {
279            capacity = (capacity + (shard_amount - 1)) & !(shard_amount - 1);
280        }
281
282        let cps = capacity / shard_amount;
283
284        let shards = (0..shard_amount)
285            .map(|_| RwLock::new(HashMap::with_capacity_and_hasher(cps, hasher.clone())))
286            .collect();
287
288        Self {
289            shift,
290            shards,
291            hasher,
292        }
293    }
294
295    /// Hash a given item to produce a usize.
296    /// Uses the provided or default HashBuilder.
297    pub fn hash_usize<T: Hash>(&self, item: &T) -> usize {
298        let mut hasher = self.hasher.build_hasher();
299
300        item.hash(&mut hasher);
301
302        hasher.finish() as usize
303    }
304
305    cfg_if! {
306        if #[cfg(feature = "raw-api")] {
307            /// Allows you to peek at the inner shards that store your data.
308            /// You should probably not use this unless you know what you are doing.
309            ///
310            /// Requires the `raw-api` feature to be enabled.
311            ///
312            /// # Examples
313            ///
314            /// ```
315            /// use dashmap::DashMap;
316            ///
317            /// let map = DashMap::<(), ()>::new();
318            /// println!("Amount of shards: {}", map.shards().len());
319            /// ```
320            pub fn shards(&self) -> &[RwLock<HashMap<K, V, S>>] {
321                &self.shards
322            }
323
324            /// Provides mutable access to the inner shards that store your data.
325            /// You should probably not use this unless you know what you are doing.
326            ///
327            /// Requires the `raw-api` feature to be enabled.
328            ///
329            /// # Examples
330            ///
331            /// ```
332            /// use dashmap::DashMap;
333            /// use dashmap::SharedValue;
334            ///
335            /// let mut map = DashMap::<i32, &'static str>::new();
336            /// let shard_ind = map.determine_map(&42);
337            /// map.shards_mut()[shard_ind].get_mut().insert(42, SharedValue::new("forty two"));
338            /// assert_eq!(*map.get(&42).unwrap(), "forty two");
339            /// ```
340            pub fn shards_mut(&mut self) -> &mut [RwLock<HashMap<K, V, S>>] {
341                &mut self.shards
342            }
343
344            /// Consumes this `DashMap` and returns the inner shards.
345            /// You should probably not use this unless you know what you are doing.
346            ///
347            /// Requires the `raw-api` feature to be enabled.
348            ///
349            /// See [`DashMap::shards()`] and [`DashMap::shards_mut()`] for more information.
350            pub fn into_shards(self) -> Box<[RwLock<HashMap<K, V, S>>]> {
351                self.shards
352            }
353        } else {
354            #[allow(dead_code)]
355            pub(crate) fn shards(&self) -> &[RwLock<HashMap<K, V, S>>] {
356                &self.shards
357            }
358
359            #[allow(dead_code)]
360            pub(crate) fn shards_mut(&mut self) -> &mut [RwLock<HashMap<K, V, S>>] {
361                &mut self.shards
362            }
363
364            #[allow(dead_code)]
365            pub(crate) fn into_shards(self) -> Box<[RwLock<HashMap<K, V, S>>]> {
366                self.shards
367            }
368        }
369    }
370
371    cfg_if! {
372        if #[cfg(feature = "raw-api")] {
373            /// Finds which shard a certain key is stored in.
374            /// You should probably not use this unless you know what you are doing.
375            /// Note that shard selection is dependent on the default or provided HashBuilder.
376            ///
377            /// Requires the `raw-api` feature to be enabled.
378            ///
379            /// # Examples
380            ///
381            /// ```
382            /// use dashmap::DashMap;
383            ///
384            /// let map = DashMap::new();
385            /// map.insert("coca-cola", 1.4);
386            /// println!("coca-cola is stored in shard: {}", map.determine_map("coca-cola"));
387            /// ```
388            pub fn determine_map<Q>(&self, key: &Q) -> usize
389            where
390                K: Borrow<Q>,
391                Q: Hash + Eq + ?Sized,
392            {
393                let hash = self.hash_usize(&key);
394                self.determine_shard(hash)
395            }
396        }
397    }
398
399    cfg_if! {
400        if #[cfg(feature = "raw-api")] {
401            /// Finds which shard a certain hash is stored in.
402            ///
403            /// Requires the `raw-api` feature to be enabled.
404            ///
405            /// # Examples
406            ///
407            /// ```
408            /// use dashmap::DashMap;
409            ///
410            /// let map: DashMap<i32, i32> = DashMap::new();
411            /// let key = "key";
412            /// let hash = map.hash_usize(&key);
413            /// println!("hash is stored in shard: {}", map.determine_shard(hash));
414            /// ```
415            pub fn determine_shard(&self, hash: usize) -> usize {
416                // Leave the high 7 bits for the HashBrown SIMD tag.
417                (hash << 7) >> self.shift
418            }
419        } else {
420
421            pub(crate) fn determine_shard(&self, hash: usize) -> usize {
422                // Leave the high 7 bits for the HashBrown SIMD tag.
423                (hash << 7) >> self.shift
424            }
425        }
426    }
427
428    /// Returns a reference to the map's [`BuildHasher`].
429    ///
430    /// # Examples
431    ///
432    /// ```rust
433    /// use dashmap::DashMap;
434    /// use std::collections::hash_map::RandomState;
435    ///
436    /// let hasher = RandomState::new();
437    /// let map: DashMap<i32, i32> = DashMap::new();
438    /// let hasher: &RandomState = map.hasher();
439    /// ```
440    ///
441    /// [`BuildHasher`]: https://doc.rust-lang.org/std/hash/trait.BuildHasher.html
442    pub fn hasher(&self) -> &S {
443        &self.hasher
444    }
445
446    /// Inserts a key and a value into the map. Returns the old value associated with the key if there was one.
447    ///
448    /// **Locking behaviour:** May deadlock if called when holding any sort of reference into the map.
449    ///
450    /// # Examples
451    ///
452    /// ```
453    /// use dashmap::DashMap;
454    ///
455    /// let map = DashMap::new();
456    /// map.insert("I am the key!", "And I am the value!");
457    /// ```
458    pub fn insert(&self, key: K, value: V) -> Option<V> {
459        self._insert(key, value)
460    }
461
462    /// Removes an entry from the map, returning the key and value if they existed in the map.
463    ///
464    /// **Locking behaviour:** May deadlock if called when holding any sort of reference into the map.
465    ///
466    /// # Examples
467    ///
468    /// ```
469    /// use dashmap::DashMap;
470    ///
471    /// let soccer_team = DashMap::new();
472    /// soccer_team.insert("Jack", "Goalie");
473    /// assert_eq!(soccer_team.remove("Jack").unwrap().1, "Goalie");
474    /// ```
475    pub fn remove<Q>(&self, key: &Q) -> Option<(K, V)>
476    where
477        K: Borrow<Q>,
478        Q: Hash + Eq + ?Sized,
479    {
480        self._remove(key)
481    }
482
483    /// Removes an entry from the map, returning the key and value
484    /// if the entry existed and the provided conditional function returned true.
485    ///
486    /// **Locking behaviour:** May deadlock if called when holding any sort of reference into the map.
487    ///
488    /// ```
489    /// use dashmap::DashMap;
490    ///
491    /// let soccer_team = DashMap::new();
492    /// soccer_team.insert("Sam", "Forward");
493    /// soccer_team.remove_if("Sam", |_, position| position == &"Goalie");
494    /// assert!(soccer_team.contains_key("Sam"));
495    /// ```
496    /// ```
497    /// use dashmap::DashMap;
498    ///
499    /// let soccer_team = DashMap::new();
500    /// soccer_team.insert("Sam", "Forward");
501    /// soccer_team.remove_if("Sam", |_, position| position == &"Forward");
502    /// assert!(!soccer_team.contains_key("Sam"));
503    /// ```
504    pub fn remove_if<Q>(&self, key: &Q, f: impl FnOnce(&K, &V) -> bool) -> Option<(K, V)>
505    where
506        K: Borrow<Q>,
507        Q: Hash + Eq + ?Sized,
508    {
509        self._remove_if(key, f)
510    }
511
512    pub fn remove_if_mut<Q>(&self, key: &Q, f: impl FnOnce(&K, &mut V) -> bool) -> Option<(K, V)>
513    where
514        K: Borrow<Q>,
515        Q: Hash + Eq + ?Sized,
516    {
517        self._remove_if_mut(key, f)
518    }
519
520    /// Creates an iterator over a DashMap yielding immutable references.
521    ///
522    /// **Locking behaviour:** May deadlock if called when holding a mutable reference into the map.
523    ///
524    /// # Examples
525    ///
526    /// ```
527    /// use dashmap::DashMap;
528    ///
529    /// let words = DashMap::new();
530    /// words.insert("hello", "world");
531    /// assert_eq!(words.iter().count(), 1);
532    /// ```
533    pub fn iter(&'a self) -> Iter<'a, K, V, S, DashMap<K, V, S>> {
534        self._iter()
535    }
536
537    /// Iterator over a DashMap yielding mutable references.
538    ///
539    /// **Locking behaviour:** May deadlock if called when holding any sort of reference into the map.
540    ///
541    /// # Examples
542    ///
543    /// ```
544    /// use dashmap::DashMap;
545    ///
546    /// let map = DashMap::new();
547    /// map.insert("Johnny", 21);
548    /// map.iter_mut().for_each(|mut r| *r += 1);
549    /// assert_eq!(*map.get("Johnny").unwrap(), 22);
550    /// ```
551    pub fn iter_mut(&'a self) -> IterMut<'a, K, V, S, DashMap<K, V, S>> {
552        self._iter_mut()
553    }
554
555    /// Get an immutable reference to an entry in the map
556    ///
557    /// **Locking behaviour:** May deadlock if called when holding a mutable reference into the map.
558    ///
559    /// # Examples
560    ///
561    /// ```
562    /// use dashmap::DashMap;
563    ///
564    /// let youtubers = DashMap::new();
565    /// youtubers.insert("Bosnian Bill", 457000);
566    /// assert_eq!(*youtubers.get("Bosnian Bill").unwrap(), 457000);
567    /// ```
568    pub fn get<Q>(&'a self, key: &Q) -> Option<Ref<'a, K, V, S>>
569    where
570        K: Borrow<Q>,
571        Q: Hash + Eq + ?Sized,
572    {
573        self._get(key)
574    }
575
576    /// Get a mutable reference to an entry in the map
577    ///
578    /// **Locking behaviour:** May deadlock if called when holding any sort of reference into the map.
579    ///
580    /// # Examples
581    ///
582    /// ```
583    /// use dashmap::DashMap;
584    ///
585    /// let class = DashMap::new();
586    /// class.insert("Albin", 15);
587    /// *class.get_mut("Albin").unwrap() -= 1;
588    /// assert_eq!(*class.get("Albin").unwrap(), 14);
589    /// ```
590    pub fn get_mut<Q>(&'a self, key: &Q) -> Option<RefMut<'a, K, V, S>>
591    where
592        K: Borrow<Q>,
593        Q: Hash + Eq + ?Sized,
594    {
595        self._get_mut(key)
596    }
597
598    /// Get an immutable reference to an entry in the map, if the shard is not locked.
599    /// If the shard is locked, the function will return [TryResult::Locked].
600    ///
601    /// # Examples
602    ///
603    /// ```
604    /// use dashmap::DashMap;
605    /// use dashmap::try_result::TryResult;
606    ///
607    /// let map = DashMap::new();
608    /// map.insert("Johnny", 21);
609    ///
610    /// assert_eq!(*map.try_get("Johnny").unwrap(), 21);
611    ///
612    /// let _result1_locking = map.get_mut("Johnny");
613    ///
614    /// let result2 = map.try_get("Johnny");
615    /// assert!(result2.is_locked());
616    /// ```
617    pub fn try_get<Q>(&'a self, key: &Q) -> TryResult<Ref<'a, K, V, S>>
618    where
619        K: Borrow<Q>,
620        Q: Hash + Eq + ?Sized,
621    {
622        self._try_get(key)
623    }
624
625    /// Get a mutable reference to an entry in the map, if the shard is not locked.
626    /// If the shard is locked, the function will return [TryResult::Locked].
627    ///
628    /// # Examples
629    ///
630    /// ```
631    /// use dashmap::DashMap;
632    /// use dashmap::try_result::TryResult;
633    ///
634    /// let map = DashMap::new();
635    /// map.insert("Johnny", 21);
636    ///
637    /// *map.try_get_mut("Johnny").unwrap() += 1;
638    /// assert_eq!(*map.get("Johnny").unwrap(), 22);
639    ///
640    /// let _result1_locking = map.get("Johnny");
641    ///
642    /// let result2 = map.try_get_mut("Johnny");
643    /// assert!(result2.is_locked());
644    /// ```
645    pub fn try_get_mut<Q>(&'a self, key: &Q) -> TryResult<RefMut<'a, K, V, S>>
646    where
647        K: Borrow<Q>,
648        Q: Hash + Eq + ?Sized,
649    {
650        self._try_get_mut(key)
651    }
652
653    /// Remove excess capacity to reduce memory usage.
654    ///
655    /// **Locking behaviour:** May deadlock if called when holding any sort of reference into the map.
656    pub fn shrink_to_fit(&self) {
657        self._shrink_to_fit();
658    }
659
660    /// Retain elements that whose predicates return true
661    /// and discard elements whose predicates return false.
662    ///
663    /// **Locking behaviour:** May deadlock if called when holding any sort of reference into the map.
664    ///
665    /// # Examples
666    ///
667    /// ```
668    /// use dashmap::DashMap;
669    ///
670    /// let people = DashMap::new();
671    /// people.insert("Albin", 15);
672    /// people.insert("Jones", 22);
673    /// people.insert("Charlie", 27);
674    /// people.retain(|_, v| *v > 20);
675    /// assert_eq!(people.len(), 2);
676    /// ```
677    pub fn retain(&self, f: impl FnMut(&K, &mut V) -> bool) {
678        self._retain(f);
679    }
680
681    /// Fetches the total number of key-value pairs stored in the map.
682    ///
683    /// **Locking behaviour:** May deadlock if called when holding a mutable reference into the map.
684    ///
685    /// # Examples
686    ///
687    /// ```
688    /// use dashmap::DashMap;
689    ///
690    /// let people = DashMap::new();
691    /// people.insert("Albin", 15);
692    /// people.insert("Jones", 22);
693    /// people.insert("Charlie", 27);
694    /// assert_eq!(people.len(), 3);
695    /// ```
696    pub fn len(&self) -> usize {
697        self._len()
698    }
699
700    /// Checks if the map is empty or not.
701    ///
702    /// **Locking behaviour:** May deadlock if called when holding a mutable reference into the map.
703    ///
704    /// # Examples
705    ///
706    /// ```
707    /// use dashmap::DashMap;
708    ///
709    /// let map = DashMap::<(), ()>::new();
710    /// assert!(map.is_empty());
711    /// ```
712    pub fn is_empty(&self) -> bool {
713        self._is_empty()
714    }
715
716    /// Removes all key-value pairs in the map.
717    ///
718    /// **Locking behaviour:** May deadlock if called when holding any sort of reference into the map.
719    ///
720    /// # Examples
721    ///
722    /// ```
723    /// use dashmap::DashMap;
724    ///
725    /// let stats = DashMap::new();
726    /// stats.insert("Goals", 4);
727    /// assert!(!stats.is_empty());
728    /// stats.clear();
729    /// assert!(stats.is_empty());
730    /// ```
731    pub fn clear(&self) {
732        self._clear();
733    }
734
735    /// Returns how many key-value pairs the map can store without reallocating.
736    ///
737    /// **Locking behaviour:** May deadlock if called when holding a mutable reference into the map.
738    pub fn capacity(&self) -> usize {
739        self._capacity()
740    }
741
742    /// Modify a specific value according to a function.
743    ///
744    /// **Locking behaviour:** May deadlock if called when holding any sort of reference into the map.
745    ///
746    /// # Examples
747    ///
748    /// ```
749    /// use dashmap::DashMap;
750    ///
751    /// let stats = DashMap::new();
752    /// stats.insert("Goals", 4);
753    /// stats.alter("Goals", |_, v| v * 2);
754    /// assert_eq!(*stats.get("Goals").unwrap(), 8);
755    /// ```
756    ///
757    /// # Panics
758    ///
759    /// If the given closure panics, then `alter` will abort the process
760    pub fn alter<Q>(&self, key: &Q, f: impl FnOnce(&K, V) -> V)
761    where
762        K: Borrow<Q>,
763        Q: Hash + Eq + ?Sized,
764    {
765        self._alter(key, f);
766    }
767
768    /// Modify every value in the map according to a function.
769    ///
770    /// **Locking behaviour:** May deadlock if called when holding any sort of reference into the map.
771    ///
772    /// # Examples
773    ///
774    /// ```
775    /// use dashmap::DashMap;
776    ///
777    /// let stats = DashMap::new();
778    /// stats.insert("Wins", 4);
779    /// stats.insert("Losses", 2);
780    /// stats.alter_all(|_, v| v + 1);
781    /// assert_eq!(*stats.get("Wins").unwrap(), 5);
782    /// assert_eq!(*stats.get("Losses").unwrap(), 3);
783    /// ```
784    ///
785    /// # Panics
786    ///
787    /// If the given closure panics, then `alter_all` will abort the process
788    pub fn alter_all(&self, f: impl FnMut(&K, V) -> V) {
789        self._alter_all(f);
790    }
791
792    /// Scoped access into an item of the map according to a function.
793    ///
794    /// **Locking behaviour:** May deadlock if called when holding any sort of reference into the map.
795    ///
796    /// # Examples
797    ///
798    /// ```
799    /// use dashmap::DashMap;
800    ///
801    /// let warehouse = DashMap::new();
802    /// warehouse.insert(4267, ("Banana", 100));
803    /// warehouse.insert(2359, ("Pear", 120));
804    /// let fruit = warehouse.view(&4267, |_k, v| *v);
805    /// assert_eq!(fruit, Some(("Banana", 100)));
806    /// ```
807    ///
808    /// # Panics
809    ///
810    /// If the given closure panics, then `view` will abort the process
811    pub fn view<Q, R>(&self, key: &Q, f: impl FnOnce(&K, &V) -> R) -> Option<R>
812    where
813        K: Borrow<Q>,
814        Q: Hash + Eq + ?Sized,
815    {
816        self._view(key, f)
817    }
818
819    /// Checks if the map contains a specific key.
820    ///
821    /// **Locking behaviour:** May deadlock if called when holding a mutable reference into the map.
822    ///
823    /// # Examples
824    ///
825    /// ```
826    /// use dashmap::DashMap;
827    ///
828    /// let team_sizes = DashMap::new();
829    /// team_sizes.insert("Dakota Cherries", 23);
830    /// assert!(team_sizes.contains_key("Dakota Cherries"));
831    /// ```
832    pub fn contains_key<Q>(&self, key: &Q) -> bool
833    where
834        K: Borrow<Q>,
835        Q: Hash + Eq + ?Sized,
836    {
837        self._contains_key(key)
838    }
839
840    /// Advanced entry API that tries to mimic `std::collections::HashMap`.
841    /// See the documentation on `dashmap::mapref::entry` for more details.
842    ///
843    /// **Locking behaviour:** May deadlock if called when holding any sort of reference into the map.
844    pub fn entry(&'a self, key: K) -> Entry<'a, K, V, S> {
845        self._entry(key)
846    }
847
848    /// Advanced entry API that tries to mimic `std::collections::HashMap`.
849    /// See the documentation on `dashmap::mapref::entry` for more details.
850    ///
851    /// Returns None if the shard is currently locked.
852    pub fn try_entry(&'a self, key: K) -> Option<Entry<'a, K, V, S>> {
853        self._try_entry(key)
854    }
855
856    /// Advanced entry API that tries to mimic `std::collections::HashMap::try_reserve`.
857    /// Tries to reserve capacity for at least `shard * additional`
858    /// and may reserve more space to avoid frequent reallocations.
859    ///
860    /// # Errors
861    ///
862    /// If the capacity overflows, or the allocator reports a failure, then an error is returned.
863    // TODO: return std::collections::TryReserveError once std::collections::TryReserveErrorKind stabilises.
864    pub fn try_reserve(&mut self, additional: usize) -> Result<(), TryReserveError> {
865        for shard in self.shards.iter() {
866            shard
867                .write()
868                .try_reserve(additional)
869                .map_err(|_| TryReserveError {})?;
870        }
871        Ok(())
872    }
873}
874
875impl<'a, K: 'a + Eq + Hash, V: 'a, S: 'a + BuildHasher + Clone> Map<'a, K, V, S>
876    for DashMap<K, V, S>
877{
878    fn _shard_count(&self) -> usize {
879        self.shards.len()
880    }
881
882    unsafe fn _get_read_shard(&'a self, i: usize) -> &'a HashMap<K, V, S> {
883        debug_assert!(i < self.shards.len());
884
885        &*self.shards.get_unchecked(i).data_ptr()
886    }
887
888    unsafe fn _yield_read_shard(&'a self, i: usize) -> RwLockReadGuard<'a, HashMap<K, V, S>> {
889        debug_assert!(i < self.shards.len());
890
891        self.shards.get_unchecked(i).read()
892    }
893
894    unsafe fn _yield_write_shard(&'a self, i: usize) -> RwLockWriteGuard<'a, HashMap<K, V, S>> {
895        debug_assert!(i < self.shards.len());
896
897        self.shards.get_unchecked(i).write()
898    }
899
900    unsafe fn _try_yield_read_shard(
901        &'a self,
902        i: usize,
903    ) -> Option<RwLockReadGuard<'a, HashMap<K, V, S>>> {
904        debug_assert!(i < self.shards.len());
905
906        self.shards.get_unchecked(i).try_read()
907    }
908
909    unsafe fn _try_yield_write_shard(
910        &'a self,
911        i: usize,
912    ) -> Option<RwLockWriteGuard<'a, HashMap<K, V, S>>> {
913        debug_assert!(i < self.shards.len());
914
915        self.shards.get_unchecked(i).try_write()
916    }
917
918    fn _insert(&self, key: K, value: V) -> Option<V> {
919        let hash = self.hash_usize(&key);
920
921        let idx = self.determine_shard(hash);
922
923        let mut shard = unsafe { self._yield_write_shard(idx) };
924
925        shard
926            .insert(key, SharedValue::new(value))
927            .map(|v| v.into_inner())
928    }
929
930    fn _remove<Q>(&self, key: &Q) -> Option<(K, V)>
931    where
932        K: Borrow<Q>,
933        Q: Hash + Eq + ?Sized,
934    {
935        let hash = self.hash_usize(&key);
936
937        let idx = self.determine_shard(hash);
938
939        let mut shard = unsafe { self._yield_write_shard(idx) };
940
941        shard.remove_entry(key).map(|(k, v)| (k, v.into_inner()))
942    }
943
944    fn _remove_if<Q>(&self, key: &Q, f: impl FnOnce(&K, &V) -> bool) -> Option<(K, V)>
945    where
946        K: Borrow<Q>,
947        Q: Hash + Eq + ?Sized,
948    {
949        let hash = self.hash_usize(&key);
950
951        let idx = self.determine_shard(hash);
952
953        let mut shard = unsafe { self._yield_write_shard(idx) };
954
955        if let Some((kptr, vptr)) = shard.get_key_value(key) {
956            unsafe {
957                let kptr: *const K = kptr;
958                let vptr: *mut V = vptr.as_ptr();
959
960                if f(&*kptr, &mut *vptr) {
961                    shard.remove_entry(key).map(|(k, v)| (k, v.into_inner()))
962                } else {
963                    None
964                }
965            }
966        } else {
967            None
968        }
969    }
970
971    fn _remove_if_mut<Q>(&self, key: &Q, f: impl FnOnce(&K, &mut V) -> bool) -> Option<(K, V)>
972    where
973        K: Borrow<Q>,
974        Q: Hash + Eq + ?Sized,
975    {
976        let hash = self.hash_usize(&key);
977
978        let idx = self.determine_shard(hash);
979
980        let mut shard = unsafe { self._yield_write_shard(idx) };
981
982        if let Some((kptr, vptr)) = shard.get_key_value(key) {
983            unsafe {
984                let kptr: *const K = kptr;
985                let vptr: *mut V = vptr.as_ptr();
986
987                if f(&*kptr, &mut *vptr) {
988                    shard.remove_entry(key).map(|(k, v)| (k, v.into_inner()))
989                } else {
990                    None
991                }
992            }
993        } else {
994            None
995        }
996    }
997
998    fn _iter(&'a self) -> Iter<'a, K, V, S, DashMap<K, V, S>> {
999        Iter::new(self)
1000    }
1001
1002    fn _iter_mut(&'a self) -> IterMut<'a, K, V, S, DashMap<K, V, S>> {
1003        IterMut::new(self)
1004    }
1005
1006    fn _get<Q>(&'a self, key: &Q) -> Option<Ref<'a, K, V, S>>
1007    where
1008        K: Borrow<Q>,
1009        Q: Hash + Eq + ?Sized,
1010    {
1011        let hash = self.hash_usize(&key);
1012
1013        let idx = self.determine_shard(hash);
1014
1015        let shard = unsafe { self._yield_read_shard(idx) };
1016
1017        if let Some((kptr, vptr)) = shard.get_key_value(key) {
1018            unsafe {
1019                let kptr: *const K = kptr;
1020                let vptr: *const V = vptr.get();
1021                Some(Ref::new(shard, kptr, vptr))
1022            }
1023        } else {
1024            None
1025        }
1026    }
1027
1028    fn _get_mut<Q>(&'a self, key: &Q) -> Option<RefMut<'a, K, V, S>>
1029    where
1030        K: Borrow<Q>,
1031        Q: Hash + Eq + ?Sized,
1032    {
1033        let hash = self.hash_usize(&key);
1034
1035        let idx = self.determine_shard(hash);
1036
1037        let shard = unsafe { self._yield_write_shard(idx) };
1038
1039        if let Some((kptr, vptr)) = shard.get_key_value(key) {
1040            unsafe {
1041                let kptr: *const K = kptr;
1042                let vptr: *mut V = vptr.as_ptr();
1043                Some(RefMut::new(shard, kptr, vptr))
1044            }
1045        } else {
1046            None
1047        }
1048    }
1049
1050    fn _try_get<Q>(&'a self, key: &Q) -> TryResult<Ref<'a, K, V, S>>
1051    where
1052        K: Borrow<Q>,
1053        Q: Hash + Eq + ?Sized,
1054    {
1055        let hash = self.hash_usize(&key);
1056
1057        let idx = self.determine_shard(hash);
1058
1059        let shard = match unsafe { self._try_yield_read_shard(idx) } {
1060            Some(shard) => shard,
1061            None => return TryResult::Locked,
1062        };
1063
1064        if let Some((kptr, vptr)) = shard.get_key_value(key) {
1065            unsafe {
1066                let kptr: *const K = kptr;
1067                let vptr: *const V = vptr.get();
1068                TryResult::Present(Ref::new(shard, kptr, vptr))
1069            }
1070        } else {
1071            TryResult::Absent
1072        }
1073    }
1074
1075    fn _try_get_mut<Q>(&'a self, key: &Q) -> TryResult<RefMut<'a, K, V, S>>
1076    where
1077        K: Borrow<Q>,
1078        Q: Hash + Eq + ?Sized,
1079    {
1080        let hash = self.hash_usize(&key);
1081
1082        let idx = self.determine_shard(hash);
1083
1084        let shard = match unsafe { self._try_yield_write_shard(idx) } {
1085            Some(shard) => shard,
1086            None => return TryResult::Locked,
1087        };
1088
1089        if let Some((kptr, vptr)) = shard.get_key_value(key) {
1090            unsafe {
1091                let kptr: *const K = kptr;
1092                let vptr: *mut V = vptr.as_ptr();
1093                TryResult::Present(RefMut::new(shard, kptr, vptr))
1094            }
1095        } else {
1096            TryResult::Absent
1097        }
1098    }
1099
1100    fn _shrink_to_fit(&self) {
1101        self.shards.iter().for_each(|s| s.write().shrink_to_fit());
1102    }
1103
1104    fn _retain(&self, mut f: impl FnMut(&K, &mut V) -> bool) {
1105        self.shards
1106            .iter()
1107            .for_each(|s| s.write().retain(|k, v| f(k, v.get_mut())));
1108    }
1109
1110    fn _len(&self) -> usize {
1111        self.shards.iter().map(|s| s.read().len()).sum()
1112    }
1113
1114    fn _capacity(&self) -> usize {
1115        self.shards.iter().map(|s| s.read().capacity()).sum()
1116    }
1117
1118    fn _alter<Q>(&self, key: &Q, f: impl FnOnce(&K, V) -> V)
1119    where
1120        K: Borrow<Q>,
1121        Q: Hash + Eq + ?Sized,
1122    {
1123        if let Some(mut r) = self.get_mut(key) {
1124            util::map_in_place_2(r.pair_mut(), f);
1125        }
1126    }
1127
1128    fn _alter_all(&self, mut f: impl FnMut(&K, V) -> V) {
1129        self.shards.iter().for_each(|s| {
1130            s.write()
1131                .iter_mut()
1132                .for_each(|(k, v)| util::map_in_place_2((k, v.get_mut()), &mut f));
1133        });
1134    }
1135
1136    fn _view<Q, R>(&self, key: &Q, f: impl FnOnce(&K, &V) -> R) -> Option<R>
1137    where
1138        K: Borrow<Q>,
1139        Q: Hash + Eq + ?Sized,
1140    {
1141        self.get(key).map(|r| {
1142            let (k, v) = r.pair();
1143            f(k, v)
1144        })
1145    }
1146
1147    fn _entry(&'a self, key: K) -> Entry<'a, K, V, S> {
1148        let hash = self.hash_usize(&key);
1149
1150        let idx = self.determine_shard(hash);
1151
1152        let shard = unsafe { self._yield_write_shard(idx) };
1153
1154        if let Some((kptr, vptr)) = shard.get_key_value(&key) {
1155            unsafe {
1156                let kptr: *const K = kptr;
1157                let vptr: *mut V = vptr.as_ptr();
1158                Entry::Occupied(OccupiedEntry::new(shard, key, (kptr, vptr)))
1159            }
1160        } else {
1161            unsafe { Entry::Vacant(VacantEntry::new(shard, key)) }
1162        }
1163    }
1164
1165    fn _try_entry(&'a self, key: K) -> Option<Entry<'a, K, V, S>> {
1166        let hash = self.hash_usize(&key);
1167
1168        let idx = self.determine_shard(hash);
1169
1170        let shard = match unsafe { self._try_yield_write_shard(idx) } {
1171            Some(shard) => shard,
1172            None => return None,
1173        };
1174
1175        if let Some((kptr, vptr)) = shard.get_key_value(&key) {
1176            unsafe {
1177                let kptr: *const K = kptr;
1178                let vptr: *mut V = vptr.as_ptr();
1179
1180                Some(Entry::Occupied(OccupiedEntry::new(
1181                    shard,
1182                    key,
1183                    (kptr, vptr),
1184                )))
1185            }
1186        } else {
1187            unsafe { Some(Entry::Vacant(VacantEntry::new(shard, key))) }
1188        }
1189    }
1190
1191    fn _hasher(&self) -> S {
1192        self.hasher.clone()
1193    }
1194}
1195
1196impl<K: Eq + Hash + fmt::Debug, V: fmt::Debug, S: BuildHasher + Clone> fmt::Debug
1197    for DashMap<K, V, S>
1198{
1199    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1200        let mut pmap = f.debug_map();
1201
1202        for r in self {
1203            let (k, v) = r.pair();
1204
1205            pmap.entry(k, v);
1206        }
1207
1208        pmap.finish()
1209    }
1210}
1211
1212impl<'a, K: 'a + Eq + Hash, V: 'a, S: BuildHasher + Clone> Shl<(K, V)> for &'a DashMap<K, V, S> {
1213    type Output = Option<V>;
1214
1215    fn shl(self, pair: (K, V)) -> Self::Output {
1216        self.insert(pair.0, pair.1)
1217    }
1218}
1219
1220impl<'a, K: 'a + Eq + Hash, V: 'a, S: BuildHasher + Clone, Q> Shr<&Q> for &'a DashMap<K, V, S>
1221where
1222    K: Borrow<Q>,
1223    Q: Hash + Eq + ?Sized,
1224{
1225    type Output = Ref<'a, K, V, S>;
1226
1227    fn shr(self, key: &Q) -> Self::Output {
1228        self.get(key).unwrap()
1229    }
1230}
1231
1232impl<'a, K: 'a + Eq + Hash, V: 'a, S: BuildHasher + Clone, Q> BitOr<&Q> for &'a DashMap<K, V, S>
1233where
1234    K: Borrow<Q>,
1235    Q: Hash + Eq + ?Sized,
1236{
1237    type Output = RefMut<'a, K, V, S>;
1238
1239    fn bitor(self, key: &Q) -> Self::Output {
1240        self.get_mut(key).unwrap()
1241    }
1242}
1243
1244impl<'a, K: 'a + Eq + Hash, V: 'a, S: BuildHasher + Clone, Q> Sub<&Q> for &'a DashMap<K, V, S>
1245where
1246    K: Borrow<Q>,
1247    Q: Hash + Eq + ?Sized,
1248{
1249    type Output = Option<(K, V)>;
1250
1251    fn sub(self, key: &Q) -> Self::Output {
1252        self.remove(key)
1253    }
1254}
1255
1256impl<'a, K: 'a + Eq + Hash, V: 'a, S: BuildHasher + Clone, Q> BitAnd<&Q> for &'a DashMap<K, V, S>
1257where
1258    K: Borrow<Q>,
1259    Q: Hash + Eq + ?Sized,
1260{
1261    type Output = bool;
1262
1263    fn bitand(self, key: &Q) -> Self::Output {
1264        self.contains_key(key)
1265    }
1266}
1267
1268impl<K: Eq + Hash, V, S: BuildHasher + Clone> IntoIterator for DashMap<K, V, S> {
1269    type Item = (K, V);
1270
1271    type IntoIter = OwningIter<K, V, S>;
1272
1273    fn into_iter(self) -> Self::IntoIter {
1274        OwningIter::new(self)
1275    }
1276}
1277
1278impl<'a, K: Eq + Hash, V, S: BuildHasher + Clone> IntoIterator for &'a DashMap<K, V, S> {
1279    type Item = RefMulti<'a, K, V, S>;
1280
1281    type IntoIter = Iter<'a, K, V, S, DashMap<K, V, S>>;
1282
1283    fn into_iter(self) -> Self::IntoIter {
1284        self.iter()
1285    }
1286}
1287
1288impl<K: Eq + Hash, V, S: BuildHasher + Clone> Extend<(K, V)> for DashMap<K, V, S> {
1289    fn extend<I: IntoIterator<Item = (K, V)>>(&mut self, intoiter: I) {
1290        for pair in intoiter.into_iter() {
1291            self.insert(pair.0, pair.1);
1292        }
1293    }
1294}
1295
1296impl<K: Eq + Hash, V, S: BuildHasher + Clone + Default> FromIterator<(K, V)> for DashMap<K, V, S> {
1297    fn from_iter<I: IntoIterator<Item = (K, V)>>(intoiter: I) -> Self {
1298        let mut map = DashMap::default();
1299
1300        map.extend(intoiter);
1301
1302        map
1303    }
1304}
1305
1306#[cfg(test)]
1307mod tests {
1308    use crate::DashMap;
1309    use std::collections::hash_map::RandomState;
1310
1311    #[test]
1312    fn test_basic() {
1313        let dm = DashMap::new();
1314
1315        dm.insert(0, 0);
1316
1317        assert_eq!(dm.get(&0).unwrap().value(), &0);
1318    }
1319
1320    #[test]
1321    fn test_default() {
1322        let dm: DashMap<u32, u32> = DashMap::default();
1323
1324        dm.insert(0, 0);
1325
1326        assert_eq!(dm.get(&0).unwrap().value(), &0);
1327    }
1328
1329    #[test]
1330    fn test_multiple_hashes() {
1331        let dm: DashMap<u32, u32> = DashMap::default();
1332
1333        for i in 0..100 {
1334            dm.insert(0, i);
1335
1336            dm.insert(i, i);
1337        }
1338
1339        for i in 1..100 {
1340            let r = dm.get(&i).unwrap();
1341
1342            assert_eq!(i, *r.value());
1343
1344            assert_eq!(i, *r.key());
1345        }
1346
1347        let r = dm.get(&0).unwrap();
1348
1349        assert_eq!(99, *r.value());
1350    }
1351
1352    #[test]
1353    fn test_more_complex_values() {
1354        #[derive(Hash, PartialEq, Debug, Clone)]
1355
1356        struct T0 {
1357            s: String,
1358            u: u8,
1359        }
1360
1361        let dm = DashMap::new();
1362
1363        let range = 0..10;
1364
1365        for i in range {
1366            let t = T0 {
1367                s: i.to_string(),
1368                u: i as u8,
1369            };
1370
1371            dm.insert(i, t.clone());
1372
1373            assert_eq!(&t, dm.get(&i).unwrap().value());
1374        }
1375    }
1376
1377    #[test]
1378    fn test_different_hashers_randomstate() {
1379        let dm_hm_default: DashMap<u32, u32, RandomState> =
1380            DashMap::with_hasher(RandomState::new());
1381
1382        for i in 0..10 {
1383            dm_hm_default.insert(i, i);
1384
1385            assert_eq!(i, *dm_hm_default.get(&i).unwrap().value());
1386        }
1387    }
1388
1389    #[test]
1390    fn test_map_view() {
1391        let dm = DashMap::new();
1392
1393        let vegetables: [String; 4] = [
1394            "Salad".to_string(),
1395            "Beans".to_string(),
1396            "Potato".to_string(),
1397            "Tomato".to_string(),
1398        ];
1399
1400        // Give it some values
1401        dm.insert(0, "Banana".to_string());
1402        dm.insert(4, "Pear".to_string());
1403        dm.insert(9, "Potato".to_string());
1404        dm.insert(12, "Chicken".to_string());
1405
1406        let potato_vegetableness = dm.view(&9, |_, v| vegetables.contains(v));
1407        assert_eq!(potato_vegetableness, Some(true));
1408
1409        let chicken_vegetableness = dm.view(&12, |_, v| vegetables.contains(v));
1410        assert_eq!(chicken_vegetableness, Some(false));
1411
1412        let not_in_map = dm.view(&30, |_k, _v| false);
1413        assert_eq!(not_in_map, None);
1414    }
1415
1416    #[test]
1417    fn test_try_get() {
1418        {
1419            let map = DashMap::new();
1420            map.insert("Johnny", 21);
1421
1422            assert_eq!(*map.try_get("Johnny").unwrap(), 21);
1423
1424            let _result1_locking = map.get_mut("Johnny");
1425
1426            let result2 = map.try_get("Johnny");
1427            assert!(result2.is_locked());
1428        }
1429
1430        {
1431            let map = DashMap::new();
1432            map.insert("Johnny", 21);
1433
1434            *map.try_get_mut("Johnny").unwrap() += 1;
1435            assert_eq!(*map.get("Johnny").unwrap(), 22);
1436
1437            let _result1_locking = map.get("Johnny");
1438
1439            let result2 = map.try_get_mut("Johnny");
1440            assert!(result2.is_locked());
1441        }
1442    }
1443
1444    #[test]
1445    fn test_try_reserve() {
1446        let mut map: DashMap<i32, i32> = DashMap::new();
1447        // DashMap is empty and doesn't allocate memory
1448        assert_eq!(map.capacity(), 0);
1449
1450        map.try_reserve(10).unwrap();
1451
1452        // And now map can hold at least 10 elements
1453        assert!(map.capacity() >= 10);
1454    }
1455
1456    #[test]
1457    fn test_try_reserve_errors() {
1458        let mut map: DashMap<i32, i32> = DashMap::new();
1459
1460        match map.try_reserve(usize::MAX) {
1461            Err(_) => {}
1462            _ => panic!("should have raised CapacityOverflow error"),
1463        }
1464    }
1465}