@@ -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.
@@ -336,7 +337,7 @@ impl<'a, K: 'a + Eq + Hash, V: 'a, S: BuildHasher + Clone> DashMap<K, V, S> {
336
337
/// };
337
338
/// let data = (42, "forty two");
338
339
/// let hash = hasher(&data);
339
- /// map.shards_mut()[shard_ind].get_mut().insert (hash, data, hasher);
340
+ /// map.shards_mut()[shard_ind].get_mut().insert_unique (hash, data, hasher);
340
341
/// assert_eq!(*map.get(&42).unwrap(), "forty two");
341
342
/// ```
342
343
pub fn shards_mut( & mut self ) -> & mut [ CachePadded <RwLock <HashMap <K , V >>>] {
@@ -955,8 +956,8 @@ impl<'a, K: 'a + Eq + Hash, V: 'a, S: 'a + BuildHasher + Clone> Map<'a, K, V, S>
955
956
956
957
let mut shard = unsafe { self . _yield_write_shard ( idx) } ;
957
958
958
- if let Some ( bucket ) = shard. find ( hash, |( k, _v) | key == k. borrow ( ) ) {
959
- let ( ( k, v) , _) = unsafe { shard . remove ( bucket ) } ;
959
+ if let Ok ( entry ) = shard. find_entry ( hash, |( k, _v) | key == k. borrow ( ) ) {
960
+ let ( ( k, v) , _) = entry . remove ( ) ;
960
961
Some ( ( k, v) )
961
962
} else {
962
963
None
@@ -974,10 +975,10 @@ impl<'a, K: 'a + Eq + Hash, V: 'a, S: 'a + BuildHasher + Clone> Map<'a, K, V, S>
974
975
975
976
let mut shard = unsafe { self . _yield_write_shard ( idx) } ;
976
977
977
- if let Some ( bucket ) = shard. find ( hash, |( k, _v) | key == k. borrow ( ) ) {
978
- let ( k, v) = unsafe { bucket . as_ref ( ) } ;
978
+ if let Ok ( entry ) = shard. find_entry ( hash, |( k, _v) | key == k. borrow ( ) ) {
979
+ let ( k, v) = entry . get ( ) ;
979
980
if f ( k, v) {
980
- let ( ( k, v) , _) = unsafe { shard . remove ( bucket ) } ;
981
+ let ( ( k, v) , _) = entry . remove ( ) ;
981
982
Some ( ( k, v) )
982
983
} else {
983
984
None
@@ -998,10 +999,10 @@ impl<'a, K: 'a + Eq + Hash, V: 'a, S: 'a + BuildHasher + Clone> Map<'a, K, V, S>
998
999
999
1000
let mut shard = unsafe { self . _yield_write_shard ( idx) } ;
1000
1001
1001
- if let Some ( bucket ) = shard. find ( hash, |( k, _v) | key == k. borrow ( ) ) {
1002
- let ( k, v) = unsafe { bucket . as_mut ( ) } ;
1002
+ if let Ok ( mut entry ) = shard. find_entry ( hash, |( k, _v) | key == k. borrow ( ) ) {
1003
+ let ( k, v) = entry . get_mut ( ) ;
1003
1004
if f ( k, v) {
1004
- let ( ( k, v) , _) = unsafe { shard . remove ( bucket ) } ;
1005
+ let ( ( k, v) , _) = entry . remove ( ) ;
1005
1006
Some ( ( k, v) )
1006
1007
} else {
1007
1008
None
@@ -1032,11 +1033,8 @@ impl<'a, K: 'a + Eq + Hash, V: 'a, S: 'a + BuildHasher + Clone> Map<'a, K, V, S>
1032
1033
// SAFETY: The data will not outlive the guard, since we pass the guard to `Ref`.
1033
1034
let ( guard, shard) = unsafe { RwLockReadGuardDetached :: detach_from ( shard) } ;
1034
1035
1035
- if let Some ( bucket) = shard. find ( hash, |( k, _v) | key == k. borrow ( ) ) {
1036
- unsafe {
1037
- let ( k, v) = bucket. as_ref ( ) ;
1038
- Some ( Ref :: new ( guard, k, v) )
1039
- }
1036
+ if let Some ( ( k, v) ) = shard. find ( hash, |( k, _v) | key == k. borrow ( ) ) {
1037
+ unsafe { Some ( Ref :: new ( guard, k, v) ) }
1040
1038
} else {
1041
1039
None
1042
1040
}
@@ -1055,11 +1053,8 @@ impl<'a, K: 'a + Eq + Hash, V: 'a, S: 'a + BuildHasher + Clone> Map<'a, K, V, S>
1055
1053
// SAFETY: The data will not outlive the guard, since we pass the guard to `RefMut`.
1056
1054
let ( guard, shard) = unsafe { RwLockWriteGuardDetached :: detach_from ( shard) } ;
1057
1055
1058
- if let Some ( bucket) = shard. find ( hash, |( k, _v) | key == k. borrow ( ) ) {
1059
- unsafe {
1060
- let ( k, v) = bucket. as_mut ( ) ;
1061
- Some ( RefMut :: new ( guard, k, v) )
1062
- }
1056
+ if let Some ( ( k, v) ) = shard. find_mut ( hash, |( k, _v) | key == k. borrow ( ) ) {
1057
+ unsafe { Some ( RefMut :: new ( guard, k, v) ) }
1063
1058
} else {
1064
1059
None
1065
1060
}
@@ -1081,11 +1076,8 @@ impl<'a, K: 'a + Eq + Hash, V: 'a, S: 'a + BuildHasher + Clone> Map<'a, K, V, S>
1081
1076
// SAFETY: The data will not outlive the guard, since we pass the guard to `Ref`.
1082
1077
let ( guard, shard) = unsafe { RwLockReadGuardDetached :: detach_from ( shard) } ;
1083
1078
1084
- if let Some ( bucket) = shard. find ( hash, |( k, _v) | key == k. borrow ( ) ) {
1085
- unsafe {
1086
- let ( k, v) = bucket. as_ref ( ) ;
1087
- TryResult :: Present ( Ref :: new ( guard, k, v) )
1088
- }
1079
+ if let Some ( ( k, v) ) = shard. find ( hash, |( k, _v) | key == k. borrow ( ) ) {
1080
+ unsafe { TryResult :: Present ( Ref :: new ( guard, k, v) ) }
1089
1081
} else {
1090
1082
TryResult :: Absent
1091
1083
}
@@ -1107,11 +1099,8 @@ impl<'a, K: 'a + Eq + Hash, V: 'a, S: 'a + BuildHasher + Clone> Map<'a, K, V, S>
1107
1099
// SAFETY: The data will not outlive the guard, since we pass the guard to `RefMut`.
1108
1100
let ( guard, shard) = unsafe { RwLockWriteGuardDetached :: detach_from ( shard) } ;
1109
1101
1110
- if let Some ( bucket) = shard. find ( hash, |( k, _v) | key == k. borrow ( ) ) {
1111
- unsafe {
1112
- let ( k, v) = bucket. as_mut ( ) ;
1113
- TryResult :: Present ( RefMut :: new ( guard, k, v) )
1114
- }
1102
+ if let Some ( ( k, v) ) = shard. find_mut ( hash, |( k, _v) | key == k. borrow ( ) ) {
1103
+ unsafe { TryResult :: Present ( RefMut :: new ( guard, k, v) ) }
1115
1104
} else {
1116
1105
TryResult :: Absent
1117
1106
}
@@ -1131,16 +1120,7 @@ impl<'a, K: 'a + Eq + Hash, V: 'a, S: 'a + BuildHasher + Clone> Map<'a, K, V, S>
1131
1120
1132
1121
fn _retain ( & self , mut f : impl FnMut ( & K , & mut V ) -> bool ) {
1133
1122
self . shards . iter ( ) . for_each ( |s| {
1134
- unsafe {
1135
- let mut shard = s. write ( ) ;
1136
- // Here we only use `iter` as a temporary, preventing use-after-free
1137
- for bucket in shard. iter ( ) {
1138
- let ( k, v) = bucket. as_mut ( ) ;
1139
- if !f ( & * k, v) {
1140
- shard. erase ( bucket) ;
1141
- }
1142
- }
1143
- }
1123
+ s. write ( ) . retain ( |( k, v) | f ( k, v) ) ;
1144
1124
} ) ;
1145
1125
}
1146
1126
@@ -1187,7 +1167,7 @@ impl<'a, K: 'a + Eq + Hash, V: 'a, S: 'a + BuildHasher + Clone> Map<'a, K, V, S>
1187
1167
// SAFETY: The data will not outlive the guard, since we pass the guard to `Entry`.
1188
1168
let ( guard, shard) = unsafe { RwLockWriteGuardDetached :: detach_from ( shard) } ;
1189
1169
1190
- match shard. find_or_find_insert_slot (
1170
+ match shard. entry (
1191
1171
hash,
1192
1172
|( k, _v) | k == & key,
1193
1173
|( k, _v) | {
@@ -1196,8 +1176,12 @@ impl<'a, K: 'a + Eq + Hash, V: 'a, S: 'a + BuildHasher + Clone> Map<'a, K, V, S>
1196
1176
hasher. finish ( )
1197
1177
} ,
1198
1178
) {
1199
- Ok ( elem) => Entry :: Occupied ( unsafe { OccupiedEntry :: new ( guard, key, shard, elem) } ) ,
1200
- Err ( slot) => Entry :: Vacant ( unsafe { VacantEntry :: new ( guard, key, hash, shard, slot) } ) ,
1179
+ hash_table:: Entry :: Occupied ( entry) => {
1180
+ Entry :: Occupied ( unsafe { OccupiedEntry :: new ( guard, key, entry) } )
1181
+ }
1182
+ hash_table:: Entry :: Vacant ( entry) => {
1183
+ Entry :: Vacant ( unsafe { VacantEntry :: new ( guard, key, entry) } )
1184
+ }
1201
1185
}
1202
1186
}
1203
1187
@@ -1213,7 +1197,7 @@ impl<'a, K: 'a + Eq + Hash, V: 'a, S: 'a + BuildHasher + Clone> Map<'a, K, V, S>
1213
1197
// SAFETY: The data will not outlive the guard, since we pass the guard to `Entry`.
1214
1198
let ( guard, shard) = unsafe { RwLockWriteGuardDetached :: detach_from ( shard) } ;
1215
1199
1216
- match shard. find_or_find_insert_slot (
1200
+ match shard. entry (
1217
1201
hash,
1218
1202
|( k, _v) | k == & key,
1219
1203
|( k, _v) | {
@@ -1222,11 +1206,11 @@ impl<'a, K: 'a + Eq + Hash, V: 'a, S: 'a + BuildHasher + Clone> Map<'a, K, V, S>
1222
1206
hasher. finish ( )
1223
1207
} ,
1224
1208
) {
1225
- Ok ( elem ) => Some ( Entry :: Occupied ( unsafe {
1226
- OccupiedEntry :: new ( guard, key, shard , elem )
1209
+ hash_table :: Entry :: Occupied ( entry ) => Some ( Entry :: Occupied ( unsafe {
1210
+ OccupiedEntry :: new ( guard, key, entry )
1227
1211
} ) ) ,
1228
- Err ( slot ) => Some ( Entry :: Vacant ( unsafe {
1229
- VacantEntry :: new ( guard, key, hash , shard , slot )
1212
+ hash_table :: Entry :: Vacant ( entry ) => Some ( Entry :: Vacant ( unsafe {
1213
+ VacantEntry :: new ( guard, key, entry )
1230
1214
} ) ) ,
1231
1215
}
1232
1216
}
@@ -1359,15 +1343,12 @@ where
1359
1343
. iter ( )
1360
1344
. map ( |shard_lock| {
1361
1345
let shard = shard_lock. read ( ) ;
1362
- let hashtable_size = shard. allocation_info ( ) . 1 . size ( ) ;
1346
+ let hashtable_size = shard. allocation_size ( ) ;
1363
1347
1364
1348
// Safety: The iterator is dropped before the HashTable
1365
- let iter = unsafe { shard. iter ( ) } ;
1366
- let entry_size_iter = iter. map ( |bucket| {
1367
- // Safety: The iterator returns buckets with valid pointers to entries
1368
- let ( key, value) = unsafe { bucket. as_ref ( ) } ;
1369
- key. extra_size ( ) + value. extra_size ( )
1370
- } ) ;
1349
+ let iter = shard. iter ( ) ;
1350
+ let entry_size_iter =
1351
+ iter. map ( |( key, value) | key. extra_size ( ) + value. extra_size ( ) ) ;
1371
1352
1372
1353
core:: mem:: size_of :: < CachePadded < RwLock < HashMap < K , V > > > > ( )
1373
1354
+ hashtable_size
0 commit comments