@@ -8,6 +8,7 @@ use core::mem::{self, ManuallyDrop};
8
8
use core:: ops:: { Index , RangeBounds } ;
9
9
use core:: ptr;
10
10
11
+ use super :: borrow:: DormantMutRef ;
11
12
use super :: node:: { self , marker, ForceResult :: * , Handle , InsertResult :: * , NodeRef } ;
12
13
use super :: search:: { self , SearchResult :: * } ;
13
14
use super :: unwrap_unchecked;
@@ -228,24 +229,23 @@ where
228
229
}
229
230
230
231
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 ( ) ;
232
234
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
+ }
238
238
GoDown ( _) => None ,
239
239
}
240
240
}
241
241
242
242
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) {
245
246
Found ( handle) => Some ( mem:: replace ( handle. into_key_mut ( ) , key) ) ,
246
247
GoDown ( handle) => {
247
- VacantEntry { key, handle, length : & mut self . length , _marker : PhantomData }
248
- . insert ( ( ) ) ;
248
+ VacantEntry { key, handle, dormant_map, _marker : PhantomData } . insert ( ( ) ) ;
249
249
None
250
250
}
251
251
}
@@ -459,7 +459,7 @@ impl<K: Debug + Ord, V: Debug> Debug for Entry<'_, K, V> {
459
459
pub struct VacantEntry < ' a , K : ' a , V : ' a > {
460
460
key : K ,
461
461
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 > > ,
463
463
464
464
// Be invariant in `K` and `V`
465
465
_marker : PhantomData < & ' a mut ( K , V ) > ,
@@ -479,8 +479,7 @@ impl<K: Debug + Ord, V> Debug for VacantEntry<'_, K, V> {
479
479
#[ stable( feature = "rust1" , since = "1.0.0" ) ]
480
480
pub struct OccupiedEntry < ' a , K : ' a , V : ' a > {
481
481
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 > > ,
484
483
485
484
// Be invariant in `K` and `V`
486
485
_marker : PhantomData < & ' a mut ( K , V ) > ,
@@ -644,13 +643,10 @@ impl<K: Ord, V> BTreeMap<K, V> {
644
643
/// ```
645
644
#[ unstable( feature = "map_first_last" , issue = "62924" ) ]
646
645
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 ( ) ;
648
648
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 } )
654
650
}
655
651
656
652
/// Removes and returns the first element in the map.
@@ -721,13 +717,10 @@ impl<K: Ord, V> BTreeMap<K, V> {
721
717
/// ```
722
718
#[ unstable( feature = "map_first_last" , issue = "62924" ) ]
723
719
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 ( ) ;
725
722
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 } )
731
724
}
732
725
733
726
/// Removes and returns the last element in the map.
@@ -901,12 +894,12 @@ impl<K: Ord, V> BTreeMap<K, V> {
901
894
K : Borrow < Q > ,
902
895
Q : Ord ,
903
896
{
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 ( ) ;
905
899
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
+ }
910
903
GoDown ( _) => None ,
911
904
}
912
905
}
@@ -1073,13 +1066,12 @@ impl<K: Ord, V> BTreeMap<K, V> {
1073
1066
#[ stable( feature = "rust1" , since = "1.0.0" ) ]
1074
1067
pub fn entry ( & mut self , key : K ) -> Entry < ' _ , K , V > {
1075
1068
// 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 } ) ,
1081
1073
GoDown ( handle) => {
1082
- Vacant ( VacantEntry { key, handle, length : & mut self . length , _marker : PhantomData } )
1074
+ Vacant ( VacantEntry { key, handle, dormant_map , _marker : PhantomData } )
1083
1075
}
1084
1076
}
1085
1077
}
@@ -1284,9 +1276,17 @@ impl<K: Ord, V> BTreeMap<K, V> {
1284
1276
}
1285
1277
1286
1278
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
+ }
1290
1290
}
1291
1291
1292
1292
/// Creates a consuming iterator visiting all the keys, in sorted order.
@@ -1671,6 +1671,9 @@ where
1671
1671
/// of the predicate, thus also serving for BTreeSet::DrainFilter.
1672
1672
pub ( super ) struct DrainFilterInner < ' a , K : ' a , V : ' a > {
1673
1673
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.
1674
1677
cur_leaf_edge : Option < Handle < NodeRef < marker:: Mut < ' a > , K , V , marker:: Leaf > , marker:: Edge > > ,
1675
1678
}
1676
1679
@@ -1728,7 +1731,13 @@ impl<'a, K: 'a, V: 'a> DrainFilterInner<'a, K, V> {
1728
1731
let ( k, v) = kv. kv_mut ( ) ;
1729
1732
if pred ( k, v) {
1730
1733
* 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
+ } ) ;
1732
1741
self . cur_leaf_edge = Some ( pos) ;
1733
1742
return Some ( kv) ;
1734
1743
}
@@ -2456,13 +2465,20 @@ impl<'a, K: Ord, V> VacantEntry<'a, K, V> {
2456
2465
/// ```
2457
2466
#[ stable( feature = "rust1" , since = "1.0.0" ) ]
2458
2467
pub fn insert ( self , value : V ) -> & ' a mut V {
2459
- * self . length += 1 ;
2460
-
2461
2468
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
+ }
2463
2475
( 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 ( ) ;
2465
2480
root. push_internal_level ( ) . push ( ins. k , ins. v , ins. right ) ;
2481
+ map. length += 1 ;
2466
2482
val_ptr
2467
2483
}
2468
2484
} ;
@@ -2636,18 +2652,25 @@ impl<'a, K: Ord, V> OccupiedEntry<'a, K, V> {
2636
2652
2637
2653
// Body of `remove_entry`, separate to keep the above implementations short.
2638
2654
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
+ }
2642
2664
old_kv
2643
2665
}
2644
2666
}
2645
2667
2646
2668
impl < ' a , K : ' a , V : ' a > Handle < NodeRef < marker:: Mut < ' a > , K , V , marker:: LeafOrInternal > , marker:: KV > {
2647
2669
/// Removes a key/value-pair from the map, and returns that pair, as well as
2648
2670
/// the leaf edge corresponding to that former pair.
2649
- fn remove_kv_tracking (
2671
+ fn remove_kv_tracking < F : FnOnce ( ) > (
2650
2672
self ,
2673
+ handle_emptied_internal_root : F ,
2651
2674
) -> ( ( K , V ) , Handle < NodeRef < marker:: Mut < ' a > , K , V , marker:: Leaf > , marker:: Edge > ) {
2652
2675
let ( old_kv, mut pos, was_internal) = match self . force ( ) {
2653
2676
Leaf ( leaf) => {
@@ -2700,7 +2723,7 @@ impl<'a, K: 'a, V: 'a> Handle<NodeRef<marker::Mut<'a>, K, V, marker::LeafOrInter
2700
2723
// The parent that was just emptied must be the root,
2701
2724
// because nodes on a lower level would not have been
2702
2725
// left with a single child.
2703
- parent . into_root_mut ( ) . pop_internal_level ( ) ;
2726
+ handle_emptied_internal_root ( ) ;
2704
2727
break ;
2705
2728
} else {
2706
2729
cur_node = parent. forget_type ( ) ;
0 commit comments