@@ -1780,18 +1780,12 @@ where
17801780 where
17811781 F : FnMut ( & K , & mut V ) -> bool ,
17821782 {
1783- while let Some ( kv) = unsafe { self . next_kv ( ) } {
1784- let ( k, v) = unsafe { ptr :: read ( & kv ) } . into_kv_mut ( ) ;
1783+ while let Some ( mut kv) = unsafe { self . next_kv ( ) } {
1784+ let ( k, v) = kv . kv_mut ( ) ;
17851785 if pred ( k, v) {
17861786 * self . length -= 1 ;
17871787 let ( k, v, leaf_edge_location) = kv. remove_kv_tracking ( ) ;
1788- // `remove_kv_tracking` has either preserved or invalidated `self.cur_leaf_edge`
1789- if let Some ( node) = leaf_edge_location {
1790- match search:: search_tree ( node, & k) {
1791- search:: SearchResult :: Found ( _) => unreachable ! ( ) ,
1792- search:: SearchResult :: GoDown ( leaf) => self . cur_leaf_edge = Some ( leaf) ,
1793- }
1794- } ;
1788+ self . cur_leaf_edge = Some ( leaf_edge_location) ;
17951789 return Some ( ( k, v) ) ;
17961790 }
17971791 self . cur_leaf_edge = Some ( kv. next_leaf_edge ( ) ) ;
@@ -2698,79 +2692,99 @@ impl<'a, K: Ord, V> OccupiedEntry<'a, K, V> {
26982692
26992693impl < ' a , K : ' a , V : ' a > Handle < NodeRef < marker:: Mut < ' a > , K , V , marker:: LeafOrInternal > , marker:: KV > {
27002694 /// Removes a key/value-pair from the map, and returns that pair, as well as
2701- /// the whereabouts of the leaf edge corresponding to that former pair:
2702- /// if None is returned, the leaf edge is still the left leaf edge of the KV handle;
2703- /// if a node is returned, it heads the subtree where the leaf edge may be found.
2695+ /// the leaf edge corresponding to that former pair.
27042696 fn remove_kv_tracking (
27052697 self ,
2706- ) -> ( K , V , Option < NodeRef < marker:: Mut < ' a > , K , V , marker:: LeafOrInternal > > ) {
2707- let mut levels_down_handled: isize ;
2708- let ( small_leaf, old_key, old_val) = match self . force ( ) {
2698+ ) -> ( K , V , Handle < NodeRef < marker:: Mut < ' a > , K , V , marker:: Leaf > , marker:: Edge > ) {
2699+ let ( mut pos, old_key, old_val, was_internal) = match self . force ( ) {
27092700 Leaf ( leaf) => {
2710- levels_down_handled = 1 ; // handled at same level, but affects only the right side
27112701 let ( hole, old_key, old_val) = leaf. remove ( ) ;
2712- ( hole. into_node ( ) , old_key, old_val)
2702+ ( hole, old_key, old_val, false )
27132703 }
27142704 Internal ( mut internal) => {
27152705 // Replace the location freed in the internal node with the next KV,
27162706 // and remove that next KV from its leaf.
2717- levels_down_handled = unsafe { ptr:: read ( & internal) . into_node ( ) . height ( ) } as isize ;
27182707
27192708 let key_loc = internal. kv_mut ( ) . 0 as * mut K ;
27202709 let val_loc = internal. kv_mut ( ) . 1 as * mut V ;
27212710
2722- let to_remove = internal. right_edge ( ) . descend ( ) . first_leaf_edge ( ) . right_kv ( ) . ok ( ) ;
2711+ // Deleting from the left side is typically faster since we can
2712+ // just pop an element from the end of the KV array without
2713+ // needing to shift the other values.
2714+ let to_remove = internal. left_edge ( ) . descend ( ) . last_leaf_edge ( ) . left_kv ( ) . ok ( ) ;
27232715 let to_remove = unsafe { unwrap_unchecked ( to_remove) } ;
27242716
27252717 let ( hole, key, val) = to_remove. remove ( ) ;
27262718
27272719 let old_key = unsafe { mem:: replace ( & mut * key_loc, key) } ;
27282720 let old_val = unsafe { mem:: replace ( & mut * val_loc, val) } ;
27292721
2730- ( hole. into_node ( ) , old_key, old_val)
2722+ ( hole, old_key, old_val, true )
27312723 }
27322724 } ;
27332725
27342726 // Handle underflow
2735- let mut cur_node = small_leaf. forget_type ( ) ;
2727+ let mut cur_node = unsafe { ptr:: read ( & pos) . into_node ( ) . forget_type ( ) } ;
2728+ let mut at_leaf = true ;
27362729 while cur_node. len ( ) < node:: MIN_LEN {
27372730 match handle_underfull_node ( cur_node) {
2738- AtRoot ( root) => {
2739- cur_node = root;
2740- break ;
2741- }
2731+ AtRoot ( _) => break ,
27422732 EmptyParent ( _) => unreachable ! ( ) ,
2743- Merged ( parent) => {
2744- levels_down_handled -= 1 ;
2733+ Merged ( edge, merged_with_left, offset) => {
2734+ // If we merged with our right sibling then our tracked
2735+ // position has not changed. However if we merged with our
2736+ // left sibling then our tracked position is now dangling.
2737+ if at_leaf && merged_with_left {
2738+ let idx = pos. idx ( ) + offset;
2739+ let node = match unsafe { ptr:: read ( & edge) . descend ( ) . force ( ) } {
2740+ Leaf ( leaf) => leaf,
2741+ Internal ( _) => unreachable ! ( ) ,
2742+ } ;
2743+ debug_assert ! ( idx <= node. len( ) ) ;
2744+ pos = unsafe { Handle :: new_edge ( node, idx) } ;
2745+ }
2746+
2747+ let parent = edge. into_node ( ) ;
27452748 if parent. len ( ) == 0 {
27462749 // We must be at the root
2747- let root = parent. into_root_mut ( ) ;
2748- root. pop_level ( ) ;
2749- cur_node = root. as_mut ( ) ;
2750+ parent. into_root_mut ( ) . pop_level ( ) ;
27502751 break ;
27512752 } else {
27522753 cur_node = parent. forget_type ( ) ;
2754+ at_leaf = false ;
27532755 }
27542756 }
2755- Stole ( internal_node) => {
2756- levels_down_handled -= 1 ;
2757- cur_node = internal_node. forget_type ( ) ;
2757+ Stole ( _, stole_from_left) => {
2758+ // Adjust the tracked position if we stole from a left sibling
2759+ if stole_from_left && at_leaf {
2760+ // SAFETY: This is safe since we just added an element to our node.
2761+ unsafe {
2762+ pos. next_unchecked ( ) ;
2763+ }
2764+ }
2765+
27582766 // This internal node might be underfull, but only if it's the root.
27592767 break ;
27602768 }
27612769 }
27622770 }
27632771
2764- let leaf_edge_location = if levels_down_handled > 0 { None } else { Some ( cur_node) } ;
2765- ( old_key, old_val, leaf_edge_location)
2772+ // If we deleted from an internal node then we need to compensate for
2773+ // the earlier swap and adjust the tracked position to point to the
2774+ // next element.
2775+ if was_internal {
2776+ pos = unsafe { unwrap_unchecked ( pos. next_kv ( ) . ok ( ) ) . next_leaf_edge ( ) } ;
2777+ }
2778+
2779+ ( old_key, old_val, pos)
27662780 }
27672781}
27682782
27692783enum UnderflowResult < ' a , K , V > {
27702784 AtRoot ( NodeRef < marker:: Mut < ' a > , K , V , marker:: LeafOrInternal > ) ,
27712785 EmptyParent ( NodeRef < marker:: Mut < ' a > , K , V , marker:: Internal > ) ,
2772- Merged ( NodeRef < marker:: Mut < ' a > , K , V , marker:: Internal > ) ,
2773- Stole ( NodeRef < marker:: Mut < ' a > , K , V , marker:: Internal > ) ,
2786+ Merged ( Handle < NodeRef < marker:: Mut < ' a > , K , V , marker:: Internal > , marker :: Edge > , bool , usize ) ,
2787+ Stole ( NodeRef < marker:: Mut < ' a > , K , V , marker:: Internal > , bool ) ,
27742788}
27752789
27762790fn handle_underfull_node < K , V > (
@@ -2792,14 +2806,15 @@ fn handle_underfull_node<K, V>(
27922806 } ;
27932807
27942808 if handle. can_merge ( ) {
2795- Merged ( handle. merge ( ) . into_node ( ) )
2809+ let offset = if is_left { handle. reborrow ( ) . left_edge ( ) . descend ( ) . len ( ) + 1 } else { 0 } ;
2810+ Merged ( handle. merge ( ) , is_left, offset)
27962811 } else {
27972812 if is_left {
27982813 handle. steal_left ( ) ;
27992814 } else {
28002815 handle. steal_right ( ) ;
28012816 }
2802- Stole ( handle. into_node ( ) )
2817+ Stole ( handle. into_node ( ) , is_left )
28032818 }
28042819}
28052820
0 commit comments