@@ -21,9 +21,9 @@ use fmt::{self, Debug};
2121use hash:: { Hash , SipHasher } ;
2222use iter:: { Iterator , ExactSizeIterator , IntoIterator , IteratorExt , FromIterator , Extend , Map } ;
2323use marker:: Sized ;
24- use mem:: { self , replace} ;
24+ use mem:: { self , swap , replace} ;
2525use num:: { Int , UnsignedInt } ;
26- use ops:: { Deref , DerefMut , Drop , FnMut , Index , IndexMut } ;
26+ use ops:: { Drop , FnMut , Index , IndexMut } ;
2727use option:: Option :: { self , Some , None } ;
2828use rand:: { self , Rng } ;
2929use result:: Result :: { self , Ok , Err } ;
@@ -33,11 +33,9 @@ use super::table::{
3333 Bucket ,
3434 EmptyBucket ,
3535 FullBucket ,
36- FullBucketImm ,
3736 FullBucketMut ,
3837 RawTable ,
3938 SafeHash ,
40- TableRef ,
4139 PartialRawTable ,
4240 Put ,
4341} ;
@@ -322,13 +320,12 @@ fn search_hashed<K, V, M, F>(table: M,
322320 hash : SafeHash ,
323321 mut is_match : F )
324322 -> InternalEntry < K , V , M > where
325- RawTable < K , V > : BorrowFrom < M > ,
323+ M : Borrow < RawTable < K , V > > ,
326324 F : FnMut ( & K ) -> bool ,
327325{
328326 // 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) {
332329 Some ( probe) => probe,
333330 None => return InternalEntry :: TableIsEmpty ,
334331 } ;
@@ -392,8 +389,8 @@ fn pop_internal<K, V>(starting_bucket: FullBucketMut<K, V>) -> (K, V) {
392389fn robin_hood < ' a , K : ' a , V : ' a > ( bucket : FullBucketMut < ' a , K , V > ,
393390 mut ib : usize ,
394391 mut hash : SafeHash ,
395- mut k : K ,
396- mut v : V )
392+ mut key : K ,
393+ mut val : V )
397394 -> & ' a mut V {
398395 let starting_index = bucket. index ( ) ;
399396 let size = {
@@ -407,9 +404,11 @@ fn robin_hood<'a, K: 'a, V: 'a>(bucket: FullBucketMut<'a, K, V>,
407404 let idx_end = starting_index + size - bucket. displacement ( ) ;
408405
409406 loop {
410- let ( old_hash , old_key , old_val ) = {
407+ {
411408 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) ;
413412 } ;
414413 loop {
415414 let probe = bucket. into_next ( ) ;
@@ -418,7 +417,7 @@ fn robin_hood<'a, K: 'a, V: 'a>(bucket: FullBucketMut<'a, K, V>,
418417 let full_bucket = match probe. peek ( ) {
419418 Empty ( bucket) => {
420419 // Found a hole!
421- let b = bucket. put ( old_hash , old_key , old_val ) ;
420+ let b = bucket. put ( hash , key , val ) ;
422421 // Now that it's stolen, just read the value's pointer
423422 // right out of the table!
424423 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>,
433432 // Robin hood! Steal the spot.
434433 if ib < probe_ib {
435434 ib = probe_ib;
436- hash = old_hash;
437- k = old_key;
438- v = old_val;
439435 break ;
440436 }
441437 }
@@ -444,20 +440,19 @@ fn robin_hood<'a, K: 'a, V: 'a>(bucket: FullBucketMut<'a, K, V>,
444440
445441// Performs insertion with relaxed requirements.
446442// 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 > >
449445{
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 ( ) ;
453448 let ib = buckets. index ( ) ;
454449
455450 while buckets. index ( ) != ib + cap {
456451 // We don't need to compare hashes for value swap.
457452 // Not even DIBs for Robin Hood.
458453 buckets = match buckets. peek ( ) {
459454 Empty ( empty) => {
460- return empty. put ( h , k , v ) . into_table ( ) ;
455+ return empty. put ( hash , key , val ) . into_table ( ) ;
461456 }
462457 Full ( full) => full. into_bucket ( )
463458 } ;
@@ -477,24 +472,20 @@ impl<K, V, S> HashMap<K, V, S>
477472 /// Search for a key, yielding the index if it's found in the hashtable.
478473 /// If you already have the hash for the key lying around, use
479474 /// 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 > >
481477 where K : Borrow < Q > , Q : Eq + Hash
482478 {
483479 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 ( ) ) )
488481 }
489482
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 > >
491485 where K : Borrow < Q > , Q : Eq + Hash
492486 {
493487 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 ( ) ) )
498489 }
499490}
500491
@@ -653,7 +644,7 @@ impl<K, V, S> HashMap<K, V, S>
653644 // Grow the table.
654645 let is_inplace = self . table . grow_inplace ( new_capacity) ;
655646
656- let mut destination = if is_inplace {
647+ let destination = if is_inplace {
657648 // Resizing in-place.
658649 None
659650 } else {
@@ -933,14 +924,13 @@ impl<K, V, S> HashMap<K, V, S>
933924 pub fn entry ( & mut self , key : K ) -> Entry < K , V > {
934925 // Gotta resize now.
935926 self . reserve ( 1 ) ;
936-
937927 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 ( ) ) ) {
939929 InternalEntry :: Occupied ( state) => Occupied ( state) ,
940930 InternalEntry :: Vacant ( bucket) => Vacant ( VacantEntry {
941- elem : bucket,
942- hash : hash,
943931 key : key,
932+ hash : hash,
933+ elem : bucket,
944934 } ) ,
945935 InternalEntry :: TableIsEmpty => unreachable ! ( )
946936 }
@@ -1044,7 +1034,7 @@ impl<K, V, S> HashMap<K, V, S>
10441034 pub fn get < Q : ?Sized > ( & self , k : & Q ) -> Option < & V >
10451035 where K : Borrow < Q > , Q : Hash + Eq
10461036 {
1047- self . search ( k) . map ( |bucket| bucket. into_refs ( ) . 1 )
1037+ self . search ( k) . into_option ( ) . map ( |bucket| bucket. into_refs ( ) . 1 )
10481038 }
10491039
10501040 /// Returns true if the map contains a value for the specified key.
@@ -1067,7 +1057,7 @@ impl<K, V, S> HashMap<K, V, S>
10671057 pub fn contains_key < Q : ?Sized > ( & self , k : & Q ) -> bool
10681058 where K : Borrow < Q > , Q : Hash + Eq
10691059 {
1070- self . search ( k) . is_some ( )
1060+ self . search ( k) . into_option ( ) . is_some ( )
10711061 }
10721062
10731063 /// Returns a mutable reference to the value corresponding to the key.
@@ -1093,7 +1083,7 @@ impl<K, V, S> HashMap<K, V, S>
10931083 pub fn get_mut < Q : ?Sized > ( & mut self , k : & Q ) -> Option < & mut V >
10941084 where K : Borrow < Q > , Q : Hash + Eq
10951085 {
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 )
10971087 }
10981088
10991089 /// 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>
11131103 /// assert_eq!(map[37], "c");
11141104 /// ```
11151105 #[ 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 > {
11181107 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)
11201110 }
11211111
11221112 /// 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>
11441134 return None
11451135 }
11461136
1147- self . search_mut ( k) . map ( |bucket| pop_internal ( bucket) . 1 )
1137+ self . search_mut ( k) . into_option ( ) . map ( |bucket| pop_internal ( bucket) . 1 )
11481138 }
11491139}
11501140
@@ -1397,6 +1387,15 @@ enum InternalEntry<K, V, M> {
13971387 TableIsEmpty ,
13981388}
13991389
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+
14001399#[ stable( feature = "rust1" , since = "1.0.0" ) ]
14011400impl < ' a , K , V > Iterator for Iter < ' a , K , V > {
14021401 type Item = ( & ' a K , & ' a V ) ;
@@ -1547,7 +1546,7 @@ impl<'a, K, V> OccupiedEntry<'a, K, V> {
15471546
15481547#[ unstable( feature = "std_misc" ,
15491548 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 > > {
15511550 /// Gets a mutable reference to the value in the entry.
15521551 #[ stable( feature = "rust1" , since = "1.0.0" ) ]
15531552 pub fn get_mut ( & mut self ) -> & mut V {
0 commit comments