Skip to content

Commit febc45d

Browse files
committed
Revert "Only hash keys once, taking advantage of hashbrown raw entry api (#259)"
This reverts commit 3448b6f.
1 parent dfb7b9a commit febc45d

File tree

2 files changed

+67
-62
lines changed

2 files changed

+67
-62
lines changed

src/lib.rs

+50-54
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,6 @@ use core::fmt;
3434
use core::hash::{BuildHasher, Hash, Hasher};
3535
use core::iter::FromIterator;
3636
use core::ops::{BitAnd, BitOr, Shl, Shr, Sub};
37-
use hashbrown::hash_map::RawEntryMut;
3837
use iter::{Iter, IterMut, OwningIter};
3938
use mapref::entry::{Entry, OccupiedEntry, VacantEntry};
4039
use mapref::multiple::RefMulti;
@@ -296,15 +295,11 @@ impl<'a, K: 'a + Eq + Hash, V: 'a, S: BuildHasher + Clone> DashMap<K, V, S> {
296295
/// Hash a given item to produce a usize.
297296
/// Uses the provided or default HashBuilder.
298297
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 {
303298
let mut hasher = self.hasher.build_hasher();
304299

305300
item.hash(&mut hasher);
306301

307-
hasher.finish()
302+
hasher.finish() as usize
308303
}
309304

310305
cfg_if! {
@@ -921,9 +916,9 @@ impl<'a, K: 'a + Eq + Hash, V: 'a, S: 'a + BuildHasher + Clone> Map<'a, K, V, S>
921916
}
922917

