1 #![allow(clippy::type_complexity)]
2 
3 #[cfg(feature = "arbitrary")]
4 mod arbitrary;
5 pub mod iter;
6 pub mod iter_set;
7 mod lock;
8 pub mod mapref;
9 mod read_only;
10 #[cfg(feature = "serde")]
11 mod serde;
12 mod set;
13 pub mod setref;
14 mod t;
15 pub mod try_result;
16 mod util;
17 
18 #[cfg(feature = "rayon")]
19 pub mod rayon {
20     pub mod map;
21     pub mod read_only;
22     pub mod set;
23 }
24 
25 #[cfg(not(feature = "raw-api"))]
26 use crate::lock::{RwLock, RwLockReadGuard, RwLockWriteGuard};
27 
28 #[cfg(feature = "raw-api")]
29 pub use crate::lock::{RawRwLock, RwLock, RwLockReadGuard, RwLockWriteGuard};
30 
31 use cfg_if::cfg_if;
32 use core::borrow::Borrow;
33 use core::fmt;
34 use core::hash::{BuildHasher, Hash, Hasher};
35 use core::iter::FromIterator;
36 use core::ops::{BitAnd, BitOr, Shl, Shr, Sub};
37 use iter::{Iter, IterMut, OwningIter};
38 use mapref::entry::{Entry, OccupiedEntry, VacantEntry};
39 use mapref::multiple::RefMulti;
40 use mapref::one::{Ref, RefMut};
41 use once_cell::sync::OnceCell;
42 pub use read_only::ReadOnlyView;
43 pub use set::DashSet;
44 use std::collections::hash_map::RandomState;
45 pub use t::Map;
46 use try_result::TryResult;
47 
48 cfg_if! {
49     if #[cfg(feature = "raw-api")] {
50         pub use util::SharedValue;
51     } else {
52         use util::SharedValue;
53     }
54 }
55 
56 pub(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)]
64 pub struct TryReserveError {}
65 
default_shard_amount() -> usize66 fn 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 
ncb(shard_amount: usize) -> usize73 fn 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.
88 pub struct DashMap<K, V, S = RandomState> {
89     shift: usize,
90     shards: Box<[RwLock<HashMap<K, V, S>>]>,
91     hasher: S,
92 }
93 
94 impl<K: Eq + Hash + Clone, V: Clone, S: Clone> Clone for DashMap<K, V, S> {
clone(&self) -> Self95     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 
112 impl<K, V, S> Default for DashMap<K, V, S>
113 where
114     K: Eq + Hash,
115     S: Default + BuildHasher + Clone,
116 {
default() -> Self117     fn default() -> Self {
118         Self::with_hasher(Default::default())
119     }
120 }
121 
122 impl<'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     /// ```
new() -> Self133     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     /// ```
with_capacity(capacity: usize) -> Self148     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     /// ```
with_shard_amount(shard_amount: usize) -> Self166     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     /// ```
with_capacity_and_shard_amount(capacity: usize, shard_amount: usize) -> Self184     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 
193 impl<'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.
into_read_only(self) -> ReadOnlyView<K, V, S>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     /// ```
with_hasher(hasher: S) -> Self211     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     /// ```
with_capacity_and_hasher(capacity: usize, hasher: S) -> Self228     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     /// ```
with_hasher_and_shard_amount(hasher: S, shard_amount: usize) -> Self248     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     /// ```
with_capacity_and_hasher_and_shard_amount( mut capacity: usize, hasher: S, shard_amount: usize, ) -> Self268     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.
hash_usize<T: Hash>(&self, item: &T) -> usize297     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
hasher(&self) -> &S442     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     /// ```
insert(&self, key: K, value: V) -> Option<V>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     /// ```
remove<Q>(&self, key: &Q) -> Option<(K, V)> where K: Borrow<Q>, Q: Hash + Eq + ?Sized,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     /// ```
remove_if<Q>(&self, key: &Q, f: impl FnOnce(&K, &V) -> bool) -> Option<(K, V)> where K: Borrow<Q>, Q: Hash + Eq + ?Sized,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 
remove_if_mut<Q>(&self, key: &Q, f: impl FnOnce(&K, &mut V) -> bool) -> Option<(K, V)> where K: Borrow<Q>, Q: Hash + Eq + ?Sized,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     /// ```
iter(&'a self) -> Iter<'a, K, V, S, DashMap<K, V, S>>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     /// ```
iter_mut(&'a self) -> IterMut<'a, K, V, S, DashMap<K, V, S>>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     /// ```
get<Q>(&'a self, key: &Q) -> Option<Ref<'a, K, V, S>> where K: Borrow<Q>, Q: Hash + Eq + ?Sized,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     /// ```
get_mut<Q>(&'a self, key: &Q) -> Option<RefMut<'a, K, V, S>> where K: Borrow<Q>, Q: Hash + Eq + ?Sized,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     /// ```
try_get<Q>(&'a self, key: &Q) -> TryResult<Ref<'a, K, V, S>> where K: Borrow<Q>, Q: Hash + Eq + ?Sized,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     /// ```
try_get_mut<Q>(&'a self, key: &Q) -> TryResult<RefMut<'a, K, V, S>> where K: Borrow<Q>, Q: Hash + Eq + ?Sized,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.
shrink_to_fit(&self)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     /// ```
retain(&self, f: impl FnMut(&K, &mut V) -> bool)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     /// ```
len(&self) -> usize696     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     /// ```
is_empty(&self) -> bool712     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     /// ```
clear(&self)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.
capacity(&self) -> usize738     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
alter<Q>(&self, key: &Q, f: impl FnOnce(&K, V) -> V) where K: Borrow<Q>, Q: Hash + Eq + ?Sized,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
alter_all(&self, f: impl FnMut(&K, V) -> V)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
view<Q, R>(&self, key: &Q, f: impl FnOnce(&K, &V) -> R) -> Option<R> where K: Borrow<Q>, Q: Hash + Eq + ?Sized,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     /// ```
contains_key<Q>(&self, key: &Q) -> bool where K: Borrow<Q>, Q: Hash + Eq + ?Sized,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.
entry(&'a self, key: K) -> Entry<'a, K, V, S>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.
try_entry(&'a self, key: K) -> Option<Entry<'a, K, V, S>>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.
try_reserve(&mut self, additional: usize) -> Result<(), TryReserveError>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 
875 impl<'a, K: 'a + Eq + Hash, V: 'a, S: 'a + BuildHasher + Clone> Map<'a, K, V, S>
876     for DashMap<K, V, S>
877 {
_shard_count(&self) -> usize878     fn _shard_count(&self) -> usize {
879         self.shards.len()
880     }
881 
_get_read_shard(&'a self, i: usize) -> &'a HashMap<K, V, S>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 
_yield_read_shard(&'a self, i: usize) -> RwLockReadGuard<'a, HashMap<K, V, S>>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 
_yield_write_shard(&'a self, i: usize) -> RwLockWriteGuard<'a, HashMap<K, V, S>>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 
_try_yield_read_shard( &'a self, i: usize, ) -> Option<RwLockReadGuard<'a, HashMap<K, V, S>>>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 
_try_yield_write_shard( &'a self, i: usize, ) -> Option<RwLockWriteGuard<'a, HashMap<K, V, S>>>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 
_insert(&self, key: K, value: V) -> Option<V>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 
_remove<Q>(&self, key: &Q) -> Option<(K, V)> where K: Borrow<Q>, Q: Hash + Eq + ?Sized,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 
_remove_if<Q>(&self, key: &Q, f: impl FnOnce(&K, &V) -> bool) -> Option<(K, V)> where K: Borrow<Q>, Q: Hash + Eq + ?Sized,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 
_remove_if_mut<Q>(&self, key: &Q, f: impl FnOnce(&K, &mut V) -> bool) -> Option<(K, V)> where K: Borrow<Q>, Q: Hash + Eq + ?Sized,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 
_iter(&'a self) -> Iter<'a, K, V, S, DashMap<K, V, S>>998     fn _iter(&'a self) -> Iter<'a, K, V, S, DashMap<K, V, S>> {
999         Iter::new(self)
1000     }
1001 
_iter_mut(&'a self) -> IterMut<'a, K, V, S, DashMap<K, V, S>>1002     fn _iter_mut(&'a self) -> IterMut<'a, K, V, S, DashMap<K, V, S>> {
1003         IterMut::new(self)
1004     }
1005 
_get<Q>(&'a self, key: &Q) -> Option<Ref<'a, K, V, S>> where K: Borrow<Q>, Q: Hash + Eq + ?Sized,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 
_get_mut<Q>(&'a self, key: &Q) -> Option<RefMut<'a, K, V, S>> where K: Borrow<Q>, Q: Hash + Eq + ?Sized,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 
_try_get<Q>(&'a self, key: &Q) -> TryResult<Ref<'a, K, V, S>> where K: Borrow<Q>, Q: Hash + Eq + ?Sized,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 
_try_get_mut<Q>(&'a self, key: &Q) -> TryResult<RefMut<'a, K, V, S>> where K: Borrow<Q>, Q: Hash + Eq + ?Sized,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 
_shrink_to_fit(&self)1100     fn _shrink_to_fit(&self) {
1101         self.shards.iter().for_each(|s| s.write().shrink_to_fit());
1102     }
1103 
_retain(&self, mut f: impl FnMut(&K, &mut V) -> bool)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 
_len(&self) -> usize1110     fn _len(&self) -> usize {
1111         self.shards.iter().map(|s| s.read().len()).sum()
1112     }
1113 
_capacity(&self) -> usize1114     fn _capacity(&self) -> usize {
1115         self.shards.iter().map(|s| s.read().capacity()).sum()
1116     }
1117 
_alter<Q>(&self, key: &Q, f: impl FnOnce(&K, V) -> V) where K: Borrow<Q>, Q: Hash + Eq + ?Sized,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 
_alter_all(&self, mut f: impl FnMut(&K, V) -> V)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 
_view<Q, R>(&self, key: &Q, f: impl FnOnce(&K, &V) -> R) -> Option<R> where K: Borrow<Q>, Q: Hash + Eq + ?Sized,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 
_entry(&'a self, key: K) -> Entry<'a, K, V, S>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 
_try_entry(&'a self, key: K) -> Option<Entry<'a, K, V, S>>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 
_hasher(&self) -> S1191     fn _hasher(&self) -> S {
1192         self.hasher.clone()
1193     }
1194 }
1195 
1196 impl<K: Eq + Hash + fmt::Debug, V: fmt::Debug, S: BuildHasher + Clone> fmt::Debug
1197     for DashMap<K, V, S>
1198 {
fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result1199     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 
1212 impl<'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 
shl(self, pair: (K, V)) -> Self::Output1215     fn shl(self, pair: (K, V)) -> Self::Output {
1216         self.insert(pair.0, pair.1)
1217     }
1218 }
1219 
1220 impl<'a, K: 'a + Eq + Hash, V: 'a, S: BuildHasher + Clone, Q> Shr<&Q> for &'a DashMap<K, V, S>
1221 where
1222     K: Borrow<Q>,
1223     Q: Hash + Eq + ?Sized,
1224 {
1225     type Output = Ref<'a, K, V, S>;
1226 
shr(self, key: &Q) -> Self::Output1227     fn shr(self, key: &Q) -> Self::Output {
1228         self.get(key).unwrap()
1229     }
1230 }
1231 
1232 impl<'a, K: 'a + Eq + Hash, V: 'a, S: BuildHasher + Clone, Q> BitOr<&Q> for &'a DashMap<K, V, S>
1233 where
1234     K: Borrow<Q>,
1235     Q: Hash + Eq + ?Sized,
1236 {
1237     type Output = RefMut<'a, K, V, S>;
1238 
bitor(self, key: &Q) -> Self::Output1239     fn bitor(self, key: &Q) -> Self::Output {
1240         self.get_mut(key).unwrap()
1241     }
1242 }
1243 
1244 impl<'a, K: 'a + Eq + Hash, V: 'a, S: BuildHasher + Clone, Q> Sub<&Q> for &'a DashMap<K, V, S>
1245 where
1246     K: Borrow<Q>,
1247     Q: Hash + Eq + ?Sized,
1248 {
1249     type Output = Option<(K, V)>;
1250 
sub(self, key: &Q) -> Self::Output1251     fn sub(self, key: &Q) -> Self::Output {
1252         self.remove(key)
1253     }
1254 }
1255 
1256 impl<'a, K: 'a + Eq + Hash, V: 'a, S: BuildHasher + Clone, Q> BitAnd<&Q> for &'a DashMap<K, V, S>
1257 where
1258     K: Borrow<Q>,
1259     Q: Hash + Eq + ?Sized,
1260 {
1261     type Output = bool;
1262 
bitand(self, key: &Q) -> Self::Output1263     fn bitand(self, key: &Q) -> Self::Output {
1264         self.contains_key(key)
1265     }
1266 }
1267 
1268 impl<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 
into_iter(self) -> Self::IntoIter1273     fn into_iter(self) -> Self::IntoIter {
1274         OwningIter::new(self)
1275     }
1276 }
1277 
1278 impl<'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 
into_iter(self) -> Self::IntoIter1283     fn into_iter(self) -> Self::IntoIter {
1284         self.iter()
1285     }
1286 }
1287 
1288 impl<K: Eq + Hash, V, S: BuildHasher + Clone> Extend<(K, V)> for DashMap<K, V, S> {
extend<I: IntoIterator<Item = (K, V)>>(&mut self, intoiter: I)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 
1296 impl<K: Eq + Hash, V, S: BuildHasher + Clone + Default> FromIterator<(K, V)> for DashMap<K, V, S> {
from_iter<I: IntoIterator<Item = (K, V)>>(intoiter: I) -> Self1297     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)]
1307 mod tests {
1308     use crate::DashMap;
1309     use std::collections::hash_map::RandomState;
1310 
1311     #[test]
test_basic()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]
test_default()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]
test_multiple_hashes()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]
test_more_complex_values()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]
test_different_hashers_randomstate()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]
test_map_view()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]
test_try_get()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]
test_try_reserve()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]
test_try_reserve_errors()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 }
1466