@@ -21,9 +21,9 @@ use fmt::{self, Debug};
21
21
use hash:: { Hash , SipHasher } ;
22
22
use iter:: { Iterator , ExactSizeIterator , IntoIterator , IteratorExt , FromIterator , Extend , Map } ;
23
23
use marker:: Sized ;
24
- use mem:: { self , replace} ;
24
+ use mem:: { self , swap , replace} ;
25
25
use num:: { Int , UnsignedInt } ;
26
- use ops:: { Deref , DerefMut , Drop , FnMut , Index , IndexMut } ;
26
+ use ops:: { Drop , FnMut , Index , IndexMut } ;
27
27
use option:: Option :: { self , Some , None } ;
28
28
use rand:: { self , Rng } ;
29
29
use result:: Result :: { self , Ok , Err } ;
@@ -33,11 +33,9 @@ use super::table::{
33
33
Bucket ,
34
34
EmptyBucket ,
35
35
FullBucket ,
36
- FullBucketImm ,
37
36
FullBucketMut ,
38
37
RawTable ,
39
38
SafeHash ,
40
- TableRef ,
41
39
PartialRawTable ,
42
40
Put ,
43
41
} ;
@@ -322,13 +320,12 @@ fn search_hashed<K, V, M, F>(table: M,
322
320
hash : SafeHash ,
323
321
mut is_match : F )
324
322
-> InternalEntry < K , V , M > where
325
- RawTable < K , V > : BorrowFrom < M > ,
323
+ M : Borrow < RawTable < K , V > > ,
326
324
F : FnMut ( & K ) -> bool ,
327
325
{
328
326
// Worst case, we'll find one empty bucket among `size + 1` buckets.
329
- let table = TableRef ( table) ;
330
- let size = table. size ( ) ;
331
- let mut probe = match Bucket :: new ( table. 0 , hash) {
327
+ let size = table. borrow ( ) . size ( ) ;
328
+ let mut probe = match Bucket :: new ( table, hash) {
332
329
Some ( probe) => probe,
333
330
None => return InternalEntry :: TableIsEmpty ,
334
331
} ;
@@ -392,8 +389,8 @@ fn pop_internal<K, V>(starting_bucket: FullBucketMut<K, V>) -> (K, V) {
392
389
fn robin_hood < ' a , K : ' a , V : ' a > ( bucket : FullBucketMut < ' a , K , V > ,
393
390
mut ib : usize ,
394
391
mut hash : SafeHash ,
395
- mut k : K ,
396
- mut v : V )
392
+ mut key : K ,
393
+ mut val : V )
397
394
-> & ' a mut V {
398
395
let starting_index = bucket. index ( ) ;
399
396
let size = {
@@ -407,9 +404,11 @@ fn robin_hood<'a, K: 'a, V: 'a>(bucket: FullBucketMut<'a, K, V>,
407
404
let idx_end = starting_index + size - bucket. displacement ( ) ;
408
405
409
406
loop {
410
- let ( old_hash , old_key , old_val ) = {
407
+ {
411
408
let ( h_ref, k_ref, v_ref) = bucket. read_mut ( ) ;
412
- ( replace ( h_ref, hash) , replace ( k_ref, k) , replace ( v_ref, v) )
409
+ swap ( h_ref, & mut hash) ;
410
+ swap ( k_ref, & mut key) ;
411
+ swap ( v_ref, & mut val) ;
413
412
} ;
414
413
loop {
415
414
let probe = bucket. into_next ( ) ;
@@ -418,7 +417,7 @@ fn robin_hood<'a, K: 'a, V: 'a>(bucket: FullBucketMut<'a, K, V>,
418
417
let full_bucket = match probe. peek ( ) {
419
418
Empty ( bucket) => {
420
419
// Found a hole!
421
- let b = bucket. put ( old_hash , old_key , old_val ) ;
420
+ let b = bucket. put ( hash , key , val ) ;
422
421
// Now that it's stolen, just read the value's pointer
423
422
// right out of the table!
424
423
return b. into_table ( ) . into_mut_refs ( ) . 1 ;
@@ -433,9 +432,6 @@ fn robin_hood<'a, K: 'a, V: 'a>(bucket: FullBucketMut<'a, K, V>,
433
432
// Robin hood! Steal the spot.
434
433
if ib < probe_ib {
435
434
ib = probe_ib;
436
- hash = old_hash;
437
- k = old_key;
438
- v = old_val;
439
435
break ;
440
436
}
441
437
}
@@ -444,20 +440,19 @@ fn robin_hood<'a, K: 'a, V: 'a>(bucket: FullBucketMut<'a, K, V>,
444
440
445
441
// Performs insertion with relaxed requirements.
446
442
// The caller should ensure that invariants of Robin Hood linear probing hold.
447
- fn insert_hashed_ordered < M : Put , K , V > ( arg : M , h : SafeHash , k : K , v : V ) -> M
448
- where RawTable < K , V > : BorrowFromMut < M >
443
+ fn insert_hashed_ordered < M : Put , K , V > ( table : M , hash : SafeHash , key : K , val : V ) -> M
444
+ where M : BorrowMut < RawTable < K , V > >
449
445
{
450
- let table = TableRef ( arg) ;
451
- let cap = table. capacity ( ) ;
452
- let mut buckets = Bucket :: new ( table. 0 , h) . unwrap ( ) ;
446
+ let cap = table. borrow ( ) . capacity ( ) ;
447
+ let mut buckets = Bucket :: new ( table, hash) . unwrap ( ) ;
453
448
let ib = buckets. index ( ) ;
454
449
455
450
while buckets. index ( ) != ib + cap {
456
451
// We don't need to compare hashes for value swap.
457
452
// Not even DIBs for Robin Hood.
458
453
buckets = match buckets. peek ( ) {
459
454
Empty ( empty) => {
460
- return empty. put ( h , k , v ) . into_table ( ) ;
455
+ return empty. put ( hash , key , val ) . into_table ( ) ;
461
456
}
462
457
Full ( full) => full. into_bucket ( )
463
458
} ;
@@ -477,24 +472,20 @@ impl<K, V, S> HashMap<K, V, S>
477
472
/// Search for a key, yielding the index if it's found in the hashtable.
478
473
/// If you already have the hash for the key lying around, use
479
474
/// search_hashed.
480
- fn search < ' a , Q : ?Sized > ( & ' a self , q : & Q ) -> Option < FullBucketImm < ' a , K , V > >
475
+ fn search < ' a , Q : ?Sized > ( & ' a self , q : & Q )
476
+ -> InternalEntry < K , V , & ' a RawTable < K , V > >
481
477
where K : Borrow < Q > , Q : Eq + Hash
482
478
{
483
479
let hash = self . make_hash ( q) ;
484
- match search_hashed ( & self . table , hash, |k| q. eq ( k. borrow ( ) ) ) {
485
- InternalEntry :: Occupied ( bucket) => Some ( bucket. elem ) ,
486
- _ => None ,
487
- }
480
+ search_hashed ( & self . table , hash, |k| q. eq ( k. borrow ( ) ) )
488
481
}
489
482
490
- fn search_mut < ' a , Q : ?Sized > ( & ' a mut self , q : & Q ) -> Option < FullBucketMut < ' a , K , V > >
483
+ fn search_mut < ' a , Q : ?Sized > ( & ' a mut self , q : & Q )
484
+ -> InternalEntry < K , V , & ' a mut RawTable < K , V > >
491
485
where K : Borrow < Q > , Q : Eq + Hash
492
486
{
493
487
let hash = self . make_hash ( q) ;
494
- match search_hashed ( & mut self . table , hash, |k| q. eq ( k. borrow ( ) ) ) {
495
- InternalEntry :: Occupied ( bucket) => Some ( bucket. elem ) ,
496
- _ => None ,
497
- }
488
+ search_hashed ( & mut self . table , hash, |k| q. eq ( k. borrow ( ) ) )
498
489
}
499
490
}
500
491
@@ -653,7 +644,7 @@ impl<K, V, S> HashMap<K, V, S>
653
644
// Grow the table.
654
645
let is_inplace = self . table . grow_inplace ( new_capacity) ;
655
646
656
- let mut destination = if is_inplace {
647
+ let destination = if is_inplace {
657
648
// Resizing in-place.
658
649
None
659
650
} else {
@@ -933,14 +924,13 @@ impl<K, V, S> HashMap<K, V, S>
933
924
pub fn entry ( & mut self , key : K ) -> Entry < K , V > {
934
925
// Gotta resize now.
935
926
self . reserve ( 1 ) ;
936
-
937
927
let hash = self . make_hash ( & key) ;
938
- match search_hashed ( & mut self . table , hash, |k| * k == key) {
928
+ match search_hashed ( & mut self . table , hash, |k| key. eq ( k . borrow ( ) ) ) {
939
929
InternalEntry :: Occupied ( state) => Occupied ( state) ,
940
930
InternalEntry :: Vacant ( bucket) => Vacant ( VacantEntry {
941
- elem : bucket,
942
- hash : hash,
943
931
key : key,
932
+ hash : hash,
933
+ elem : bucket,
944
934
} ) ,
945
935
InternalEntry :: TableIsEmpty => unreachable ! ( )
946
936
}
@@ -1044,7 +1034,7 @@ impl<K, V, S> HashMap<K, V, S>
1044
1034
pub fn get < Q : ?Sized > ( & self , k : & Q ) -> Option < & V >
1045
1035
where K : Borrow < Q > , Q : Hash + Eq
1046
1036
{
1047
- self . search ( k) . map ( |bucket| bucket. into_refs ( ) . 1 )
1037
+ self . search ( k) . into_option ( ) . map ( |bucket| bucket. into_refs ( ) . 1 )
1048
1038
}
1049
1039
1050
1040
/// Returns true if the map contains a value for the specified key.
@@ -1067,7 +1057,7 @@ impl<K, V, S> HashMap<K, V, S>
1067
1057
pub fn contains_key < Q : ?Sized > ( & self , k : & Q ) -> bool
1068
1058
where K : Borrow < Q > , Q : Hash + Eq
1069
1059
{
1070
- self . search ( k) . is_some ( )
1060
+ self . search ( k) . into_option ( ) . is_some ( )
1071
1061
}
1072
1062
1073
1063
/// Returns a mutable reference to the value corresponding to the key.
@@ -1093,7 +1083,7 @@ impl<K, V, S> HashMap<K, V, S>
1093
1083
pub fn get_mut < Q : ?Sized > ( & mut self , k : & Q ) -> Option < & mut V >
1094
1084
where K : Borrow < Q > , Q : Hash + Eq
1095
1085
{
1096
- self . search_mut ( k) . map ( |bucket| bucket. into_mut_refs ( ) . 1 )
1086
+ self . search_mut ( k) . into_option ( ) . map ( |bucket| bucket. into_mut_refs ( ) . 1 )
1097
1087
}
1098
1088
1099
1089
/// Inserts a key-value pair from the map. If the key already had a value
@@ -1113,10 +1103,10 @@ impl<K, V, S> HashMap<K, V, S>
1113
1103
/// assert_eq!(map[37], "c");
1114
1104
/// ```
1115
1105
#[ stable( feature = "rust1" , since = "1.0.0" ) ]
1116
- pub fn insert ( & mut self , k : K , v : V ) -> Option < V > {
1117
- let hash = self . make_hash ( & k) ;
1106
+ pub fn insert ( & mut self , key : K , value : V ) -> Option < V > {
1118
1107
self . reserve ( 1 ) ;
1119
- self . insert_hashed_nocheck ( hash, k, v)
1108
+ let hash = self . make_hash ( & key) ;
1109
+ self . insert_hashed_nocheck ( hash, key, value)
1120
1110
}
1121
1111
1122
1112
/// Removes a key from the map, returning the value at the key if the key
@@ -1144,7 +1134,7 @@ impl<K, V, S> HashMap<K, V, S>
1144
1134
return None
1145
1135
}
1146
1136
1147
- self . search_mut ( k) . map ( |bucket| pop_internal ( bucket) . 1 )
1137
+ self . search_mut ( k) . into_option ( ) . map ( |bucket| pop_internal ( bucket) . 1 )
1148
1138
}
1149
1139
}
1150
1140
@@ -1397,6 +1387,15 @@ enum InternalEntry<K, V, M> {
1397
1387
TableIsEmpty ,
1398
1388
}
1399
1389
1390
+ impl < K , V , M > InternalEntry < K , V , M > {
1391
+ fn into_option ( self ) -> Option < FullBucket < K , V , M > > {
1392
+ match self {
1393
+ InternalEntry :: Occupied ( bucket) => Some ( bucket. elem ) ,
1394
+ _ => None ,
1395
+ }
1396
+ }
1397
+ }
1398
+
1400
1399
#[ stable( feature = "rust1" , since = "1.0.0" ) ]
1401
1400
impl < ' a , K , V > Iterator for Iter < ' a , K , V > {
1402
1401
type Item = ( & ' a K , & ' a V ) ;
@@ -1547,7 +1546,7 @@ impl<'a, K, V> OccupiedEntry<'a, K, V> {
1547
1546
1548
1547
#[ unstable( feature = "std_misc" ,
1549
1548
reason = "matches collection reform v2 specification, waiting for dust to settle" ) ]
1550
- impl < ' a , K : ' a , V : ' a , M : ' a > OccupiedEntryState < K , V , M > where RawTable < K , V > : BorrowFromMut < M > {
1549
+ impl < ' a , K : ' a , V : ' a , M : ' a > OccupiedEntryState < K , V , M > where M : BorrowMut < RawTable < K , V > > {
1551
1550
/// Gets a mutable reference to the value in the entry.
1552
1551
#[ stable( feature = "rust1" , since = "1.0.0" ) ]
1553
1552
pub fn get_mut ( & mut self ) -> & mut V {
0 commit comments