@@ -35,6 +35,7 @@ use core::hash::{BuildHasher, Hash, Hasher};
35
35
use core:: iter:: FromIterator ;
36
36
use core:: ops:: { BitAnd , BitOr , Shl , Shr , Sub } ;
37
37
use crossbeam_utils:: CachePadded ;
38
+ use hashbrown:: hash_table;
38
39
use iter:: { Iter , IterMut , OwningIter } ;
39
40
use lock:: { RwLockReadGuardDetached , RwLockWriteGuardDetached } ;
40
41
pub use mapref:: entry:: { Entry , OccupiedEntry , VacantEntry } ;
@@ -47,7 +48,7 @@ use std::collections::hash_map::RandomState;
47
48
pub use t:: Map ;
48
49
use try_result:: TryResult ;
49
50
50
- pub ( crate ) type HashMap < K , V > = hashbrown :: raw :: RawTable < ( K , V ) > ;
51
+ pub ( crate ) type HashMap < K , V > = hash_table :: HashTable < ( K , V ) > ;
51
52
52
53
// Temporary reimplementation of [`std::collections::TryReserveError`]
53
54
// util [`std::collections::TryReserveError`] stabilises.
@@ -340,7 +341,7 @@ impl<'a, K: 'a + Eq + Hash, V: 'a, S: BuildHasher + Clone> DashMap<K, V, S> {
340
341
/// };
341
342
/// let data = (42, "forty two");
342
343
/// let hash = hasher(&data);
343
- /// map.shards_mut()[shard_ind].get_mut().insert (hash, data, hasher);
344
+ /// map.shards_mut()[shard_ind].get_mut().insert_unique (hash, data, hasher);
344
345
/// assert_eq!(*map.get(&42).unwrap(), "forty two");
345
346
/// ```
346
347
pub fn shards_mut( & mut self ) -> & mut [ CachePadded <RwLock <HashMap <K , V >>>] {
@@ -959,8 +960,8 @@ impl<'a, K: 'a + Eq + Hash, V: 'a, S: 'a + BuildHasher + Clone> Map<'a, K, V, S>
959
960
960
961
let mut shard = unsafe { self . _yield_write_shard ( idx) } ;
961
962
962
- if let Some ( bucket ) = shard. find ( hash, |( k, _v) | key == k. borrow ( ) ) {
963
- let ( ( k, v) , _) = unsafe { shard . remove ( bucket ) } ;
963
+ if let Ok ( entry ) = shard. find_entry ( hash, |( k, _v) | key == k. borrow ( ) ) {
964
+ let ( ( k, v) , _) = entry . remove ( ) ;
964
965
Some ( ( k, v) )
965
966
} else {
966
967
None
@@ -978,10 +979,10 @@ impl<'a, K: 'a + Eq + Hash, V: 'a, S: 'a + BuildHasher + Clone> Map<'a, K, V, S>
978
979
979
980
let mut shard = unsafe { self . _yield_write_shard ( idx) } ;
980
981
981
- if let Some ( bucket ) = shard. find ( hash, |( k, _v) | key == k. borrow ( ) ) {
982
- let ( k, v) = unsafe { bucket . as_ref ( ) } ;
982
+ if let Ok ( entry ) = shard. find_entry ( hash, |( k, _v) | key == k. borrow ( ) ) {
983
+ let ( k, v) = entry . get ( ) ;
983
984
if f ( k, v) {
984
- let ( ( k, v) , _) = unsafe { shard . remove ( bucket ) } ;
985
+ let ( ( k, v) , _) = entry . remove ( ) ;
985
986
Some ( ( k, v) )
986
987
} else {
987
988
None
@@ -1002,10 +1003,10 @@ impl<'a, K: 'a + Eq + Hash, V: 'a, S: 'a + BuildHasher + Clone> Map<'a, K, V, S>
1002
1003
1003
1004
let mut shard = unsafe { self . _yield_write_shard ( idx) } ;
1004
1005
1005
- if let Some ( bucket ) = shard. find ( hash, |( k, _v) | key == k. borrow ( ) ) {
1006
- let ( k, v) = unsafe { bucket . as_mut ( ) } ;
1006
+ if let Ok ( mut entry ) = shard. find_entry ( hash, |( k, _v) | key == k. borrow ( ) ) {
1007
+ let ( k, v) = entry . get_mut ( ) ;
1007
1008
if f ( k, v) {
1008
- let ( ( k, v) , _) = unsafe { shard . remove ( bucket ) } ;
1009
+ let ( ( k, v) , _) = entry . remove ( ) ;
1009
1010
Some ( ( k, v) )
1010
1011
} else {
1011
1012
None
@@ -1036,11 +1037,8 @@ impl<'a, K: 'a + Eq + Hash, V: 'a, S: 'a + BuildHasher + Clone> Map<'a, K, V, S>
1036
1037
// SAFETY: The data will not outlive the guard, since we pass the guard to `Ref`.
1037
1038
let ( guard, shard) = unsafe { RwLockReadGuardDetached :: detach_from ( shard) } ;
1038
1039
1039
- if let Some ( bucket) = shard. find ( hash, |( k, _v) | key == k. borrow ( ) ) {
1040
- unsafe {
1041
- let ( k, v) = bucket. as_ref ( ) ;
1042
- Some ( Ref :: new ( guard, k, v) )
1043
- }
1040
+ if let Some ( ( k, v) ) = shard. find ( hash, |( k, _v) | key == k. borrow ( ) ) {
1041
+ unsafe { Some ( Ref :: new ( guard, k, v) ) }
1044
1042
} else {
1045
1043
None
1046
1044
}
@@ -1059,11 +1057,8 @@ impl<'a, K: 'a + Eq + Hash, V: 'a, S: 'a + BuildHasher + Clone> Map<'a, K, V, S>
1059
1057
// SAFETY: The data will not outlive the guard, since we pass the guard to `RefMut`.
1060
1058
let ( guard, shard) = unsafe { RwLockWriteGuardDetached :: detach_from ( shard) } ;
1061
1059
1062
- if let Some ( bucket) = shard. find ( hash, |( k, _v) | key == k. borrow ( ) ) {
1063
- unsafe {
1064
- let ( k, v) = bucket. as_mut ( ) ;
1065
- Some ( RefMut :: new ( guard, k, v) )
1066
- }
1060
+ if let Some ( ( k, v) ) = shard. find_mut ( hash, |( k, _v) | key == k. borrow ( ) ) {
1061
+ unsafe { Some ( RefMut :: new ( guard, k, v) ) }
1067
1062
} else {
1068
1063
None
1069
1064
}
@@ -1085,11 +1080,8 @@ impl<'a, K: 'a + Eq + Hash, V: 'a, S: 'a + BuildHasher + Clone> Map<'a, K, V, S>
1085
1080
// SAFETY: The data will not outlive the guard, since we pass the guard to `Ref`.
1086
1081
let ( guard, shard) = unsafe { RwLockReadGuardDetached :: detach_from ( shard) } ;
1087
1082
1088
- if let Some ( bucket) = shard. find ( hash, |( k, _v) | key == k. borrow ( ) ) {
1089
- unsafe {
1090
- let ( k, v) = bucket. as_ref ( ) ;
1091
- TryResult :: Present ( Ref :: new ( guard, k, v) )
1092
- }
1083
+ if let Some ( ( k, v) ) = shard. find ( hash, |( k, _v) | key == k. borrow ( ) ) {
1084
+ unsafe { TryResult :: Present ( Ref :: new ( guard, k, v) ) }
1093
1085
} else {
1094
1086
TryResult :: Absent
1095
1087
}
@@ -1111,11 +1103,8 @@ impl<'a, K: 'a + Eq + Hash, V: 'a, S: 'a + BuildHasher + Clone> Map<'a, K, V, S>
1111
1103
// SAFETY: The data will not outlive the guard, since we pass the guard to `RefMut`.
1112
1104
let ( guard, shard) = unsafe { RwLockWriteGuardDetached :: detach_from ( shard) } ;
1113
1105
1114
- if let Some ( bucket) = shard. find ( hash, |( k, _v) | key == k. borrow ( ) ) {
1115
- unsafe {
1116
- let ( k, v) = bucket. as_mut ( ) ;
1117
- TryResult :: Present ( RefMut :: new ( guard, k, v) )
1118
- }
1106
+ if let Some ( ( k, v) ) = shard. find_mut ( hash, |( k, _v) | key == k. borrow ( ) ) {
1107
+ unsafe { TryResult :: Present ( RefMut :: new ( guard, k, v) ) }
1119
1108
} else {
1120
1109
TryResult :: Absent
1121
1110
}
@@ -1135,16 +1124,7 @@ impl<'a, K: 'a + Eq + Hash, V: 'a, S: 'a + BuildHasher + Clone> Map<'a, K, V, S>
1135
1124
1136
1125
fn _retain ( & self , mut f : impl FnMut ( & K , & mut V ) -> bool ) {
1137
1126
self . shards . iter ( ) . for_each ( |s| {
1138
- unsafe {
1139
- let mut shard = s. write ( ) ;
1140
- // Here we only use `iter` as a temporary, preventing use-after-free
1141
- for bucket in shard. iter ( ) {
1142
- let ( k, v) = bucket. as_mut ( ) ;
1143
- if !f ( & * k, v) {
1144
- shard. erase ( bucket) ;
1145
- }
1146
- }
1147
- }
1127
+ s. write ( ) . retain ( |( k, v) | f ( k, v) ) ;
1148
1128
} ) ;
1149
1129
}
1150
1130
@@ -1191,7 +1171,7 @@ impl<'a, K: 'a + Eq + Hash, V: 'a, S: 'a + BuildHasher + Clone> Map<'a, K, V, S>
1191
1171
// SAFETY: The data will not outlive the guard, since we pass the guard to `Entry`.
1192
1172
let ( guard, shard) = unsafe { RwLockWriteGuardDetached :: detach_from ( shard) } ;
1193
1173
1194
- match shard. find_or_find_insert_slot (
1174
+ match shard. entry (
1195
1175
hash,
1196
1176
|( k, _v) | k == & key,
1197
1177
|( k, _v) | {
@@ -1200,8 +1180,12 @@ impl<'a, K: 'a + Eq + Hash, V: 'a, S: 'a + BuildHasher + Clone> Map<'a, K, V, S>
1200
1180
hasher. finish ( )
1201
1181
} ,
1202
1182
) {
1203
- Ok ( elem) => Entry :: Occupied ( unsafe { OccupiedEntry :: new ( guard, key, shard, elem) } ) ,
1204
- Err ( slot) => Entry :: Vacant ( unsafe { VacantEntry :: new ( guard, key, hash, shard, slot) } ) ,
1183
+ hash_table:: Entry :: Occupied ( entry) => {
1184
+ Entry :: Occupied ( unsafe { OccupiedEntry :: new ( guard, key, entry) } )
1185
+ }
1186
+ hash_table:: Entry :: Vacant ( entry) => {
1187
+ Entry :: Vacant ( unsafe { VacantEntry :: new ( guard, key, entry) } )
1188
+ }
1205
1189
}
1206
1190
}
1207
1191
@@ -1217,7 +1201,7 @@ impl<'a, K: 'a + Eq + Hash, V: 'a, S: 'a + BuildHasher + Clone> Map<'a, K, V, S>
1217
1201
// SAFETY: The data will not outlive the guard, since we pass the guard to `Entry`.
1218
1202
let ( guard, shard) = unsafe { RwLockWriteGuardDetached :: detach_from ( shard) } ;
1219
1203
1220
- match shard. find_or_find_insert_slot (
1204
+ match shard. entry (
1221
1205
hash,
1222
1206
|( k, _v) | k == & key,
1223
1207
|( k, _v) | {
@@ -1226,11 +1210,11 @@ impl<'a, K: 'a + Eq + Hash, V: 'a, S: 'a + BuildHasher + Clone> Map<'a, K, V, S>
1226
1210
hasher. finish ( )
1227
1211
} ,
1228
1212
) {
1229
- Ok ( elem ) => Some ( Entry :: Occupied ( unsafe {
1230
- OccupiedEntry :: new ( guard, key, shard , elem )
1213
+ hash_table :: Entry :: Occupied ( entry ) => Some ( Entry :: Occupied ( unsafe {
1214
+ OccupiedEntry :: new ( guard, key, entry )
1231
1215
} ) ) ,
1232
- Err ( slot ) => Some ( Entry :: Vacant ( unsafe {
1233
- VacantEntry :: new ( guard, key, hash , shard , slot )
1216
+ hash_table :: Entry :: Vacant ( entry ) => Some ( Entry :: Vacant ( unsafe {
1217
+ VacantEntry :: new ( guard, key, entry )
1234
1218
} ) ) ,
1235
1219
}
1236
1220
}
@@ -1363,15 +1347,12 @@ where
1363
1347
. iter ( )
1364
1348
. map ( |shard_lock| {
1365
1349
let shard = shard_lock. read ( ) ;
1366
- let hashtable_size = shard. allocation_info ( ) . 1 . size ( ) ;
1350
+ let hashtable_size = shard. allocation_size ( ) ;
1367
1351
1368
1352
// Safety: The iterator is dropped before the HashTable
1369
- let iter = unsafe { shard. iter ( ) } ;
1370
- let entry_size_iter = iter. map ( |bucket| {
1371
- // Safety: The iterator returns buckets with valid pointers to entries
1372
- let ( key, value) = unsafe { bucket. as_ref ( ) } ;
1373
- key. extra_size ( ) + value. extra_size ( )
1374
- } ) ;
1353
+ let iter = shard. iter ( ) ;
1354
+ let entry_size_iter =
1355
+ iter. map ( |( key, value) | key. extra_size ( ) + value. extra_size ( ) ) ;
1375
1356
1376
1357
core:: mem:: size_of :: < CachePadded < RwLock < HashMap < K , V > > > > ( )
1377
1358
+ hashtable_size
0 commit comments