923918
fn _insert(&self, key: K, value: V) -> Option<V> {
924-
let hash = self.hash_u64(&key);
919+
let hash = self.hash_usize(&key);
925920

926-
let idx = self.determine_shard(hash as usize);
921+
let idx = self.determine_shard(hash);
927922

928923
let mut shard = unsafe { self._yield_write_shard(idx) };
929924

@@ -937,9 +932,9 @@ impl<'a, K: 'a + Eq + Hash, V: 'a, S: 'a + BuildHasher + Clone> Map<'a, K, V, S>
937932
K: Borrow<Q>,
938933
Q: Hash + Eq + ?Sized,
939934
{
940-
let hash = self.hash_u64(&key);
935+
let hash = self.hash_usize(&key);
941936

942-
let idx = self.determine_shard(hash as usize);
937+
let idx = self.determine_shard(hash);
943938

944939
let mut shard = unsafe { self._yield_write_shard(idx) };
945940

@@ -951,20 +946,22 @@ impl<'a, K: 'a + Eq + Hash, V: 'a, S: 'a + BuildHasher + Clone> Map<'a, K, V, S>
951946
K: Borrow<Q>,
952947
Q: Hash + Eq + ?Sized,
953948
{
954-
let hash = self.hash_u64(&key);
949+
let hash = self.hash_usize(&key);
955950

956-
let idx = self.determine_shard(hash as usize);
951+
let idx = self.determine_shard(hash);
957952

958953
let mut shard = unsafe { self._yield_write_shard(idx) };
959954

960-
if let RawEntryMut::Occupied(entry) =
961-
shard.raw_entry_mut().from_key_hashed_nocheck(hash, key)
962-
{
963-
if f(entry.key(), entry.get().get()) {
964-
let (k, v) = entry.remove_entry();
965-
Some((k, v.into_inner()))
966-
} else {
967-
None
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+
}
968965
}
969966
} else {
970967
None
@@ -976,21 +973,22 @@ impl<'a, K: 'a + Eq + Hash, V: 'a, S: 'a + BuildHasher + Clone> Map<'a, K, V, S>
976973
K: Borrow<Q>,
977974
Q: Hash + Eq + ?Sized,
978975
{
979-
let hash = self.hash_u64(&key);
976+
let hash = self.hash_usize(&key);
980977

981-
let idx = self.determine_shard(hash as usize);
978+
let idx = self.determine_shard(hash);
982979

983980
let mut shard = unsafe { self._yield_write_shard(idx) };
984981

985-
if let RawEntryMut::Occupied(mut entry) =
986-
shard.raw_entry_mut().from_key_hashed_nocheck(hash, key)
987-
{
988-
let (k, v) = entry.get_key_value_mut();
989-
if f(k, v.get_mut()) {
990-
let (k, v) = entry.remove_entry();
991-
Some((k, v.into_inner()))
992-
} else {
993-
None
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+
}
994992
}
995993
} else {
996994
None
@@ -1010,13 +1008,13 @@ impl<'a, K: 'a + Eq + Hash, V: 'a, S: 'a + BuildHasher + Clone> Map<'a, K, V, S>
10101008
K: Borrow<Q>,
10111009
Q: Hash + Eq + ?Sized,
10121010
{
1013-
let hash = self.hash_u64(&key);
1011+
let hash = self.hash_usize(&key);
10141012

1015-
let idx = self.determine_shard(hash as usize);
1013+
let idx = self.determine_shard(hash);
10161014

10171015
let shard = unsafe { self._yield_read_shard(idx) };
10181016

1019-
if let Some((kptr, vptr)) = shard.raw_entry().from_key_hashed_nocheck(hash, key) {
1017+
if let Some((kptr, vptr)) = shard.get_key_value(key) {
10201018
unsafe {
10211019
let kptr: *const K = kptr;
10221020
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>
10321030
K: Borrow<Q>,
10331031
Q: Hash + Eq + ?Sized,
10341032
{
1035-
let hash = self.hash_u64(&key);
1033+
let hash = self.hash_usize(&key);
10361034

1037-
let idx = self.determine_shard(hash as usize);
1035+
let idx = self.determine_shard(hash);
10381036

1039-
let mut shard = unsafe { self._yield_write_shard(idx) };
1037+
let shard = unsafe { self._yield_write_shard(idx) };
10401038

1041-
if let RawEntryMut::Occupied(mut entry) =
1042-
shard.raw_entry_mut().from_key_hashed_nocheck(hash, key)
1043-
{
1039+
if let Some((kptr, vptr)) = shard.get_key_value(key) {
10441040
unsafe {
1045-
let kptr: *const K = entry.key();
1046-
let vptr: *mut V = entry.get_mut().as_ptr();
1041+
let kptr: *const K = kptr;
1042+
let vptr: *mut V = vptr.as_ptr();
10471043
Some(RefMut::new(shard, kptr, vptr))
10481044
}
10491045
} else {
@@ -1056,16 +1052,16 @@ impl<'a, K: 'a + Eq + Hash, V: 'a, S: 'a + BuildHasher + Clone> Map<'a, K, V, S>
10561052
K: Borrow<Q>,
10571053
Q: Hash + Eq + ?Sized,
10581054
{
1059-
let hash = self.hash_u64(&key);
1055+
let hash = self.hash_usize(&key);
10601056

1061-
let idx = self.determine_shard(hash as usize);
1057+
let idx = self.determine_shard(hash);
10621058

10631059
let shard = match unsafe { self._try_yield_read_shard(idx) } {
10641060
Some(shard) => shard,
10651061
None => return TryResult::Locked,
10661062
};
10671063

1068-
if let Some((kptr, vptr)) = shard.raw_entry().from_key_hashed_nocheck(hash, key) {
1064+
if let Some((kptr, vptr)) = shard.get_key_value(key) {
10691065
unsafe {
10701066
let kptr: *const K = kptr;
10711067
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>
10811077
K: Borrow<Q>,
10821078
Q: Hash + Eq + ?Sized,
10831079
{
1084-
let hash = self.hash_u64(&key);
1080+
let hash = self.hash_usize(&key);
10851081

1086-
let idx = self.determine_shard(hash as usize);
1082+
let idx = self.determine_shard(hash);
10871083

10881084
let shard = match unsafe { self._try_yield_write_shard(idx) } {
10891085
Some(shard) => shard,
10901086
None => return TryResult::Locked,
10911087
};
10921088

1093-
if let Some((kptr, vptr)) = shard.raw_entry().from_key_hashed_nocheck(hash, key) {
1089+
if let Some((kptr, vptr)) = shard.get_key_value(key) {
10941090
unsafe {
10951091
let kptr: *const K = kptr;
10961092
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>
11491145
}
11501146

11511147
fn _entry(&'a self, key: K) -> Entry<'a, K, V, S> {
1152-
let hash = self.hash_u64(&key);
1148+
let hash = self.hash_usize(&key);
11531149

1154-
let idx = self.determine_shard(hash as usize);
1150+
let idx = self.determine_shard(hash);
11551151

11561152
let shard = unsafe { self._yield_write_shard(idx) };
11571153

1158-
if let Some((kptr, vptr)) = shard.raw_entry().from_key_hashed_nocheck(hash, &key) {
1154+
if let Some((kptr, vptr)) = shard.get_key_value(&key) {
11591155
unsafe {
11601156
let kptr: *const K = kptr;
11611157
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>
11671163
}
11681164

11691165
fn _try_entry(&'a self, key: K) -> Option<Entry<'a, K, V, S>> {
1170-
let hash = self.hash_u64(&key);
1166+
let hash = self.hash_usize(&key);
11711167

1172-
let idx = self.determine_shard(hash as usize);
1168+
let idx = self.determine_shard(hash);
11731169

11741170
let shard = match unsafe { self._try_yield_write_shard(idx) } {
11751171
Some(shard) => shard,
11761172
None => return None,
11771173
};
11781174

1179-
if let Some((kptr, vptr)) = shard.raw_entry().from_key_hashed_nocheck(hash, &key) {
1175+
if let Some((kptr, vptr)) = shard.get_key_value(&key) {
11801176
unsafe {
11811177
let kptr: *const K = kptr;
11821178
let vptr: *mut V = vptr.as_ptr();

src/read_only.rs

+17-8
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,13 @@ impl<'a, K: 'a + Eq + Hash, V: 'a, S: BuildHasher + Clone> ReadOnlyView<K, V, S>
6161
K: Borrow<Q>,
6262
Q: Hash + Eq + ?Sized,
6363
{
64-
self.get(key).is_some()
64+
let hash = self.map.hash_usize(&key);
65+
66+
let idx = self.map.determine_shard(hash);
67+
68+
let shard = unsafe { self.map._get_read_shard(idx) };
69+
70+
shard.contains_key(key)
6571
}
6672

6773
/// 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, V, S>
7076
K: Borrow<Q>,
7177
Q: Hash + Eq + ?Sized,
7278
{
73-
self.get_key_value(key).map(|(_k, v)| v)
79+
let hash = self.map.hash_usize(&key);
80+
81+
let idx = self.map.determine_shard(hash);
82+
83+
let shard = unsafe { self.map._get_read_shard(idx) };
84+
85+
shard.get(key).map(|v| v.get())
7486
}
7587

7688
/// 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, V, S>
7991
K: Borrow<Q>,
8092
Q: Hash + Eq + ?Sized,
8193
{
82-
let hash = self.map.hash_u64(&key);
94+
let hash = self.map.hash_usize(&key);
8395

84-
let idx = self.map.determine_shard(hash as usize);
96+
let idx = self.map.determine_shard(hash);
8597

8698
let shard = unsafe { self.map._get_read_shard(idx) };
8799

88-
shard
89-
.raw_entry()
90-
.from_key_hashed_nocheck(hash, key)
91-
.map(|(k, v)| (k, v.get()))
100+
shard.get_key_value(key).map(|(k, v)| (k, v.get()))
92101
}
93102

94103
fn shard_read_iter(&'a self) -> impl Iterator<Item = &'a HashMap<K, V, S>> + 'a {

0 commit comments

Comments
 (0)