@@ -24,8 +24,8 @@ use std::mem;
24
24
use std:: ops:: Index ;
25
25
26
26
use allocative:: Allocative ;
27
- use hashbrown:: raw :: Bucket ;
28
- use hashbrown:: raw :: RawTable ;
27
+ use hashbrown:: hash_table ;
28
+ use hashbrown:: HashTable ;
29
29
30
30
use crate :: Equivalent ;
31
31
use crate :: Hashed ;
@@ -35,7 +35,7 @@ use crate::StarlarkHasher;
35
35
/// Hash map which does not expose any insertion order-specific behavior
36
36
/// (except `Debug`).
37
37
#[ derive( Clone , Allocative ) ]
38
- pub struct UnorderedMap < K , V > ( RawTable < ( K , V ) > ) ;
38
+ pub struct UnorderedMap < K , V > ( HashTable < ( K , V ) > ) ;
39
39
40
40
impl < K , V > Default for UnorderedMap < K , V > {
41
41
#[ inline]
@@ -48,13 +48,13 @@ impl<K, V> UnorderedMap<K, V> {
48
48
/// Create a new empty map.
49
49
#[ inline]
50
50
pub const fn new ( ) -> UnorderedMap < K , V > {
51
- UnorderedMap ( RawTable :: new ( ) )
51
+ UnorderedMap ( HashTable :: new ( ) )
52
52
}
53
53
54
54
/// Create a new empty map with the specified capacity.
55
55
#[ inline]
56
56
pub fn with_capacity ( n : usize ) -> UnorderedMap < K , V > {
57
- UnorderedMap ( RawTable :: with_capacity ( n) )
57
+ UnorderedMap ( HashTable :: with_capacity ( n) )
58
58
}
59
59
60
60
/// Get the number of elements in the map.
@@ -87,7 +87,7 @@ impl<K, V> UnorderedMap<K, V> {
87
87
{
88
88
let hash = key. hash ( ) . promote ( ) ;
89
89
self . 0
90
- . get ( hash, |( next_k, _v) | key. key ( ) . equivalent ( next_k) )
90
+ . find ( hash, |( next_k, _v) | key. key ( ) . equivalent ( next_k) )
91
91
. map ( |( _, v) | v)
92
92
}
93
93
@@ -99,7 +99,7 @@ impl<K, V> UnorderedMap<K, V> {
99
99
{
100
100
let hash = StarlarkHashValue :: new ( k) . promote ( ) ;
101
101
self . 0
102
- . get_mut ( hash, |( next_k, _v) | k. equivalent ( next_k) )
102
+ . find_mut ( hash, |( next_k, _v) | k. equivalent ( next_k) )
103
103
. map ( |( _, v) | v)
104
104
}
105
105
@@ -157,19 +157,7 @@ impl<K, V> UnorderedMap<K, V> {
157
157
where
158
158
F : FnMut ( & K , & mut V ) -> bool ,
159
159
{
160
- // TODO(nga): update hashbrown and use safe `HashTable` instead of this heavily unsafe code:
161
- // https://docs.rs/hashbrown/latest/hashbrown/struct.HashTable.html
162
-
163
- // Unsafe code is copy-paste from `hashbrown` crate:
164
- // https://github.com/rust-lang/hashbrown/blob/f2e62124cd947b5e2309dd6a24c7e422932aae97/src/map.rs#L923
165
- unsafe {
166
- for item in self . 0 . iter ( ) {
167
- let ( k, v) = item. as_mut ( ) ;
168
- if !f ( k, v) {
169
- self . 0 . erase ( item) ;
170
- }
171
- }
172
- }
160
+ self . 0 . retain ( move |( k, v) | f ( k, v) ) ;
173
161
}
174
162
175
163
/// Get an entry in the map for in-place manipulation.
@@ -179,14 +167,13 @@ impl<K, V> UnorderedMap<K, V> {
179
167
K : Hash + Eq ,
180
168
{
181
169
let hash = StarlarkHashValue :: new ( & k) . promote ( ) ;
182
- if let Some ( bucket) = self . 0 . find ( hash, |( next_k, _v) | k. equivalent ( next_k) ) {
183
- Entry :: Occupied ( OccupiedEntry { _map : self , bucket } )
184
- } else {
185
- Entry :: Vacant ( VacantEntry {
186
- map : self ,
187
- key : k,
188
- hash,
189
- } )
170
+ match self . 0 . entry (
171
+ hash,
172
+ |( next_k, _v) | k. equivalent ( next_k) ,
173
+ |( k, _v) | StarlarkHashValue :: new ( k) . promote ( ) ,
174
+ ) {
175
+ hash_table:: Entry :: Occupied ( entry) => Entry :: Occupied ( OccupiedEntry { entry } ) ,
176
+ hash_table:: Entry :: Vacant ( entry) => Entry :: Vacant ( VacantEntry { entry, key : k } ) ,
190
177
}
191
178
}
192
179
@@ -205,13 +192,13 @@ impl<K, V> UnorderedMap<K, V> {
205
192
/// Entries in the map, in arbitrary order.
206
193
#[ inline]
207
194
pub fn entries_unordered ( & self ) -> impl ExactSizeIterator < Item = ( & K , & V ) > {
208
- unsafe { self . 0 . iter ( ) . map ( |e| ( & e. as_ref ( ) . 0 , & e. as_ref ( ) . 1 ) ) }
195
+ self . 0 . iter ( ) . map ( |e| ( & e. 0 , & e. 1 ) )
209
196
}
210
197
211
198
/// Entries in the map, in arbitrary order.
212
199
#[ inline]
213
200
pub fn entries_unordered_mut ( & mut self ) -> impl ExactSizeIterator < Item = ( & K , & mut V ) > {
214
- unsafe { self . 0 . iter ( ) . map ( |e| ( & e. as_ref ( ) . 0 , & mut e. as_mut ( ) . 1 ) ) }
201
+ self . 0 . iter_mut ( ) . map ( |e| ( & e. 0 , & mut e. 1 ) )
215
202
}
216
203
217
204
/// Keys in the map, in arbitrary order.
@@ -322,14 +309,12 @@ impl<K: Eq + Hash, V> FromIterator<(K, V)> for UnorderedMap<K, V> {
322
309
323
310
/// Reference to an occupied entry in a [`UnorderedMap`].
324
311
pub struct OccupiedEntry < ' a , K , V > {
325
- _map : & ' a mut UnorderedMap < K , V > ,
326
- bucket : Bucket < ( K , V ) > ,
312
+ entry : hash_table:: OccupiedEntry < ' a , ( K , V ) > ,
327
313
}
328
314
329
315
/// Reference to a vacant entry in a [`UnorderedMap`].
330
316
pub struct VacantEntry < ' a , K , V > {
331
- map : & ' a mut UnorderedMap < K , V > ,
332
- hash : u64 ,
317
+ entry : hash_table:: VacantEntry < ' a , ( K , V ) > ,
333
318
key : K ,
334
319
}
335
320
@@ -345,23 +330,21 @@ impl<'a, K: Eq + Hash, V> VacantEntry<'a, K, V> {
345
330
/// Insert a value into the map.
346
331
#[ inline]
347
332
pub fn insert ( self , value : V ) {
348
- self . map . 0 . insert ( self . hash , ( self . key , value) , |( k, _v) | {
349
- StarlarkHashValue :: new ( k) . promote ( )
350
- } ) ;
333
+ self . entry . insert ( ( self . key , value) ) ;
351
334
}
352
335
}
353
336
354
337
impl < ' a , K , V > OccupiedEntry < ' a , K , V > {
355
338
/// Remove the entry from the map.
356
339
#[ inline]
357
340
pub fn get ( & self ) -> & V {
358
- unsafe { & self . bucket . as_ref ( ) . 1 }
341
+ & self . entry . get ( ) . 1
359
342
}
360
343
361
344
/// Get a reference to the value associated with the entry.
362
345
#[ inline]
363
346
pub fn get_mut ( & mut self ) -> & mut V {
364
- unsafe { & mut self . bucket . as_mut ( ) . 1 }
347
+ & mut self . entry . get_mut ( ) . 1
365
348
}
366
349
367
350
/// Replace the value associated with the entry.
@@ -403,26 +386,23 @@ impl<'a, K, V> RawEntryBuilderMut<'a, K, V> {
403
386
F : for < ' b > FnMut ( & ' b K ) -> bool ,
404
387
{
405
388
let hash = hash. promote ( ) ;
406
- if let Some ( bucket) = self . map . 0 . find ( hash, |( next_k, _v) | is_match ( next_k) ) {
407
- RawEntryMut :: Occupied ( RawOccupiedEntryMut {
408
- map : self . map ,
409
- bucket,
410
- } )
411
- } else {
412
- RawEntryMut :: Vacant ( RawVacantEntryMut { map : self . map } )
389
+ match self . map . 0 . find_entry ( hash, |( next_k, _v) | is_match ( next_k) ) {
390
+ Ok ( entry) => RawEntryMut :: Occupied ( RawOccupiedEntryMut { entry } ) ,
391
+ Err ( entry) => RawEntryMut :: Vacant ( RawVacantEntryMut {
392
+ table : entry. into_table ( ) ,
393
+ } ) ,
413
394
}
414
395
}
415
396
}
416
397
417
398
/// Occupied entry.
418
399
pub struct RawOccupiedEntryMut < ' a , K , V > {
419
- map : & ' a mut UnorderedMap < K , V > ,
420
- bucket : Bucket < ( K , V ) > ,
400
+ entry : hash_table:: OccupiedEntry < ' a , ( K , V ) > ,
421
401
}
422
402
423
403
/// Vacant entry.
424
404
pub struct RawVacantEntryMut < ' a , K , V > {
425
- map : & ' a mut UnorderedMap < K , V > ,
405
+ table : & ' a mut HashTable < ( K , V ) > ,
426
406
}
427
407
428
408
/// Raw entry.
@@ -449,19 +429,19 @@ impl<'a, K, V> RawOccupiedEntryMut<'a, K, V> {
449
429
/// Get a reference to the value associated with the entry.
450
430
#[ inline]
451
431
pub fn get ( & self ) -> & V {
452
- unsafe { & self . bucket . as_ref ( ) . 1 }
432
+ & self . entry . get ( ) . 1
453
433
}
454
434
455
435
/// Get a reference to the value associated with the entry.
456
436
#[ inline]
457
437
pub fn get_mut ( & mut self ) -> & mut V {
458
- unsafe { & mut self . bucket . as_mut ( ) . 1 }
438
+ & mut self . entry . get_mut ( ) . 1
459
439
}
460
440
461
441
/// Get a reference to the key associated with the entry.
462
442
#[ inline]
463
443
pub fn key_mut ( & mut self ) -> & mut K {
464
- unsafe { & mut self . bucket . as_mut ( ) . 0 }
444
+ & mut self . entry . get_mut ( ) . 0
465
445
}
466
446
467
447
/// Remove the entry, return the value.
@@ -473,7 +453,7 @@ impl<'a, K, V> RawOccupiedEntryMut<'a, K, V> {
473
453
/// Remove the entry, return the key and value.
474
454
#[ inline]
475
455
pub fn remove_entry ( self ) -> ( K , V ) {
476
- unsafe { self . map . 0 . remove ( self . bucket ) . 0 }
456
+ self . entry . remove ( ) . 0
477
457
}
478
458
}
479
459
@@ -496,12 +476,12 @@ impl<'a, K, V> RawVacantEntryMut<'a, K, V> {
496
476
where
497
477
K : Hash ,
498
478
{
499
- let ( k, v) =
500
- self . map
501
- . 0
502
- . insert_entry ( key . hash ( ) . promote ( ) , ( key . into_key ( ) , value ) , | ( k , _v ) | {
503
- StarlarkHashValue :: new ( k ) . promote ( )
504
- } ) ;
479
+ let ( k, v) = self
480
+ . table
481
+ . insert_unique ( key . hash ( ) . promote ( ) , ( key . into_key ( ) , value ) , | ( k , _v ) | {
482
+ StarlarkHashValue :: new ( k ) . promote ( )
483
+ } )
484
+ . into_mut ( ) ;
505
485
( k, v)
506
486
}
507
487
}
0 commit comments