@@ -472,7 +472,7 @@ fn pop_internal<K, V>(starting_bucket: FullBucketMut<K, V>)
472472 }
473473
474474 // Now we've done all our shifting. Return the value we grabbed earlier.
475- ( retkey, retval, gap. into_bucket ( ) . into_table ( ) )
475+ ( retkey, retval, gap. into_table ( ) )
476476}
477477
478478/// Perform robin hood bucket stealing at the given `bucket`. You must
@@ -485,14 +485,14 @@ fn robin_hood<'a, K: 'a, V: 'a>(bucket: FullBucketMut<'a, K, V>,
485485 mut key : K ,
486486 mut val : V )
487487 -> FullBucketMut < ' a , K , V > {
488- let start_index = bucket. index ( ) ;
489488 let size = bucket. table ( ) . size ( ) ;
490- // Save the *starting point*.
491- let mut bucket = bucket. stash ( ) ;
489+ let raw_capacity = bucket. table ( ) . capacity ( ) ;
492490 // There can be at most `size - dib` buckets to displace, because
493491 // in the worst case, there are `size` elements and we already are
494492 // `displacement` buckets away from the initial one.
495- let idx_end = start_index + size - bucket. displacement ( ) ;
493+ let idx_end = ( bucket. index ( ) + size - bucket. displacement ( ) ) % raw_capacity;
494+ // Save the *starting point*.
495+ let mut bucket = bucket. stash ( ) ;
496496
497497 loop {
498498 let ( old_hash, old_key, old_val) = bucket. replace ( hash, key, val) ;
@@ -568,11 +568,8 @@ impl<K, V, S> HashMap<K, V, S>
568568 // The caller should ensure that invariants by Robin Hood Hashing hold
569569 // and that there's space in the underlying table.
570570 fn insert_hashed_ordered ( & mut self , hash : SafeHash , k : K , v : V ) {
571- let raw_cap = self . raw_capacity ( ) ;
572571 let mut buckets = Bucket :: new ( & mut self . table , hash) ;
573- // note that buckets.index() keeps increasing
574- // even if the pointer wraps back to the first bucket.
575- let limit_bucket = buckets. index ( ) + raw_cap;
572+ let start_index = buckets. index ( ) ;
576573
577574 loop {
578575 // We don't need to compare hashes for value swap.
@@ -585,7 +582,7 @@ impl<K, V, S> HashMap<K, V, S>
585582 Full ( b) => b. into_bucket ( ) ,
586583 } ;
587584 buckets. next ( ) ;
588- debug_assert ! ( buckets. index( ) < limit_bucket ) ;
585+ debug_assert ! ( buckets. index( ) != start_index ) ;
589586 }
590587 }
591588}
@@ -1244,24 +1241,25 @@ impl<K, V, S> HashMap<K, V, S>
12441241 pub fn retain < F > ( & mut self , mut f : F )
12451242 where F : FnMut ( & K , & mut V ) -> bool
12461243 {
1247- if self . table . capacity ( ) == 0 || self . table . size ( ) == 0 {
1244+ if self . table . size ( ) == 0 {
12481245 return ;
12491246 }
1247+ let mut elems_left = self . table . size ( ) ;
12501248 let mut bucket = Bucket :: head_bucket ( & mut self . table ) ;
12511249 bucket. prev ( ) ;
1252- let tail = bucket. index ( ) ;
1253- loop {
1250+ let start_index = bucket. index ( ) ;
1251+ while elems_left != 0 {
12541252 bucket = match bucket. peek ( ) {
12551253 Full ( mut full) => {
1254+ elems_left -= 1 ;
12561255 let should_remove = {
12571256 let ( k, v) = full. read_mut ( ) ;
12581257 !f ( k, v)
12591258 } ;
12601259 if should_remove {
1261- let prev_idx = full. index ( ) ;
12621260 let prev_raw = full. raw ( ) ;
12631261 let ( _, _, t) = pop_internal ( full) ;
1264- Bucket :: new_from ( prev_raw, prev_idx , t)
1262+ Bucket :: new_from ( prev_raw, t)
12651263 } else {
12661264 full. into_bucket ( )
12671265 }
@@ -1271,9 +1269,7 @@ impl<K, V, S> HashMap<K, V, S>
12711269 }
12721270 } ;
12731271 bucket. prev ( ) ; // reverse iteration
1274- if bucket. index ( ) == tail {
1275- break ;
1276- }
1272+ debug_assert ! ( elems_left == 0 || bucket. index( ) != start_index) ;
12771273 }
12781274 }
12791275}
0 commit comments