@@ -21,7 +21,7 @@ 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 } ;
2626use ops:: { Deref , DerefMut , Drop , FnMut , Index , IndexMut } ;
2727use option:: Option :: { self , Some , None } ;
@@ -392,8 +392,8 @@ fn pop_internal<K, V>(starting_bucket: FullBucketMut<K, V>) -> (K, V) {
392392fn robin_hood < ' a , K : ' a , V : ' a > ( bucket : FullBucketMut < ' a , K , V > ,
393393 mut ib : usize ,
394394 mut hash : SafeHash ,
395- mut k : K ,
396- mut v : V )
395+ mut key : K ,
396+ mut val : V )
397397 -> & ' a mut V {
398398 let starting_index = bucket. index ( ) ;
399399 let size = {
@@ -407,9 +407,11 @@ fn robin_hood<'a, K: 'a, V: 'a>(bucket: FullBucketMut<'a, K, V>,
407407 let idx_end = starting_index + size - bucket. displacement ( ) ;
408408
409409 loop {
410- let ( old_hash , old_key , old_val ) = {
410+ {
411411 let ( h_ref, k_ref, v_ref) = bucket. read_mut ( ) ;
412- ( replace ( h_ref, hash) , replace ( k_ref, k) , replace ( v_ref, v) )
412+ swap ( h_ref, & mut hash) ;
413+ swap ( k_ref, & mut key) ;
414+ swap ( v_ref, & mut val) ) ;
413415 } ;
414416 loop {
415417 let probe = bucket. into_next ( ) ;
@@ -418,7 +420,7 @@ fn robin_hood<'a, K: 'a, V: 'a>(bucket: FullBucketMut<'a, K, V>,
418420 let full_bucket = match probe. peek ( ) {
419421 Empty ( bucket) => {
420422 // Found a hole!
421- let b = bucket. put ( old_hash , old_key , old_val ) ;
423+ let b = bucket. put ( hash , key , val ) ;
422424 // Now that it's stolen, just read the value's pointer
423425 // right out of the table!
424426 return b. into_table ( ) . into_mut_refs ( ) . 1 ;
@@ -433,9 +435,6 @@ fn robin_hood<'a, K: 'a, V: 'a>(bucket: FullBucketMut<'a, K, V>,
433435 // Robin hood! Steal the spot.
434436 if ib < probe_ib {
435437 ib = probe_ib;
436- hash = old_hash;
437- k = old_key;
438- v = old_val;
439438 break ;
440439 }
441440 }
@@ -477,24 +476,20 @@ impl<K, V, S> HashMap<K, V, S>
477476 /// Search for a key, yielding the index if it's found in the hashtable.
478477 /// If you already have the hash for the key lying around, use
479478 /// search_hashed.
480- fn search < ' a , Q : ?Sized > ( & ' a self , q : & Q ) -> Option < FullBucketImm < ' a , K , V > >
479+ fn search < ' a , Q : ?Sized > ( & ' a self , q : & Q )
480+ -> Option < InternalEntry < K , V , & ' a RawTable < K , V > > >
481481 where K : Borrow < Q > , Q : Eq + Hash
482482 {
483483 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- }
484+ search_hashed ( & self . table , hash, |k| q. eq ( k. borrow ( ) ) )
488485 }
489486
490- fn search_mut < ' a , Q : ?Sized > ( & ' a mut self , q : & Q ) -> Option < FullBucketMut < ' a , K , V > >
487+ fn search_mut < ' a , Q : ?Sized > ( & ' a mut self , q : & Q )
488+ -> Option < InternalEntry < K , V , & ' a mut RawTable < K , V > > >
491489 where K : Borrow < Q > , Q : Eq + Hash
492490 {
493491 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- }
492+ search_hashed ( & mut self . table , hash, |k| q. eq ( k. borrow ( ) ) )
498493 }
499494}
500495
@@ -772,7 +767,15 @@ impl<K, V, S> HashMap<K, V, S>
772767
773768 // Shrink the table. Naive algorithm for resizing:
774769 while let Some ( ( h, k, v) ) = old_table. take_front ( ) {
775- self . insert_hashed_nocheck ( h, k, v) ;
770+ match search_hashed ( & mut self . table , hash, |key| * key == k) {
771+ InternalEntry :: Vacant ( entry) => {
772+ entry. insert ( hash, k, v) ;
773+ }
774+ InternalEntry :: Occupied ( mut entry) => {
775+ entry. insert ( v) ;
776+ }
777+ InternalEntry :: TableIsEmpty => unreachable ! ( )
778+ }
776779 }
777780
778781 debug_assert_eq ! ( self . table. size( ) , old_size) ;
@@ -934,8 +937,7 @@ impl<K, V, S> HashMap<K, V, S>
934937 // Gotta resize now.
935938 self . reserve ( 1 ) ;
936939
937- let hash = self . make_hash ( & key) ;
938- match search_hashed ( & mut self . table , hash, |k| * k == key) {
940+ match self . search_mut ( & key) {
939941 InternalEntry :: Occupied ( state) => Occupied ( state) ,
940942 InternalEntry :: Vacant ( bucket) => Vacant ( VacantEntry {
941943 elem : bucket,
@@ -1044,7 +1046,7 @@ impl<K, V, S> HashMap<K, V, S>
10441046 pub fn get < Q : ?Sized > ( & self , k : & Q ) -> Option < & V >
10451047 where K : Borrow < Q > , Q : Hash + Eq
10461048 {
1047- self . search ( k) . map ( |bucket| bucket. into_refs ( ) . 1 )
1049+ self . search ( k) . into_option ( ) . map ( |bucket| bucket. into_refs ( ) . 1 )
10481050 }
10491051
10501052 /// Returns true if the map contains a value for the specified key.
@@ -1067,7 +1069,7 @@ impl<K, V, S> HashMap<K, V, S>
10671069 pub fn contains_key < Q : ?Sized > ( & self , k : & Q ) -> bool
10681070 where K : Borrow < Q > , Q : Hash + Eq
10691071 {
1070- self . search ( k) . is_some ( )
1072+ self . search ( k) . into_option ( ) . is_some ( )
10711073 }
10721074
10731075 /// Returns a mutable reference to the value corresponding to the key.
@@ -1093,7 +1095,7 @@ impl<K, V, S> HashMap<K, V, S>
10931095 pub fn get_mut < Q : ?Sized > ( & mut self , k : & Q ) -> Option < & mut V >
10941096 where K : Borrow < Q > , Q : Hash + Eq
10951097 {
1096- self . search_mut ( k) . map ( |bucket| bucket. into_mut_refs ( ) . 1 )
1098+ self . search_mut ( k) . into_option ( ) . map ( |bucket| bucket. into_mut_refs ( ) . 1 )
10971099 }
10981100
10991101 /// Inserts a key-value pair from the map. If the key already had a value
@@ -1113,10 +1115,19 @@ impl<K, V, S> HashMap<K, V, S>
11131115 /// assert_eq!(map[37], "c");
11141116 /// ```
11151117 #[ 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) ;
1118+ pub fn insert ( & mut self , key : K , value : V ) -> Option < V > {
11181119 self . reserve ( 1 ) ;
1119- self . insert_hashed_nocheck ( hash, k, v)
1120+
1121+ match self . search_mut ( & key) {
1122+ InternalEntry :: Vacant ( entry) => {
1123+ entry. insert ( hash, key, value) ;
1124+ return None ;
1125+ }
1126+ InternalEntry :: Occupied ( mut entry) => {
1127+ return Some ( entry. insert ( value) ) ;
1128+ }
1129+ InternalEntry :: TableIsEmpty => unreachable ! ( )
1130+ }
11201131 }
11211132
11221133 /// Removes a key from the map, returning the value at the key if the key
@@ -1144,7 +1155,7 @@ impl<K, V, S> HashMap<K, V, S>
11441155 return None
11451156 }
11461157
1147- self . search_mut ( k) . map ( |bucket| pop_internal ( bucket) . 1 )
1158+ self . search_mut ( k) . into_option ( ) . map ( |bucket| pop_internal ( bucket) . 1 )
11481159 }
11491160}
11501161
@@ -1397,6 +1408,15 @@ enum InternalEntry<K, V, M> {
13971408 TableIsEmpty ,
13981409}
13991410
1411+ impl < K , V , M > InternalEntry < K , V , M > {
1412+ fn into_option ( self ) -> Option < FullBucket < K , V , M > > {
1413+ match self {
1414+ InternalEntry :: Occupied ( bucket) => Some ( bucket. elem ) ,
1415+ _ => None ,
1416+ }
1417+ }
1418+ }
1419+
14001420#[ stable( feature = "rust1" , since = "1.0.0" ) ]
14011421impl < ' a , K , V > Iterator for Iter < ' a , K , V > {
14021422 type Item = ( & ' a K , & ' a V ) ;
0 commit comments