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 crossbeam_utils::CachePadded;
+38use iter::{Iter, IterMut, OwningIter};
+39pub use mapref::entry::{Entry, OccupiedEntry, VacantEntry};
+40use mapref::multiple::RefMulti;
+41use mapref::one::{Ref, RefMut};
+42use once_cell::sync::OnceCell;
+43pub use read_only::ReadOnlyView;
+44pub use set::DashSet;
+45use std::collections::hash_map::RandomState;
+46pub use t::Map;
+47use try_result::TryResult;
+48
+49cfg_if! {
+50 if #[cfg(feature = "raw-api")] {
+51 pub use util::SharedValue;
+52 } else {
+53 use util::SharedValue;
+54 }
+55}
+56
+57pub(crate) type HashMap<K, V> = hashbrown::raw::RawTable<(K, SharedValue<V>)>;
+58
+59#[non_exhaustive]
+64#[derive(Clone, PartialEq, Eq, Debug)]
+65pub struct TryReserveError {}
+66
+67fn default_shard_amount() -> usize {
+68 static DEFAULT_SHARD_AMOUNT: OnceCell<usize> = OnceCell::new();
+69 *DEFAULT_SHARD_AMOUNT.get_or_init(|| {
+70 (std::thread::available_parallelism().map_or(1, usize::from) * 4).next_power_of_two()
+71 })
+72}
+73
+74fn ncb(shard_amount: usize) -> usize {
+75 shard_amount.trailing_zeros() as usize
+76}
+77
+78pub struct DashMap<K, V, S = RandomState> {
+90 shift: usize,
+91 shards: Box<[CachePadded<RwLock<HashMap<K, V>>>]>,
+92 hasher: S,
+93}
+94
+95impl<K: Eq + Hash + Clone, V: Clone, S: Clone> Clone for DashMap<K, V, S> {
+96 fn clone(&self) -> Self {
+97 let mut inner_shards = Vec::new();
+98
+99 for shard in self.shards.iter() {
+100 let shard = shard.read();
+101
+102 inner_shards.push(CachePadded::new(RwLock::new((*shard).clone())));
+103 }
+104
+105 Self {
+106 shift: self.shift,
+107 shards: inner_shards.into_boxed_slice(),
+108 hasher: self.hasher.clone(),
+109 }
+110 }
+111}
+112
+113impl<K, V, S> Default for DashMap<K, V, S>
+114where
+115 K: Eq + Hash,
+116 S: Default + BuildHasher + Clone,
+117{
+118 fn default() -> Self {
+119 Self::with_hasher(Default::default())
+120 }
+121}
+122
+123impl<'a, K: 'a + Eq + Hash, V: 'a> DashMap<K, V, RandomState> {
+124 pub fn new() -> Self {
+135 DashMap::with_hasher(RandomState::default())
+136 }
+137
+138 pub fn with_capacity(capacity: usize) -> Self {
+150 DashMap::with_capacity_and_hasher(capacity, RandomState::default())
+151 }
+152
+153 pub fn with_shard_amount(shard_amount: usize) -> Self {
+168 Self::with_capacity_and_hasher_and_shard_amount(0, RandomState::default(), shard_amount)
+169 }
+170
+171 pub fn with_capacity_and_shard_amount(capacity: usize, shard_amount: usize) -> Self {
+186 Self::with_capacity_and_hasher_and_shard_amount(
+187 capacity,
+188 RandomState::default(),
+189 shard_amount,
+190 )
+191 }
+192}
+193
+194impl<'a, K: 'a + Eq + Hash, V: 'a, S: BuildHasher + Clone> DashMap<K, V, S> {
+195 pub fn into_read_only(self) -> ReadOnlyView<K, V, S> {
+197 ReadOnlyView::new(self)
+198 }
+199
+200 pub fn with_hasher(hasher: S) -> Self {
+213 Self::with_capacity_and_hasher(0, hasher)
+214 }
+215
+216 pub fn with_capacity_and_hasher(capacity: usize, hasher: S) -> Self {
+230 Self::with_capacity_and_hasher_and_shard_amount(capacity, hasher, default_shard_amount())
+231 }
+232
+233 pub fn with_hasher_and_shard_amount(hasher: S, shard_amount: usize) -> Self {
+250 Self::with_capacity_and_hasher_and_shard_amount(0, hasher, shard_amount)
+251 }
+252
+253 pub fn with_capacity_and_hasher_and_shard_amount(
+270 mut capacity: usize,
+271 hasher: S,
+272 shard_amount: usize,
+273 ) -> Self {
+274 assert!(shard_amount > 1);
+275 assert!(shard_amount.is_power_of_two());
+276
+277 let shift = util::ptr_size_bits() - ncb(shard_amount);
+278
+279 if capacity != 0 {
+280 capacity = (capacity + (shard_amount - 1)) & !(shard_amount - 1);
+281 }
+282
+283 let cps = capacity / shard_amount;
+284
+285 let shards = (0..shard_amount)
+286 .map(|_| CachePadded::new(RwLock::new(HashMap::with_capacity(cps))))
+287 .collect();
+288
+289 Self {
+290 shift,
+291 shards,
+292 hasher,
+293 }
+294 }
+295
+296 pub fn hash_usize<T: Hash>(&self, item: &T) -> usize {
+299 self.hash_u64(item) as usize
+300 }
+301
+302 fn hash_u64<T: Hash>(&self, item: &T) -> u64 {
+303 let mut hasher = self.hasher.build_hasher();
+304
+305 item.hash(&mut hasher);
+306
+307 hasher.finish()
+308 }
+309
+310 cfg_if! {
+311 if #[cfg(feature = "raw-api")] {
+312 pub fn shards(&self) -> &[CachePadded<RwLock<HashMap<K, V>>>] {
+326 &self.shards
+327 }
+328
+329 pub fn shards_mut(&mut self) -> &mut [CachePadded<RwLock<HashMap<K, V>>>] {
+355 &mut self.shards
+356 }
+357
+358 pub fn into_shards(self) -> Box<[CachePadded<RwLock<HashMap<K, V>>>]> {
+365 self.shards
+366 }
+367 } else {
+368 #[allow(dead_code)]
+369 pub(crate) fn shards(&self) -> &[CachePadded<RwLock<HashMap<K, V>>>] {
+370 &self.shards
+371 }
+372
+373 #[allow(dead_code)]
+374 pub(crate) fn shards_mut(&mut self) -> &mut [CachePadded<RwLock<HashMap<K, V>>>] {
+375 &mut self.shards
+376 }
+377
+378 #[allow(dead_code)]
+379 pub(crate) fn into_shards(self) -> Box<[CachePadded<RwLock<HashMap<K, V>>>]> {
+380 self.shards
+381 }
+382 }
+383 }
+384
+385 cfg_if! {
+386 if #[cfg(feature = "raw-api")] {
+387 pub fn determine_map<Q>(&self, key: &Q) -> usize
+403 where
+404 K: Borrow<Q>,
+405 Q: Hash + Eq + ?Sized,
+406 {
+407 let hash = self.hash_usize(&key);
+408 self.determine_shard(hash)
+409 }
+410 }
+411 }
+412
+413 cfg_if! {
+414 if #[cfg(feature = "raw-api")] {
+415 pub fn determine_shard(&self, hash: usize) -> usize {
+430 (hash << 7) >> self.shift
+432 }
+433 } else {
+434
+435 pub(crate) fn determine_shard(&self, hash: usize) -> usize {
+436 (hash << 7) >> self.shift
+438 }
+439 }
+440 }
+441
+442 pub fn hasher(&self) -> &S {
+457 &self.hasher
+458 }
+459
+460 pub fn insert(&self, key: K, value: V) -> Option<V> {
+473 self._insert(key, value)
+474 }
+475
+476 pub fn remove<Q>(&self, key: &Q) -> Option<(K, V)>
+490 where
+491 K: Borrow<Q>,
+492 Q: Hash + Eq + ?Sized,
+493 {
+494 self._remove(key)
+495 }
+496
+497 pub fn remove_if<Q>(&self, key: &Q, f: impl FnOnce(&K, &V) -> bool) -> Option<(K, V)>
+519 where
+520 K: Borrow<Q>,
+521 Q: Hash + Eq + ?Sized,
+522 {
+523 self._remove_if(key, f)
+524 }
+525
+526 pub fn remove_if_mut<Q>(&self, key: &Q, f: impl FnOnce(&K, &mut V) -> bool) -> Option<(K, V)>
+527 where
+528 K: Borrow<Q>,
+529 Q: Hash + Eq + ?Sized,
+530 {
+531 self._remove_if_mut(key, f)
+532 }
+533
+534 pub fn iter(&'a self) -> Iter<'a, K, V, S, DashMap<K, V, S>> {
+548 self._iter()
+549 }
+550
+551 pub fn iter_mut(&'a self) -> IterMut<'a, K, V, S, DashMap<K, V, S>> {
+566 self._iter_mut()
+567 }
+568
+569 pub fn get<Q>(&'a self, key: &Q) -> Option<Ref<'a, K, V>>
+583 where
+584 K: Borrow<Q>,
+585 Q: Hash + Eq + ?Sized,
+586 {
+587 self._get(key)
+588 }
+589
+590 pub fn get_mut<Q>(&'a self, key: &Q) -> Option<RefMut<'a, K, V>>
+605 where
+606 K: Borrow<Q>,
+607 Q: Hash + Eq + ?Sized,
+608 {
+609 self._get_mut(key)
+610 }
+611
+612 pub fn try_get<Q>(&'a self, key: &Q) -> TryResult<Ref<'a, K, V>>
+632 where
+633 K: Borrow<Q>,
+634 Q: Hash + Eq + ?Sized,
+635 {
+636 self._try_get(key)
+637 }
+638
+639 pub fn try_get_mut<Q>(&'a self, key: &Q) -> TryResult<RefMut<'a, K, V>>
+660 where
+661 K: Borrow<Q>,
+662 Q: Hash + Eq + ?Sized,
+663 {
+664 self._try_get_mut(key)
+665 }
+666
+667 pub fn shrink_to_fit(&self) {
+684 self._shrink_to_fit();
+685 }
+686
+687 pub fn retain(&self, f: impl FnMut(&K, &mut V) -> bool) {
+705 self._retain(f);
+706 }
+707
+708 pub fn len(&self) -> usize {
+724 self._len()
+725 }
+726
+727 pub fn is_empty(&self) -> bool {
+740 self._is_empty()
+741 }
+742
+743 pub fn clear(&self) {
+759 self._clear();
+760 }
+761
+762 pub fn capacity(&self) -> usize {
+766 self._capacity()
+767 }
+768
+769 pub fn alter<Q>(&self, key: &Q, f: impl FnOnce(&K, V) -> V)
+788 where
+789 K: Borrow<Q>,
+790 Q: Hash + Eq + ?Sized,
+791 {
+792 self._alter(key, f);
+793 }
+794
+795 pub fn alter_all(&self, f: impl FnMut(&K, V) -> V) {
+816 self._alter_all(f);
+817 }
+818
+819 pub fn view<Q, R>(&self, key: &Q, f: impl FnOnce(&K, &V) -> R) -> Option<R>
+839 where
+840 K: Borrow<Q>,
+841 Q: Hash + Eq + ?Sized,
+842 {
+843 self._view(key, f)
+844 }
+845
+846 pub fn contains_key<Q>(&self, key: &Q) -> bool
+860 where
+861 K: Borrow<Q>,
+862 Q: Hash + Eq + ?Sized,
+863 {
+864 self._contains_key(key)
+865 }
+866
+867 pub fn entry(&'a self, key: K) -> Entry<'a, K, V> {
+872 self._entry(key)
+873 }
+874
+875 pub fn try_entry(&'a self, key: K) -> Option<Entry<'a, K, V>> {
+880 self._try_entry(key)
+881 }
+882
+883 pub fn try_reserve(&mut self, additional: usize) -> Result<(), TryReserveError> {
+892 for shard in self.shards.iter() {
+893 shard
+894 .write()
+895 .try_reserve(additional, |(k, _v)| {
+896 let mut hasher = self.hasher.build_hasher();
+897 k.hash(&mut hasher);
+898 hasher.finish()
+899 })
+900 .map_err(|_| TryReserveError {})?;
+901 }
+902 Ok(())
+903 }
+904}
+905
+906impl<'a, K: 'a + Eq + Hash, V: 'a, S: 'a + BuildHasher + Clone> Map<'a, K, V, S>
+907 for DashMap<K, V, S>
+908{
+909 fn _shard_count(&self) -> usize {
+910 self.shards.len()
+911 }
+912
+913 unsafe fn _get_read_shard(&'a self, i: usize) -> &'a HashMap<K, V> {
+914 debug_assert!(i < self.shards.len());
+915
+916 &*self.shards.get_unchecked(i).data_ptr()
+917 }
+918
+919 unsafe fn _yield_read_shard(&'a self, i: usize) -> RwLockReadGuard<'a, HashMap<K, V>> {
+920 debug_assert!(i < self.shards.len());
+921
+922 self.shards.get_unchecked(i).read()
+923 }
+924
+925 unsafe fn _yield_write_shard(&'a self, i: usize) -> RwLockWriteGuard<'a, HashMap<K, V>> {
+926 debug_assert!(i < self.shards.len());
+927
+928 self.shards.get_unchecked(i).write()
+929 }
+930
+931 unsafe fn _try_yield_read_shard(
+932 &'a self,
+933 i: usize,
+934 ) -> Option<RwLockReadGuard<'a, HashMap<K, V>>> {
+935 debug_assert!(i < self.shards.len());
+936
+937 self.shards.get_unchecked(i).try_read()
+938 }
+939
+940 unsafe fn _try_yield_write_shard(
+941 &'a self,
+942 i: usize,
+943 ) -> Option<RwLockWriteGuard<'a, HashMap<K, V>>> {
+944 debug_assert!(i < self.shards.len());
+945
+946 self.shards.get_unchecked(i).try_write()
+947 }
+948
+949 fn _insert(&self, key: K, value: V) -> Option<V> {
+950 match self.entry(key) {
+951 Entry::Occupied(mut o) => Some(o.insert(value)),
+952 Entry::Vacant(v) => {
+953 v.insert(value);
+954 None
+955 }
+956 }
+957 }
+958
+959 fn _remove<Q>(&self, key: &Q) -> Option<(K, V)>
+960 where
+961 K: Borrow<Q>,
+962 Q: Hash + Eq + ?Sized,
+963 {
+964 let hash = self.hash_u64(&key);
+965
+966 let idx = self.determine_shard(hash as usize);
+967
+968 let mut shard = unsafe { self._yield_write_shard(idx) };
+969
+970 if let Some(bucket) = shard.find(hash, |(k, _v)| key == k.borrow()) {
+971 let ((k, v), _) = unsafe { shard.remove(bucket) };
+972 Some((k, v.into_inner()))
+973 } else {
+974 None
+975 }
+976 }
+977
+978 fn _remove_if<Q>(&self, key: &Q, f: impl FnOnce(&K, &V) -> bool) -> Option<(K, V)>
+979 where
+980 K: Borrow<Q>,
+981 Q: Hash + Eq + ?Sized,
+982 {
+983 let hash = self.hash_u64(&key);
+984
+985 let idx = self.determine_shard(hash as usize);
+986
+987 let mut shard = unsafe { self._yield_write_shard(idx) };
+988
+989 if let Some(bucket) = shard.find(hash, |(k, _v)| key == k.borrow()) {
+990 let (k, v) = unsafe { bucket.as_ref() };
+991 if f(k, v.get()) {
+992 let ((k, v), _) = unsafe { shard.remove(bucket) };
+993 Some((k, v.into_inner()))
+994 } else {
+995 None
+996 }
+997 } else {
+998 None
+999 }
+1000 }
+1001
+1002 fn _remove_if_mut<Q>(&self, key: &Q, f: impl FnOnce(&K, &mut V) -> bool) -> Option<(K, V)>
+1003 where
+1004 K: Borrow<Q>,
+1005 Q: Hash + Eq + ?Sized,
+1006 {
+1007 let hash = self.hash_u64(&key);
+1008
+1009 let idx = self.determine_shard(hash as usize);
+1010
+1011 let mut shard = unsafe { self._yield_write_shard(idx) };
+1012
+1013 if let Some(bucket) = shard.find(hash, |(k, _v)| key == k.borrow()) {
+1014 let (k, v) = unsafe { bucket.as_mut() };
+1015 if f(k, v.get_mut()) {
+1016 let ((k, v), _) = unsafe { shard.remove(bucket) };
+1017 Some((k, v.into_inner()))
+1018 } else {
+1019 None
+1020 }
+1021 } else {
+1022 None
+1023 }
+1024 }
+1025
+1026 fn _iter(&'a self) -> Iter<'a, K, V, S, DashMap<K, V, S>> {
+1027 Iter::new(self)
+1028 }
+1029
+1030 fn _iter_mut(&'a self) -> IterMut<'a, K, V, S, DashMap<K, V, S>> {
+1031 IterMut::new(self)
+1032 }
+1033
+1034 fn _get<Q>(&'a self, key: &Q) -> Option<Ref<'a, K, V>>
+1035 where
+1036 K: Borrow<Q>,
+1037 Q: Hash + Eq + ?Sized,
+1038 {
+1039 let hash = self.hash_u64(&key);
+1040
+1041 let idx = self.determine_shard(hash as usize);
+1042
+1043 let shard = unsafe { self._yield_read_shard(idx) };
+1044
+1045 if let Some(bucket) = shard.find(hash, |(k, _v)| key == k.borrow()) {
+1046 unsafe {
+1047 let (k, v) = bucket.as_ref();
+1048 Some(Ref::new(shard, k, v.as_ptr()))
+1049 }
+1050 } else {
+1051 None
+1052 }
+1053 }
+1054
+1055 fn _get_mut<Q>(&'a self, key: &Q) -> Option<RefMut<'a, K, V>>
+1056 where
+1057 K: Borrow<Q>,
+1058 Q: Hash + Eq + ?Sized,
+1059 {
+1060 let hash = self.hash_u64(&key);
+1061
+1062 let idx = self.determine_shard(hash as usize);
+1063
+1064 let shard = unsafe { self._yield_write_shard(idx) };
+1065
+1066 if let Some(bucket) = shard.find(hash, |(k, _v)| key == k.borrow()) {
+1067 unsafe {
+1068 let (k, v) = bucket.as_ref();
+1069 Some(RefMut::new(shard, k, v.as_ptr()))
+1070 }
+1071 } else {
+1072 None
+1073 }
+1074 }
+1075
+1076 fn _try_get<Q>(&'a self, key: &Q) -> TryResult<Ref<'a, K, V>>
+1077 where
+1078 K: Borrow<Q>,
+1079 Q: Hash + Eq + ?Sized,
+1080 {
+1081 let hash = self.hash_u64(&key);
+1082
+1083 let idx = self.determine_shard(hash as usize);
+1084
+1085 let shard = match unsafe { self._try_yield_read_shard(idx) } {
+1086 Some(shard) => shard,
+1087 None => return TryResult::Locked,
+1088 };
+1089
+1090 if let Some(bucket) = shard.find(hash, |(k, _v)| key == k.borrow()) {
+1091 unsafe {
+1092 let (k, v) = bucket.as_ref();
+1093 TryResult::Present(Ref::new(shard, k, v.as_ptr()))
+1094 }
+1095 } else {
+1096 TryResult::Absent
+1097 }
+1098 }
+1099
+1100 fn _try_get_mut<Q>(&'a self, key: &Q) -> TryResult<RefMut<'a, K, V>>
+1101 where
+1102 K: Borrow<Q>,
+1103 Q: Hash + Eq + ?Sized,
+1104 {
+1105 let hash = self.hash_u64(&key);
+1106
+1107 let idx = self.determine_shard(hash as usize);
+1108
+1109 let shard = match unsafe { self._try_yield_write_shard(idx) } {
+1110 Some(shard) => shard,
+1111 None => return TryResult::Locked,
+1112 };
+1113
+1114 if let Some(bucket) = shard.find(hash, |(k, _v)| key == k.borrow()) {
+1115 unsafe {
+1116 let (k, v) = bucket.as_ref();
+1117 TryResult::Present(RefMut::new(shard, k, v.as_ptr()))
+1118 }
+1119 } else {
+1120 TryResult::Absent
+1121 }
+1122 }
+1123
+1124 fn _shrink_to_fit(&self) {
+1125 self.shards.iter().for_each(|s| {
+1126 let mut shard = s.write();
+1127 let size = shard.len();
+1128 shard.shrink_to(size, |(k, _v)| {
+1129 let mut hasher = self.hasher.build_hasher();
+1130 k.hash(&mut hasher);
+1131 hasher.finish()
+1132 })
+1133 });
+1134 }
+1135
+1136 fn _retain(&self, mut f: impl FnMut(&K, &mut V) -> bool) {
+1137 self.shards.iter().for_each(|s| {
+1138 unsafe {
+1139 let mut shard = s.write();
+1140 for bucket in shard.iter() {
+1142 let (k, v) = bucket.as_mut();
+1143 if !f(&*k, v.get_mut()) {
+1144 shard.erase(bucket);
+1145 }
+1146 }
+1147 }
+1148 });
+1149 }
+1150
+1151 fn _len(&self) -> usize {
+1152 self.shards.iter().map(|s| s.read().len()).sum()
+1153 }
+1154
+1155 fn _capacity(&self) -> usize {
+1156 self.shards.iter().map(|s| s.read().capacity()).sum()
+1157 }
+1158
+1159 fn _alter<Q>(&self, key: &Q, f: impl FnOnce(&K, V) -> V)
+1160 where
+1161 K: Borrow<Q>,
+1162 Q: Hash + Eq + ?Sized,
+1163 {
+1164 if let Some(mut r) = self.get_mut(key) {
+1165 util::map_in_place_2(r.pair_mut(), f);
+1166 }
+1167 }
+1168
+1169 fn _alter_all(&self, mut f: impl FnMut(&K, V) -> V) {
+1170 self.iter_mut()
+1171 .for_each(|mut m| util::map_in_place_2(m.pair_mut(), &mut f));
+1172 }
+1173
+1174 fn _view<Q, R>(&self, key: &Q, f: impl FnOnce(&K, &V) -> R) -> Option<R>
+1175 where
+1176 K: Borrow<Q>,
+1177 Q: Hash + Eq + ?Sized,
+1178 {
+1179 self.get(key).map(|r| {
+1180 let (k, v) = r.pair();
+1181 f(k, v)
+1182 })
+1183 }
+1184
+1185 fn _entry(&'a self, key: K) -> Entry<'a, K, V> {
+1186 let hash = self.hash_u64(&key);
+1187
+1188 let idx = self.determine_shard(hash as usize);
+1189
+1190 let mut shard = unsafe { self._yield_write_shard(idx) };
+1191
+1192 match shard.find_or_find_insert_slot(
+1193 hash,
+1194 |(k, _v)| k == &key,
+1195 |(k, _v)| {
+1196 let mut hasher = self.hasher.build_hasher();
+1197 k.hash(&mut hasher);
+1198 hasher.finish()
+1199 },
+1200 ) {
+1201 Ok(elem) => Entry::Occupied(unsafe { OccupiedEntry::new(shard, key, elem) }),
+1202 Err(slot) => Entry::Vacant(unsafe { VacantEntry::new(shard, key, hash, slot) }),
+1203 }
+1204 }
+1205
+1206 fn _try_entry(&'a self, key: K) -> Option<Entry<'a, K, V>> {
+1207 let hash = self.hash_u64(&key);
+1208
+1209 let idx = self.determine_shard(hash as usize);
+1210
+1211 let mut shard = match unsafe { self._try_yield_write_shard(idx) } {
+1212 Some(shard) => shard,
+1213 None => return None,
+1214 };
+1215
+1216 match shard.find_or_find_insert_slot(
+1217 hash,
+1218 |(k, _v)| k == &key,
+1219 |(k, _v)| {
+1220 let mut hasher = self.hasher.build_hasher();
+1221 k.hash(&mut hasher);
+1222 hasher.finish()
+1223 },
+1224 ) {
+1225 Ok(elem) => Some(Entry::Occupied(unsafe {
+1226 OccupiedEntry::new(shard, key, elem)
+1227 })),
+1228 Err(slot) => Some(Entry::Vacant(unsafe {
+1229 VacantEntry::new(shard, key, hash, slot)
+1230 })),
+1231 }
+1232 }
+1233
+1234 fn _hasher(&self) -> S {
+1235 self.hasher.clone()
+1236 }
+1237}
+1238
+1239impl<K: Eq + Hash + fmt::Debug, V: fmt::Debug, S: BuildHasher + Clone> fmt::Debug
+1240 for DashMap<K, V, S>
+1241{
+1242 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+1243 let mut pmap = f.debug_map();
+1244
+1245 for r in self {
+1246 let (k, v) = r.pair();
+1247
+1248 pmap.entry(k, v);
+1249 }
+1250
+1251 pmap.finish()
+1252 }
+1253}
+1254
+1255impl<'a, K: 'a + Eq + Hash, V: 'a, S: BuildHasher + Clone> Shl<(K, V)> for &'a DashMap<K, V, S> {
+1256 type Output = Option<V>;
+1257
+1258 fn shl(self, pair: (K, V)) -> Self::Output {
+1259 self.insert(pair.0, pair.1)
+1260 }
+1261}
+1262
+1263impl<'a, K: 'a + Eq + Hash, V: 'a, S: BuildHasher + Clone, Q> Shr<&Q> for &'a DashMap<K, V, S>
+1264where
+1265 K: Borrow<Q>,
+1266 Q: Hash + Eq + ?Sized,
+1267{
+1268 type Output = Ref<'a, K, V>;
+1269
+1270 fn shr(self, key: &Q) -> Self::Output {
+1271 self.get(key).unwrap()
+1272 }
+1273}
+1274
+1275impl<'a, K: 'a + Eq + Hash, V: 'a, S: BuildHasher + Clone, Q> BitOr<&Q> for &'a DashMap<K, V, S>
+1276where
+1277 K: Borrow<Q>,
+1278 Q: Hash + Eq + ?Sized,
+1279{
+1280 type Output = RefMut<'a, K, V>;
+1281
+1282 fn bitor(self, key: &Q) -> Self::Output {
+1283 self.get_mut(key).unwrap()
+1284 }
+1285}
+1286
+1287impl<'a, K: 'a + Eq + Hash, V: 'a, S: BuildHasher + Clone, Q> Sub<&Q> for &'a DashMap<K, V, S>
+1288where
+1289 K: Borrow<Q>,
+1290 Q: Hash + Eq + ?Sized,
+1291{
+1292 type Output = Option<(K, V)>;
+1293
+1294 fn sub(self, key: &Q) -> Self::Output {
+1295 self.remove(key)
+1296 }
+1297}
+1298
+1299impl<'a, K: 'a + Eq + Hash, V: 'a, S: BuildHasher + Clone, Q> BitAnd<&Q> for &'a DashMap<K, V, S>
+1300where
+1301 K: Borrow<Q>,
+1302 Q: Hash + Eq + ?Sized,
+1303{
+1304 type Output = bool;
+1305
+1306 fn bitand(self, key: &Q) -> Self::Output {
+1307 self.contains_key(key)
+1308 }
+1309}
+1310
+1311impl<K: Eq + Hash, V, S: BuildHasher + Clone> IntoIterator for DashMap<K, V, S> {
+1312 type Item = (K, V);
+1313
+1314 type IntoIter = OwningIter<K, V, S>;
+1315
+1316 fn into_iter(self) -> Self::IntoIter {
+1317 OwningIter::new(self)
+1318 }
+1319}
+1320
+1321impl<'a, K: Eq + Hash, V, S: BuildHasher + Clone> IntoIterator for &'a DashMap<K, V, S> {
+1322 type Item = RefMulti<'a, K, V>;
+1323
+1324 type IntoIter = Iter<'a, K, V, S, DashMap<K, V, S>>;
+1325
+1326 fn into_iter(self) -> Self::IntoIter {
+1327 self.iter()
+1328 }
+1329}
+1330
+1331impl<K: Eq + Hash, V, S: BuildHasher + Clone> Extend<(K, V)> for DashMap<K, V, S> {
+1332 fn extend<I: IntoIterator<Item = (K, V)>>(&mut self, intoiter: I) {
+1333 for pair in intoiter.into_iter() {
+1334 self.insert(pair.0, pair.1);
+1335 }
+1336 }
+1337}
+1338
+1339impl<K: Eq + Hash, V, S: BuildHasher + Clone + Default> FromIterator<(K, V)> for DashMap<K, V, S> {
+1340 fn from_iter<I: IntoIterator<Item = (K, V)>>(intoiter: I) -> Self {
+1341 let mut map = DashMap::default();
+1342
+1343 map.extend(intoiter);
+1344
+1345 map
+1346 }
+1347}
+1348
+1349#[cfg(feature = "typesize")]
+1350impl<K, V, S> typesize::TypeSize for DashMap<K, V, S>
+1351where
+1352 K: typesize::TypeSize + Eq + Hash,
+1353 V: typesize::TypeSize,
+1354 S: typesize::TypeSize + Clone + BuildHasher,
+1355{
+1356 fn extra_size(&self) -> usize {
+1357 let shards_extra_size: usize = self
+1358 .shards
+1359 .iter()
+1360 .map(|shard_lock| {
+1361 let shard = shard_lock.read();
+1362 let hashtable_size = shard.allocation_info().1.size();
+1363
+1364 let iter = unsafe { shard.iter() };
+1366 let entry_size_iter = iter.map(|bucket| {
+1367 let (key, value) = unsafe { bucket.as_ref() };
+1369 key.extra_size() + value.get().extra_size()
+1370 });
+1371
+1372 core::mem::size_of::<CachePadded<RwLock<HashMap<K, V>>>>()
+1373 + hashtable_size
+1374 + entry_size_iter.sum::<usize>()
+1375 })
+1376 .sum();
+1377
+1378 self.hasher.extra_size() + shards_extra_size
+1379 }
+1380
+1381 typesize::if_typesize_details! {
+1382 fn get_collection_item_count(&self) -> Option<usize> {
+1383 Some(self.len())
+1384 }
+1385 }
+1386}
+1387
+1388#[cfg(test)]
+1389mod tests {
+1390 use crate::DashMap;
+1391 use std::collections::hash_map::RandomState;
+1392
+1393 #[test]
+1394 fn test_basic() {
+1395 let dm = DashMap::new();
+1396
+1397 dm.insert(0, 0);
+1398
+1399 assert_eq!(dm.get(&0).unwrap().value(), &0);
+1400 }
+1401
+1402 #[test]
+1403 fn test_default() {
+1404 let dm: DashMap<u32, u32> = DashMap::default();
+1405
+1406 dm.insert(0, 0);
+1407
+1408 assert_eq!(dm.get(&0).unwrap().value(), &0);
+1409 }
+1410
+1411 #[test]
+1412 fn test_multiple_hashes() {
+1413 let dm: DashMap<u32, u32> = DashMap::default();
+1414
+1415 for i in 0..100 {
+1416 dm.insert(0, i);
+1417
+1418 dm.insert(i, i);
+1419 }
+1420
+1421 for i in 1..100 {
+1422 let r = dm.get(&i).unwrap();
+1423
+1424 assert_eq!(i, *r.value());
+1425
+1426 assert_eq!(i, *r.key());
+1427 }
+1428
+1429 let r = dm.get(&0).unwrap();
+1430
+1431 assert_eq!(99, *r.value());
+1432 }
+1433
+1434 #[test]
+1435 fn test_more_complex_values() {
+1436 #[derive(Hash, PartialEq, Debug, Clone)]
+1437
+1438 struct T0 {
+1439 s: String,
+1440 u: u8,
+1441 }
+1442
+1443 let dm = DashMap::new();
+1444
+1445 let range = 0..10;
+1446
+1447 for i in range {
+1448 let t = T0 {
+1449 s: i.to_string(),
+1450 u: i as u8,
+1451 };
+1452
+1453 dm.insert(i, t.clone());
+1454
+1455 assert_eq!(&t, dm.get(&i).unwrap().value());
+1456 }
+1457 }
+1458
+1459 #[test]
+1460 fn test_different_hashers_randomstate() {
+1461 let dm_hm_default: DashMap<u32, u32, RandomState> =
+1462 DashMap::with_hasher(RandomState::new());
+1463
+1464 for i in 0..10 {
+1465 dm_hm_default.insert(i, i);
+1466
+1467 assert_eq!(i, *dm_hm_default.get(&i).unwrap().value());
+1468 }
+1469 }
+1470
+1471 #[test]
+1472 fn test_map_view() {
+1473 let dm = DashMap::new();
+1474
+1475 let vegetables: [String; 4] = [
+1476 "Salad".to_string(),
+1477 "Beans".to_string(),
+1478 "Potato".to_string(),
+1479 "Tomato".to_string(),
+1480 ];
+1481
+1482 dm.insert(0, "Banana".to_string());
+1484 dm.insert(4, "Pear".to_string());
+1485 dm.insert(9, "Potato".to_string());
+1486 dm.insert(12, "Chicken".to_string());
+1487
+1488 let potato_vegetableness = dm.view(&9, |_, v| vegetables.contains(v));
+1489 assert_eq!(potato_vegetableness, Some(true));
+1490
+1491 let chicken_vegetableness = dm.view(&12, |_, v| vegetables.contains(v));
+1492 assert_eq!(chicken_vegetableness, Some(false));
+1493
+1494 let not_in_map = dm.view(&30, |_k, _v| false);
+1495 assert_eq!(not_in_map, None);
+1496 }
+1497
+1498 #[test]
+1499 fn test_try_get() {
+1500 {
+1501 let map = DashMap::new();
+1502 map.insert("Johnny", 21);
+1503
+1504 assert_eq!(*map.try_get("Johnny").unwrap(), 21);
+1505
+1506 let _result1_locking = map.get_mut("Johnny");
+1507
+1508 let result2 = map.try_get("Johnny");
+1509 assert!(result2.is_locked());
+1510 }
+1511
+1512 {
+1513 let map = DashMap::new();
+1514 map.insert("Johnny", 21);
+1515
+1516 *map.try_get_mut("Johnny").unwrap() += 1;
+1517 assert_eq!(*map.get("Johnny").unwrap(), 22);
+1518
+1519 let _result1_locking = map.get("Johnny");
+1520
+1521 let result2 = map.try_get_mut("Johnny");
+1522 assert!(result2.is_locked());
+1523 }
+1524 }
+1525
+1526 #[test]
+1527 fn test_try_reserve() {
+1528 let mut map: DashMap<i32, i32> = DashMap::new();
+1529 assert_eq!(map.capacity(), 0);
+1531
+1532 map.try_reserve(10).unwrap();
+1533
+1534 assert!(map.capacity() >= 10);
+1536 }
+1537
+1538 #[test]
+1539 fn test_try_reserve_errors() {
+1540 let mut map: DashMap<i32, i32> = DashMap::new();
+1541
+1542 match map.try_reserve(usize::MAX) {
+1543 Err(_) => {}
+1544 _ => panic!("should have raised CapacityOverflow error"),
+1545 }
+1546 }
+1547}
+