@@ -8,6 +8,7 @@ use core::mem::{self, ManuallyDrop};
88use core:: ops:: { Index , RangeBounds } ;
99use core:: ptr;
1010
11+ use super :: borrow:: DormantMutRef ;
1112use super :: node:: { self , marker, ForceResult :: * , Handle , InsertResult :: * , NodeRef } ;
1213use super :: search:: { self , SearchResult :: * } ;
1314use super :: unwrap_unchecked;
@@ -228,24 +229,23 @@ where
228229 }
229230
230231 fn take ( & mut self , key : & Q ) -> Option < K > {
231- let root_node = self . root . as_mut ( ) ?. node_as_mut ( ) ;
232+ let ( map, dormant_map) = DormantMutRef :: new ( self ) ;
233+ let root_node = map. root . as_mut ( ) ?. node_as_mut ( ) ;
232234 match search:: search_tree ( root_node, key) {
233- Found ( handle) => Some (
234- OccupiedEntry { handle, length : & mut self . length , _marker : PhantomData }
235- . remove_kv ( )
236- . 0 ,
237- ) ,
235+ Found ( handle) => {
236+ Some ( OccupiedEntry { handle, dormant_map, _marker : PhantomData } . remove_kv ( ) . 0 )
237+ }
238238 GoDown ( _) => None ,
239239 }
240240 }
241241
242242 fn replace ( & mut self , key : K ) -> Option < K > {
243- let root = Self :: ensure_is_owned ( & mut self . root ) ;
244- match search:: search_tree :: < marker:: Mut < ' _ > , K , ( ) , K > ( root. node_as_mut ( ) , & key) {
243+ let ( map, dormant_map) = DormantMutRef :: new ( self ) ;
244+ let root_node = Self :: ensure_is_owned ( & mut map. root ) . node_as_mut ( ) ;
245+ match search:: search_tree :: < marker:: Mut < ' _ > , K , ( ) , K > ( root_node, & key) {
245246 Found ( handle) => Some ( mem:: replace ( handle. into_key_mut ( ) , key) ) ,
246247 GoDown ( handle) => {
247- VacantEntry { key, handle, length : & mut self . length , _marker : PhantomData }
248- . insert ( ( ) ) ;
248+ VacantEntry { key, handle, dormant_map, _marker : PhantomData } . insert ( ( ) ) ;
249249 None
250250 }
251251 }
@@ -459,7 +459,7 @@ impl<K: Debug + Ord, V: Debug> Debug for Entry<'_, K, V> {
459459pub struct VacantEntry < ' a , K : ' a , V : ' a > {
460460 key : K ,
461461 handle : Handle < NodeRef < marker:: Mut < ' a > , K , V , marker:: Leaf > , marker:: Edge > ,
462- length : & ' a mut usize ,
462+ dormant_map : DormantMutRef < ' a , BTreeMap < K , V > > ,
463463
464464 // Be invariant in `K` and `V`
465465 _marker : PhantomData < & ' a mut ( K , V ) > ,
@@ -479,8 +479,7 @@ impl<K: Debug + Ord, V> Debug for VacantEntry<'_, K, V> {
479479#[ stable( feature = "rust1" , since = "1.0.0" ) ]
480480pub struct OccupiedEntry < ' a , K : ' a , V : ' a > {
481481 handle : Handle < NodeRef < marker:: Mut < ' a > , K , V , marker:: LeafOrInternal > , marker:: KV > ,
482-
483- length : & ' a mut usize ,
482+ dormant_map : DormantMutRef < ' a , BTreeMap < K , V > > ,
484483
485484 // Be invariant in `K` and `V`
486485 _marker : PhantomData < & ' a mut ( K , V ) > ,
@@ -644,13 +643,10 @@ impl<K: Ord, V> BTreeMap<K, V> {
644643 /// ```
645644 #[ unstable( feature = "map_first_last" , issue = "62924" ) ]
646645 pub fn first_entry ( & mut self ) -> Option < OccupiedEntry < ' _ , K , V > > {
647- let root_node = self . root . as_mut ( ) ?. node_as_mut ( ) ;
646+ let ( map, dormant_map) = DormantMutRef :: new ( self ) ;
647+ let root_node = map. root . as_mut ( ) ?. node_as_mut ( ) ;
648648 let kv = root_node. first_leaf_edge ( ) . right_kv ( ) . ok ( ) ?;
649- Some ( OccupiedEntry {
650- handle : kv. forget_node_type ( ) ,
651- length : & mut self . length ,
652- _marker : PhantomData ,
653- } )
649+ Some ( OccupiedEntry { handle : kv. forget_node_type ( ) , dormant_map, _marker : PhantomData } )
654650 }
655651
656652 /// Removes and returns the first element in the map.
@@ -721,13 +717,10 @@ impl<K: Ord, V> BTreeMap<K, V> {
721717 /// ```
722718 #[ unstable( feature = "map_first_last" , issue = "62924" ) ]
723719 pub fn last_entry ( & mut self ) -> Option < OccupiedEntry < ' _ , K , V > > {
724- let root_node = self . root . as_mut ( ) ?. node_as_mut ( ) ;
720+ let ( map, dormant_map) = DormantMutRef :: new ( self ) ;
721+ let root_node = map. root . as_mut ( ) ?. node_as_mut ( ) ;
725722 let kv = root_node. last_leaf_edge ( ) . left_kv ( ) . ok ( ) ?;
726- Some ( OccupiedEntry {
727- handle : kv. forget_node_type ( ) ,
728- length : & mut self . length ,
729- _marker : PhantomData ,
730- } )
723+ Some ( OccupiedEntry { handle : kv. forget_node_type ( ) , dormant_map, _marker : PhantomData } )
731724 }
732725
733726 /// Removes and returns the last element in the map.
@@ -901,12 +894,12 @@ impl<K: Ord, V> BTreeMap<K, V> {
901894 K : Borrow < Q > ,
902895 Q : Ord ,
903896 {
904- let root_node = self . root . as_mut ( ) ?. node_as_mut ( ) ;
897+ let ( map, dormant_map) = DormantMutRef :: new ( self ) ;
898+ let root_node = map. root . as_mut ( ) ?. node_as_mut ( ) ;
905899 match search:: search_tree ( root_node, key) {
906- Found ( handle) => Some (
907- OccupiedEntry { handle, length : & mut self . length , _marker : PhantomData }
908- . remove_entry ( ) ,
909- ) ,
900+ Found ( handle) => {
901+ Some ( OccupiedEntry { handle, dormant_map, _marker : PhantomData } . remove_entry ( ) )
902+ }
910903 GoDown ( _) => None ,
911904 }
912905 }
@@ -1073,13 +1066,12 @@ impl<K: Ord, V> BTreeMap<K, V> {
10731066 #[ stable( feature = "rust1" , since = "1.0.0" ) ]
10741067 pub fn entry ( & mut self , key : K ) -> Entry < ' _ , K , V > {
10751068 // FIXME(@porglezomp) Avoid allocating if we don't insert
1076- let root = Self :: ensure_is_owned ( & mut self . root ) ;
1077- match search:: search_tree ( root. node_as_mut ( ) , & key) {
1078- Found ( handle) => {
1079- Occupied ( OccupiedEntry { handle, length : & mut self . length , _marker : PhantomData } )
1080- }
1069+ let ( map, dormant_map) = DormantMutRef :: new ( self ) ;
1070+ let root_node = Self :: ensure_is_owned ( & mut map. root ) . node_as_mut ( ) ;
1071+ match search:: search_tree ( root_node, & key) {
1072+ Found ( handle) => Occupied ( OccupiedEntry { handle, dormant_map, _marker : PhantomData } ) ,
10811073 GoDown ( handle) => {
1082- Vacant ( VacantEntry { key, handle, length : & mut self . length , _marker : PhantomData } )
1074+ Vacant ( VacantEntry { key, handle, dormant_map , _marker : PhantomData } )
10831075 }
10841076 }
10851077 }
@@ -1284,9 +1276,17 @@ impl<K: Ord, V> BTreeMap<K, V> {
12841276 }
12851277
12861278 pub ( super ) fn drain_filter_inner ( & mut self ) -> DrainFilterInner < ' _ , K , V > {
1287- let root_node = self . root . as_mut ( ) . map ( |r| r. node_as_mut ( ) ) ;
1288- let front = root_node. map ( |rn| rn. first_leaf_edge ( ) ) ;
1289- DrainFilterInner { length : & mut self . length , cur_leaf_edge : front }
1279+ if let Some ( root) = self . root . as_mut ( ) {
1280+ let ( root, dormant_root) = DormantMutRef :: new ( root) ;
1281+ let front = root. node_as_mut ( ) . first_leaf_edge ( ) ;
1282+ DrainFilterInner {
1283+ length : & mut self . length ,
1284+ dormant_root : Some ( dormant_root) ,
1285+ cur_leaf_edge : Some ( front) ,
1286+ }
1287+ } else {
1288+ DrainFilterInner { length : & mut self . length , dormant_root : None , cur_leaf_edge : None }
1289+ }
12901290 }
12911291
12921292 /// Creates a consuming iterator visiting all the keys, in sorted order.
@@ -1671,6 +1671,9 @@ where
16711671/// of the predicate, thus also serving for BTreeSet::DrainFilter.
16721672pub ( super ) struct DrainFilterInner < ' a , K : ' a , V : ' a > {
16731673 length : & ' a mut usize ,
1674+ // dormant_root is wrapped in an Option to be able to `take` it.
1675+ dormant_root : Option < DormantMutRef < ' a , node:: Root < K , V > > > ,
1676+ // cur_leaf_edge is wrapped in an Option because maps without root lack a leaf edge.
16741677 cur_leaf_edge : Option < Handle < NodeRef < marker:: Mut < ' a > , K , V , marker:: Leaf > , marker:: Edge > > ,
16751678}
16761679
@@ -1728,7 +1731,13 @@ impl<'a, K: 'a, V: 'a> DrainFilterInner<'a, K, V> {
17281731 let ( k, v) = kv. kv_mut ( ) ;
17291732 if pred ( k, v) {
17301733 * self . length -= 1 ;
1731- let ( kv, pos) = kv. remove_kv_tracking ( ) ;
1734+ let ( kv, pos) = kv. remove_kv_tracking ( || {
1735+ // SAFETY: we will touch the root in a way that will not
1736+ // invalidate the position returned.
1737+ let root = unsafe { self . dormant_root . take ( ) . unwrap ( ) . awaken ( ) } ;
1738+ root. pop_internal_level ( ) ;
1739+ self . dormant_root = Some ( DormantMutRef :: new ( root) . 1 ) ;
1740+ } ) ;
17321741 self . cur_leaf_edge = Some ( pos) ;
17331742 return Some ( kv) ;
17341743 }
@@ -2456,13 +2465,20 @@ impl<'a, K: Ord, V> VacantEntry<'a, K, V> {
24562465 /// ```
24572466 #[ stable( feature = "rust1" , since = "1.0.0" ) ]
24582467 pub fn insert ( self , value : V ) -> & ' a mut V {
2459- * self . length += 1 ;
2460-
24612468 let out_ptr = match self . handle . insert_recursing ( self . key , value) {
2462- ( Fit ( _) , val_ptr) => val_ptr,
2469+ ( Fit ( _) , val_ptr) => {
2470+ // Safety: We have consumed self.handle and the handle returned.
2471+ let map = unsafe { self . dormant_map . awaken ( ) } ;
2472+ map. length += 1 ;
2473+ val_ptr
2474+ }
24632475 ( Split ( ins) , val_ptr) => {
2464- let root = ins. left . into_root_mut ( ) ;
2476+ drop ( ins. left ) ;
2477+ // Safety: We have consumed self.handle and the reference returned.
2478+ let map = unsafe { self . dormant_map . awaken ( ) } ;
2479+ let root = map. root . as_mut ( ) . unwrap ( ) ;
24652480 root. push_internal_level ( ) . push ( ins. k , ins. v , ins. right ) ;
2481+ map. length += 1 ;
24662482 val_ptr
24672483 }
24682484 } ;
@@ -2636,18 +2652,25 @@ impl<'a, K: Ord, V> OccupiedEntry<'a, K, V> {
26362652
26372653 // Body of `remove_entry`, separate to keep the above implementations short.
26382654 fn remove_kv ( self ) -> ( K , V ) {
2639- * self . length -= 1 ;
2640-
2641- let ( old_kv, _) = self . handle . remove_kv_tracking ( ) ;
2655+ let mut emptied_internal_root = false ;
2656+ let ( old_kv, _) = self . handle . remove_kv_tracking ( || emptied_internal_root = true ) ;
2657+ // SAFETY: we consumed the intermediate root borrow, `self.handle`.
2658+ let map = unsafe { self . dormant_map . awaken ( ) } ;
2659+ map. length -= 1 ;
2660+ if emptied_internal_root {
2661+ let root = map. root . as_mut ( ) . unwrap ( ) ;
2662+ root. pop_internal_level ( ) ;
2663+ }
26422664 old_kv
26432665 }
26442666}
26452667
26462668impl < ' a , K : ' a , V : ' a > Handle < NodeRef < marker:: Mut < ' a > , K , V , marker:: LeafOrInternal > , marker:: KV > {
26472669 /// Removes a key/value-pair from the map, and returns that pair, as well as
26482670 /// the leaf edge corresponding to that former pair.
2649- fn remove_kv_tracking (
2671+ fn remove_kv_tracking < F : FnOnce ( ) > (
26502672 self ,
2673+ handle_emptied_internal_root : F ,
26512674 ) -> ( ( K , V ) , Handle < NodeRef < marker:: Mut < ' a > , K , V , marker:: Leaf > , marker:: Edge > ) {
26522675 let ( old_kv, mut pos, was_internal) = match self . force ( ) {
26532676 Leaf ( leaf) => {
@@ -2700,7 +2723,7 @@ impl<'a, K: 'a, V: 'a> Handle<NodeRef<marker::Mut<'a>, K, V, marker::LeafOrInter
27002723 // The parent that was just emptied must be the root,
27012724 // because nodes on a lower level would not have been
27022725 // left with a single child.
2703- parent . into_root_mut ( ) . pop_internal_level ( ) ;
2726+ handle_emptied_internal_root ( ) ;
27042727 break ;
27052728 } else {
27062729 cur_node = parent. forget_type ( ) ;
0 commit comments