diff --git a/src/lib.rs b/src/lib.rs index 34e5d8b..a74e136 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -34,6 +34,7 @@ use core::fmt; use core::hash::{BuildHasher, Hash, Hasher}; use core::iter::FromIterator; use core::ops::{BitAnd, BitOr, Shl, Shr, Sub}; +use hashbrown::hash_map::RawEntryMut; use iter::{Iter, IterMut, OwningIter}; use mapref::entry::{Entry, OccupiedEntry, VacantEntry}; use mapref::multiple::RefMulti; @@ -295,11 +296,15 @@ impl<'a, K: 'a + Eq + Hash, V: 'a, S: BuildHasher + Clone> DashMap { /// Hash a given item to produce a usize. /// Uses the provided or default HashBuilder. pub fn hash_usize(&self, item: &T) -> usize { + self.hash_u64(item) as usize + } + + fn hash_u64(&self, item: &T) -> u64 { let mut hasher = self.hasher.build_hasher(); item.hash(&mut hasher); - hasher.finish() as usize + hasher.finish() } cfg_if! { @@ -916,9 +921,9 @@ impl<'a, K: 'a + Eq + Hash, V: 'a, S: 'a + BuildHasher + Clone> Map<'a, K, V, S> } fn _insert(&self, key: K, value: V) -> Option { - let hash = self.hash_usize(&key); + let hash = self.hash_u64(&key); - let idx = self.determine_shard(hash); + let idx = self.determine_shard(hash as usize); let mut shard = unsafe { self._yield_write_shard(idx) }; @@ -932,9 +937,9 @@ impl<'a, K: 'a + Eq + Hash, V: 'a, S: 'a + BuildHasher + Clone> Map<'a, K, V, S> K: Borrow, Q: Hash + Eq + ?Sized, { - let hash = self.hash_usize(&key); + let hash = self.hash_u64(&key); - let idx = self.determine_shard(hash); + let idx = self.determine_shard(hash as usize); let mut shard = unsafe { self._yield_write_shard(idx) }; @@ -946,22 +951,20 @@ impl<'a, K: 'a + Eq + Hash, V: 'a, S: 'a + BuildHasher + Clone> Map<'a, K, V, S> K: Borrow, Q: Hash + Eq + ?Sized, { - let hash = self.hash_usize(&key); + let hash = self.hash_u64(&key); - let idx = self.determine_shard(hash); + let idx = self.determine_shard(hash as usize); let mut shard = unsafe { self._yield_write_shard(idx) }; - if let Some((kptr, vptr)) = shard.get_key_value(key) { - unsafe { - let kptr: *const K = kptr; - let vptr: *mut V = vptr.as_ptr(); - - if f(&*kptr, &mut *vptr) { - shard.remove_entry(key).map(|(k, v)| (k, v.into_inner())) - } else { - None - } + if let RawEntryMut::Occupied(entry) = + shard.raw_entry_mut().from_key_hashed_nocheck(hash, key) + { + if f(&entry.key(), &entry.get().get()) { + let (k, v) = entry.remove_entry(); + Some((k, v.into_inner())) + } else { + None } } else { None @@ -973,22 +976,21 @@ impl<'a, K: 'a + Eq + Hash, V: 'a, S: 'a + BuildHasher + Clone> Map<'a, K, V, S> K: Borrow, Q: Hash + Eq + ?Sized, { - let hash = self.hash_usize(&key); + let hash = self.hash_u64(&key); - let idx = self.determine_shard(hash); + let idx = self.determine_shard(hash as usize); let mut shard = unsafe { self._yield_write_shard(idx) }; - if let Some((kptr, vptr)) = shard.get_key_value(key) { - unsafe { - let kptr: *const K = kptr; - let vptr: *mut V = vptr.as_ptr(); - - if f(&*kptr, &mut *vptr) { - shard.remove_entry(key).map(|(k, v)| (k, v.into_inner())) - } else { - None - } + if let RawEntryMut::Occupied(mut entry) = + shard.raw_entry_mut().from_key_hashed_nocheck(hash, key) + { + let (k, v) = entry.get_key_value_mut(); + if f(k, v.get_mut()) { + let (k, v) = entry.remove_entry(); + Some((k, v.into_inner())) + } else { + None } } else { None @@ -1008,13 +1010,13 @@ impl<'a, K: 'a + Eq + Hash, V: 'a, S: 'a + BuildHasher + Clone> Map<'a, K, V, S> K: Borrow, Q: Hash + Eq + ?Sized, { - let hash = self.hash_usize(&key); + let hash = self.hash_u64(&key); - let idx = self.determine_shard(hash); + let idx = self.determine_shard(hash as usize); let shard = unsafe { self._yield_read_shard(idx) }; - if let Some((kptr, vptr)) = shard.get_key_value(key) { + if let Some((kptr, vptr)) = shard.raw_entry().from_key_hashed_nocheck(hash, key) { unsafe { let kptr: *const K = kptr; let vptr: *const V = vptr.get(); @@ -1030,16 +1032,18 @@ impl<'a, K: 'a + Eq + Hash, V: 'a, S: 'a + BuildHasher + Clone> Map<'a, K, V, S> K: Borrow, Q: Hash + Eq + ?Sized, { - let hash = self.hash_usize(&key); + let hash = self.hash_u64(&key); - let idx = self.determine_shard(hash); + let idx = self.determine_shard(hash as usize); - let shard = unsafe { self._yield_write_shard(idx) }; + let mut shard = unsafe { self._yield_write_shard(idx) }; - if let Some((kptr, vptr)) = shard.get_key_value(key) { + if let RawEntryMut::Occupied(mut entry) = + shard.raw_entry_mut().from_key_hashed_nocheck(hash, key) + { unsafe { - let kptr: *const K = kptr; - let vptr: *mut V = vptr.as_ptr(); + let kptr: *const K = entry.key(); + let vptr: *mut V = entry.get_mut().as_ptr(); Some(RefMut::new(shard, kptr, vptr)) } } else { @@ -1052,16 +1056,16 @@ impl<'a, K: 'a + Eq + Hash, V: 'a, S: 'a + BuildHasher + Clone> Map<'a, K, V, S> K: Borrow, Q: Hash + Eq + ?Sized, { - let hash = self.hash_usize(&key); + let hash = self.hash_u64(&key); - let idx = self.determine_shard(hash); + let idx = self.determine_shard(hash as usize); let shard = match unsafe { self._try_yield_read_shard(idx) } { Some(shard) => shard, None => return TryResult::Locked, }; - if let Some((kptr, vptr)) = shard.get_key_value(key) { + if let Some((kptr, vptr)) = shard.raw_entry().from_key_hashed_nocheck(hash, key) { unsafe { let kptr: *const K = kptr; let vptr: *const V = vptr.get(); @@ -1077,16 +1081,16 @@ impl<'a, K: 'a + Eq + Hash, V: 'a, S: 'a + BuildHasher + Clone> Map<'a, K, V, S> K: Borrow, Q: Hash + Eq + ?Sized, { - let hash = self.hash_usize(&key); + let hash = self.hash_u64(&key); - let idx = self.determine_shard(hash); + let idx = self.determine_shard(hash as usize); let shard = match unsafe { self._try_yield_write_shard(idx) } { Some(shard) => shard, None => return TryResult::Locked, }; - if let Some((kptr, vptr)) = shard.get_key_value(key) { + if let Some((kptr, vptr)) = shard.raw_entry().from_key_hashed_nocheck(hash, key) { unsafe { let kptr: *const K = kptr; let vptr: *mut V = vptr.as_ptr(); @@ -1145,13 +1149,13 @@ impl<'a, K: 'a + Eq + Hash, V: 'a, S: 'a + BuildHasher + Clone> Map<'a, K, V, S> } fn _entry(&'a self, key: K) -> Entry<'a, K, V, S> { - let hash = self.hash_usize(&key); + let hash = self.hash_u64(&key); - let idx = self.determine_shard(hash); + let idx = self.determine_shard(hash as usize); let shard = unsafe { self._yield_write_shard(idx) }; - if let Some((kptr, vptr)) = shard.get_key_value(&key) { + if let Some((kptr, vptr)) = shard.raw_entry().from_key_hashed_nocheck(hash, &key) { unsafe { let kptr: *const K = kptr; let vptr: *mut V = vptr.as_ptr(); @@ -1163,16 +1167,16 @@ impl<'a, K: 'a + Eq + Hash, V: 'a, S: 'a + BuildHasher + Clone> Map<'a, K, V, S> } fn _try_entry(&'a self, key: K) -> Option> { - let hash = self.hash_usize(&key); + let hash = self.hash_u64(&key); - let idx = self.determine_shard(hash); + let idx = self.determine_shard(hash as usize); let shard = match unsafe { self._try_yield_write_shard(idx) } { Some(shard) => shard, None => return None, }; - if let Some((kptr, vptr)) = shard.get_key_value(&key) { + if let Some((kptr, vptr)) = shard.raw_entry().from_key_hashed_nocheck(hash, &key) { unsafe { let kptr: *const K = kptr; let vptr: *mut V = vptr.as_ptr(); diff --git a/src/read_only.rs b/src/read_only.rs index 42ee443..a8feb43 100644 --- a/src/read_only.rs +++ b/src/read_only.rs @@ -61,13 +61,7 @@ impl<'a, K: 'a + Eq + Hash, V: 'a, S: BuildHasher + Clone> ReadOnlyView K: Borrow, Q: Hash + Eq + ?Sized, { - let hash = self.map.hash_usize(&key); - - let idx = self.map.determine_shard(hash); - - let shard = unsafe { self.map._get_read_shard(idx) }; - - shard.contains_key(key) + self.get(key).is_some() } /// Returns a reference to the value corresponding to the key. @@ -76,13 +70,7 @@ impl<'a, K: 'a + Eq + Hash, V: 'a, S: BuildHasher + Clone> ReadOnlyView K: Borrow, Q: Hash + Eq + ?Sized, { - let hash = self.map.hash_usize(&key); - - let idx = self.map.determine_shard(hash); - - let shard = unsafe { self.map._get_read_shard(idx) }; - - shard.get(key).map(|v| v.get()) + self.get_key_value(key).map(|(_k, v)| v) } /// Returns the key-value pair corresponding to the supplied key. @@ -91,13 +79,16 @@ impl<'a, K: 'a + Eq + Hash, V: 'a, S: BuildHasher + Clone> ReadOnlyView K: Borrow, Q: Hash + Eq + ?Sized, { - let hash = self.map.hash_usize(&key); + let hash = self.map.hash_u64(&key); - let idx = self.map.determine_shard(hash); + let idx = self.map.determine_shard(hash as usize); let shard = unsafe { self.map._get_read_shard(idx) }; - shard.get_key_value(key).map(|(k, v)| (k, v.get())) + shard + .raw_entry() + .from_key_hashed_nocheck(hash, key) + .map(|(k, v)| (k, v.get())) } fn shard_read_iter(&'a self) -> impl Iterator> + 'a {