@@ -9,6 +9,7 @@ use core::ops::Bound::{Excluded, Included, Unbounded};
99use core:: ops:: { Index , RangeBounds } ;
1010use core:: ptr;
1111
12+ use super :: borrow:: DormantMutRef ;
1213use super :: node:: { self , marker, ForceResult :: * , Handle , InsertResult :: * , NodeRef } ;
1314use super :: search:: { self , SearchResult :: * } ;
1415use super :: unwrap_unchecked;
@@ -229,24 +230,23 @@ where
229230 }
230231
231232 fn take ( & mut self , key : & Q ) -> Option < K > {
232- let root_node = self . root . as_mut ( ) ?. node_as_mut ( ) ;
233+ let ( map, dormant_map) = DormantMutRef :: new ( self ) ;
234+ let root_node = map. root . as_mut ( ) ?. node_as_mut ( ) ;
233235 match search:: search_tree ( root_node, key) {
234- Found ( handle) => Some (
235- OccupiedEntry { handle, length : & mut self . length , _marker : PhantomData }
236- . remove_kv ( )
237- . 0 ,
238- ) ,
236+ Found ( handle) => {
237+ Some ( OccupiedEntry { handle, dormant_map, _marker : PhantomData } . remove_kv ( ) . 0 )
238+ }
239239 GoDown ( _) => None ,
240240 }
241241 }
242242
243243 fn replace ( & mut self , key : K ) -> Option < K > {
244- let root = Self :: ensure_is_owned ( & mut self . root ) ;
245- match search:: search_tree :: < marker:: Mut < ' _ > , K , ( ) , K > ( root. node_as_mut ( ) , & key) {
244+ let ( map, dormant_map) = DormantMutRef :: new ( self ) ;
245+ let root_node = Self :: ensure_is_owned ( & mut map. root ) . node_as_mut ( ) ;
246+ match search:: search_tree :: < marker:: Mut < ' _ > , K , ( ) , K > ( root_node, & key) {
246247 Found ( handle) => Some ( mem:: replace ( handle. into_key_mut ( ) , key) ) ,
247248 GoDown ( handle) => {
248- VacantEntry { key, handle, length : & mut self . length , _marker : PhantomData }
249- . insert ( ( ) ) ;
249+ VacantEntry { key, handle, dormant_map, _marker : PhantomData } . insert ( ( ) ) ;
250250 None
251251 }
252252 }
@@ -460,7 +460,7 @@ impl<K: Debug + Ord, V: Debug> Debug for Entry<'_, K, V> {
460460pub struct VacantEntry < ' a , K : ' a , V : ' a > {
461461 key : K ,
462462 handle : Handle < NodeRef < marker:: Mut < ' a > , K , V , marker:: Leaf > , marker:: Edge > ,
463- length : & ' a mut usize ,
463+ dormant_map : DormantMutRef < ' a , BTreeMap < K , V > > ,
464464
465465 // Be invariant in `K` and `V`
466466 _marker : PhantomData < & ' a mut ( K , V ) > ,
@@ -480,8 +480,7 @@ impl<K: Debug + Ord, V> Debug for VacantEntry<'_, K, V> {
480480#[ stable( feature = "rust1" , since = "1.0.0" ) ]
481481pub struct OccupiedEntry < ' a , K : ' a , V : ' a > {
482482 handle : Handle < NodeRef < marker:: Mut < ' a > , K , V , marker:: LeafOrInternal > , marker:: KV > ,
483-
484- length : & ' a mut usize ,
483+ dormant_map : DormantMutRef < ' a , BTreeMap < K , V > > ,
485484
486485 // Be invariant in `K` and `V`
487486 _marker : PhantomData < & ' a mut ( K , V ) > ,
@@ -645,13 +644,10 @@ impl<K: Ord, V> BTreeMap<K, V> {
645644 /// ```
646645 #[ unstable( feature = "map_first_last" , issue = "62924" ) ]
647646 pub fn first_entry ( & mut self ) -> Option < OccupiedEntry < ' _ , K , V > > {
648- let root_node = self . root . as_mut ( ) ?. node_as_mut ( ) ;
647+ let ( map, dormant_map) = DormantMutRef :: new ( self ) ;
648+ let root_node = map. root . as_mut ( ) ?. node_as_mut ( ) ;
649649 let kv = root_node. first_leaf_edge ( ) . right_kv ( ) . ok ( ) ?;
650- Some ( OccupiedEntry {
651- handle : kv. forget_node_type ( ) ,
652- length : & mut self . length ,
653- _marker : PhantomData ,
654- } )
650+ Some ( OccupiedEntry { handle : kv. forget_node_type ( ) , dormant_map, _marker : PhantomData } )
655651 }
656652
657653 /// Removes and returns the first element in the map.
@@ -722,13 +718,10 @@ impl<K: Ord, V> BTreeMap<K, V> {
722718 /// ```
723719 #[ unstable( feature = "map_first_last" , issue = "62924" ) ]
724720 pub fn last_entry ( & mut self ) -> Option < OccupiedEntry < ' _ , K , V > > {
725- let root_node = self . root . as_mut ( ) ?. node_as_mut ( ) ;
721+ let ( map, dormant_map) = DormantMutRef :: new ( self ) ;
722+ let root_node = map. root . as_mut ( ) ?. node_as_mut ( ) ;
726723 let kv = root_node. last_leaf_edge ( ) . left_kv ( ) . ok ( ) ?;
727- Some ( OccupiedEntry {
728- handle : kv. forget_node_type ( ) ,
729- length : & mut self . length ,
730- _marker : PhantomData ,
731- } )
724+ Some ( OccupiedEntry { handle : kv. forget_node_type ( ) , dormant_map, _marker : PhantomData } )
732725 }
733726
734727 /// Removes and returns the last element in the map.
@@ -902,12 +895,12 @@ impl<K: Ord, V> BTreeMap<K, V> {
902895 K : Borrow < Q > ,
903896 Q : Ord ,
904897 {
905- let root_node = self . root . as_mut ( ) ?. node_as_mut ( ) ;
898+ let ( map, dormant_map) = DormantMutRef :: new ( self ) ;
899+ let root_node = map. root . as_mut ( ) ?. node_as_mut ( ) ;
906900 match search:: search_tree ( root_node, key) {
907- Found ( handle) => Some (
908- OccupiedEntry { handle, length : & mut self . length , _marker : PhantomData }
909- . remove_entry ( ) ,
910- ) ,
901+ Found ( handle) => {
902+ Some ( OccupiedEntry { handle, dormant_map, _marker : PhantomData } . remove_entry ( ) )
903+ }
911904 GoDown ( _) => None ,
912905 }
913906 }
@@ -1074,13 +1067,12 @@ impl<K: Ord, V> BTreeMap<K, V> {
10741067 #[ stable( feature = "rust1" , since = "1.0.0" ) ]
10751068 pub fn entry ( & mut self , key : K ) -> Entry < ' _ , K , V > {
10761069 // FIXME(@porglezomp) Avoid allocating if we don't insert
1077- let root = Self :: ensure_is_owned ( & mut self . root ) ;
1078- match search:: search_tree ( root. node_as_mut ( ) , & key) {
1079- Found ( handle) => {
1080- Occupied ( OccupiedEntry { handle, length : & mut self . length , _marker : PhantomData } )
1081- }
1070+ let ( map, dormant_map) = DormantMutRef :: new ( self ) ;
1071+ let root_node = Self :: ensure_is_owned ( & mut map. root ) . node_as_mut ( ) ;
1072+ match search:: search_tree ( root_node, & key) {
1073+ Found ( handle) => Occupied ( OccupiedEntry { handle, dormant_map, _marker : PhantomData } ) ,
10821074 GoDown ( handle) => {
1083- Vacant ( VacantEntry { key, handle, length : & mut self . length , _marker : PhantomData } )
1075+ Vacant ( VacantEntry { key, handle, dormant_map , _marker : PhantomData } )
10841076 }
10851077 }
10861078 }
@@ -1285,9 +1277,17 @@ impl<K: Ord, V> BTreeMap<K, V> {
12851277 }
12861278
12871279 pub ( super ) fn drain_filter_inner ( & mut self ) -> DrainFilterInner < ' _ , K , V > {
1288- let root_node = self . root . as_mut ( ) . map ( |r| r. node_as_mut ( ) ) ;
1289- let front = root_node. map ( |rn| rn. first_leaf_edge ( ) ) ;
1290- DrainFilterInner { length : & mut self . length , cur_leaf_edge : front }
1280+ if let Some ( root) = self . root . as_mut ( ) {
1281+ let ( root, dormant_root) = DormantMutRef :: new ( root) ;
1282+ let front = root. node_as_mut ( ) . first_leaf_edge ( ) ;
1283+ DrainFilterInner {
1284+ length : & mut self . length ,
1285+ dormant_root : Some ( dormant_root) ,
1286+ cur_leaf_edge : Some ( front) ,
1287+ }
1288+ } else {
1289+ DrainFilterInner { length : & mut self . length , dormant_root : None , cur_leaf_edge : None }
1290+ }
12911291 }
12921292
12931293 /// Creates a consuming iterator visiting all the keys, in sorted order.
@@ -1672,6 +1672,9 @@ where
16721672/// of the predicate, thus also serving for BTreeSet::DrainFilter.
16731673pub ( super ) struct DrainFilterInner < ' a , K : ' a , V : ' a > {
16741674 length : & ' a mut usize ,
1675+ // dormant_root is wrapped in an Option to be able to `take` it.
1676+ dormant_root : Option < DormantMutRef < ' a , node:: Root < K , V > > > ,
1677+ // cur_leaf_edge is wrapped in an Option because maps without root lack a leaf edge.
16751678 cur_leaf_edge : Option < Handle < NodeRef < marker:: Mut < ' a > , K , V , marker:: Leaf > , marker:: Edge > > ,
16761679}
16771680
@@ -1729,7 +1732,13 @@ impl<'a, K: 'a, V: 'a> DrainFilterInner<'a, K, V> {
17291732 let ( k, v) = kv. kv_mut ( ) ;
17301733 if pred ( k, v) {
17311734 * self . length -= 1 ;
1732- let ( kv, pos) = kv. remove_kv_tracking ( ) ;
1735+ let ( kv, pos) = kv. remove_kv_tracking ( || {
1736+ // SAFETY: we will touch the root in a way that will not
1737+ // invalidate the position returned.
1738+ let root = unsafe { self . dormant_root . take ( ) . unwrap ( ) . awaken ( ) } ;
1739+ root. pop_internal_level ( ) ;
1740+ self . dormant_root = Some ( DormantMutRef :: new ( root) . 1 ) ;
1741+ } ) ;
17331742 self . cur_leaf_edge = Some ( pos) ;
17341743 return Some ( kv) ;
17351744 }
@@ -2570,13 +2579,20 @@ impl<'a, K: Ord, V> VacantEntry<'a, K, V> {
25702579 /// ```
25712580 #[ stable( feature = "rust1" , since = "1.0.0" ) ]
25722581 pub fn insert ( self , value : V ) -> & ' a mut V {
2573- * self . length += 1 ;
2574-
25752582 let out_ptr = match self . handle . insert_recursing ( self . key , value) {
2576- ( Fit ( _) , val_ptr) => val_ptr,
2583+ ( Fit ( _) , val_ptr) => {
2584+ // Safety: We have consumed self.handle and the handle returned.
2585+ let map = unsafe { self . dormant_map . awaken ( ) } ;
2586+ map. length += 1 ;
2587+ val_ptr
2588+ }
25772589 ( Split ( ins) , val_ptr) => {
2578- let root = ins. left . into_root_mut ( ) ;
2590+ drop ( ins. left ) ;
2591+ // Safety: We have consumed self.handle and the reference returned.
2592+ let map = unsafe { self . dormant_map . awaken ( ) } ;
2593+ let root = map. root . as_mut ( ) . unwrap ( ) ;
25792594 root. push_internal_level ( ) . push ( ins. k , ins. v , ins. right ) ;
2595+ map. length += 1 ;
25802596 val_ptr
25812597 }
25822598 } ;
@@ -2750,18 +2766,25 @@ impl<'a, K: Ord, V> OccupiedEntry<'a, K, V> {
27502766
27512767 // Body of `remove_entry`, separate to keep the above implementations short.
27522768 fn remove_kv ( self ) -> ( K , V ) {
2753- * self . length -= 1 ;
2754-
2755- let ( old_kv, _) = self . handle . remove_kv_tracking ( ) ;
2769+ let mut emptied_internal_root = false ;
2770+ let ( old_kv, _) = self . handle . remove_kv_tracking ( || emptied_internal_root = true ) ;
2771+ // SAFETY: we consumed the intermediate root borrow, `self.handle`.
2772+ let map = unsafe { self . dormant_map . awaken ( ) } ;
2773+ map. length -= 1 ;
2774+ if emptied_internal_root {
2775+ let root = map. root . as_mut ( ) . unwrap ( ) ;
2776+ root. pop_internal_level ( ) ;
2777+ }
27562778 old_kv
27572779 }
27582780}
27592781
27602782impl < ' a , K : ' a , V : ' a > Handle < NodeRef < marker:: Mut < ' a > , K , V , marker:: LeafOrInternal > , marker:: KV > {
27612783 /// Removes a key/value-pair from the map, and returns that pair, as well as
27622784 /// the leaf edge corresponding to that former pair.
2763- fn remove_kv_tracking (
2785+ fn remove_kv_tracking < F : FnOnce ( ) > (
27642786 self ,
2787+ handle_emptied_internal_root : F ,
27652788 ) -> ( ( K , V ) , Handle < NodeRef < marker:: Mut < ' a > , K , V , marker:: Leaf > , marker:: Edge > ) {
27662789 let ( old_kv, mut pos, was_internal) = match self . force ( ) {
27672790 Leaf ( leaf) => {
@@ -2814,7 +2837,7 @@ impl<'a, K: 'a, V: 'a> Handle<NodeRef<marker::Mut<'a>, K, V, marker::LeafOrInter
28142837 // The parent that was just emptied must be the root,
28152838 // because nodes on a lower level would not have been
28162839 // left with a single child.
2817- parent . into_root_mut ( ) . pop_internal_level ( ) ;
2840+ handle_emptied_internal_root ( ) ;
28182841 break ;
28192842 } else {
28202843 cur_node = parent. forget_type ( ) ;
0 commit comments