diff --git a/src/lib.rs b/src/lib.rs index 800a8d5..34e5d8b 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -34,7 +34,6 @@ 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; @@ -296,15 +295,11 @@ 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() + hasher.finish() as usize } cfg_if! { @@ -921,9 +916,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_u64(&key); + let hash = self.hash_usize(&key); - let idx = self.determine_shard(hash as usize); + let idx = self.determine_shard(hash); let mut shard = unsafe { self._yield_write_shard(idx) }; @@ -937,9 +932,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_u64(&key); + let hash = self.hash_usize(&key); - let idx = self.determine_shard(hash as usize); + let idx = self.determine_shard(hash); let mut shard = unsafe { self._yield_write_shard(idx) }; @@ -951,20 +946,22 @@ 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_u64(&key); + let hash = self.hash_usize(&key); - let idx = self.determine_shard(hash as usize); + let idx = self.determine_shard(hash); let mut shard = unsafe { self._yield_write_shard(idx) }; - 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 + 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 + } } } else { None @@ -976,21 +973,22 @@ 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_u64(&key); + let hash = self.hash_usize(&key); - let idx = self.determine_shard(hash as usize); + let idx = self.determine_shard(hash); let mut shard = unsafe { self._yield_write_shard(idx) }; - 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 + 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 + } } } else { None @@ -1010,13 +1008,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_u64(&key); + let hash = self.hash_usize(&key); - let idx = self.determine_shard(hash as usize); + let idx = self.determine_shard(hash); let shard = unsafe { self._yield_read_shard(idx) }; - if let Some((kptr, vptr)) = shard.raw_entry().from_key_hashed_nocheck(hash, key) { + if let Some((kptr, vptr)) = shard.get_key_value(key) { unsafe { let kptr: *const K = kptr; let vptr: *const V = vptr.get(); @@ -1032,18 +1030,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_u64(&key); + let hash = self.hash_usize(&key); - let idx = self.determine_shard(hash as usize); + let idx = self.determine_shard(hash); - let mut shard = unsafe { self._yield_write_shard(idx) }; + let shard = unsafe { self._yield_write_shard(idx) }; - if let RawEntryMut::Occupied(mut entry) = - shard.raw_entry_mut().from_key_hashed_nocheck(hash, key) - { + if let Some((kptr, vptr)) = shard.get_key_value(key) { unsafe { - let kptr: *const K = entry.key(); - let vptr: *mut V = entry.get_mut().as_ptr(); + let kptr: *const K = kptr; + let vptr: *mut V = vptr.as_ptr(); Some(RefMut::new(shard, kptr, vptr)) } } else { @@ -1056,16 +1052,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_u64(&key); + let hash = self.hash_usize(&key); - let idx = self.determine_shard(hash as usize); + let idx = self.determine_shard(hash); let shard = match unsafe { self._try_yield_read_shard(idx) } { Some(shard) => shard, None => return TryResult::Locked, }; - if let Some((kptr, vptr)) = shard.raw_entry().from_key_hashed_nocheck(hash, key) { + if let Some((kptr, vptr)) = shard.get_key_value(key) { unsafe { let kptr: *const K = kptr; let vptr: *const V = vptr.get(); @@ -1081,16 +1077,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_u64(&key); + let hash = self.hash_usize(&key); - let idx = self.determine_shard(hash as usize); + let idx = self.determine_shard(hash); let shard = match unsafe { self._try_yield_write_shard(idx) } { Some(shard) => shard, None => return TryResult::Locked, }; - if let Some((kptr, vptr)) = shard.raw_entry().from_key_hashed_nocheck(hash, key) { + if let Some((kptr, vptr)) = shard.get_key_value(key) { unsafe { let kptr: *const K = kptr; let vptr: *mut V = vptr.as_ptr(); @@ -1149,13 +1145,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_u64(&key); + let hash = self.hash_usize(&key); - let idx = self.determine_shard(hash as usize); + let idx = self.determine_shard(hash); let shard = unsafe { self._yield_write_shard(idx) }; - if let Some((kptr, vptr)) = shard.raw_entry().from_key_hashed_nocheck(hash, &key) { + if let Some((kptr, vptr)) = shard.get_key_value(&key) { unsafe { let kptr: *const K = kptr; let vptr: *mut V = vptr.as_ptr(); @@ -1167,16 +1163,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_u64(&key); + let hash = self.hash_usize(&key); - let idx = self.determine_shard(hash as usize); + let idx = self.determine_shard(hash); let shard = match unsafe { self._try_yield_write_shard(idx) } { Some(shard) => shard, None => return None, }; - if let Some((kptr, vptr)) = shard.raw_entry().from_key_hashed_nocheck(hash, &key) { + if let Some((kptr, vptr)) = shard.get_key_value(&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 a8feb43..42ee443 100644 --- a/src/read_only.rs +++ b/src/read_only.rs @@ -61,7 +61,13 @@ impl<'a, K: 'a + Eq + Hash, V: 'a, S: BuildHasher + Clone> ReadOnlyView K: Borrow, Q: Hash + Eq + ?Sized, { - self.get(key).is_some() + 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) } /// Returns a reference to the value corresponding to the key. @@ -70,7 +76,13 @@ impl<'a, K: 'a + Eq + Hash, V: 'a, S: BuildHasher + Clone> ReadOnlyView K: Borrow, Q: Hash + Eq + ?Sized, { - self.get_key_value(key).map(|(_k, v)| v) + 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()) } /// Returns the key-value pair corresponding to the supplied key. @@ -79,16 +91,13 @@ impl<'a, K: 'a + Eq + Hash, V: 'a, S: BuildHasher + Clone> ReadOnlyView K: Borrow, Q: Hash + Eq + ?Sized, { - let hash = self.map.hash_u64(&key); + let hash = self.map.hash_usize(&key); - let idx = self.map.determine_shard(hash as usize); + let idx = self.map.determine_shard(hash); let shard = unsafe { self.map._get_read_shard(idx) }; - shard - .raw_entry() - .from_key_hashed_nocheck(hash, key) - .map(|(k, v)| (k, v.get())) + shard.get_key_value(key).map(|(k, v)| (k, v.get())) } fn shard_read_iter(&'a self) -> impl Iterator> + 'a {