@@ -9,6 +9,7 @@ use core::ops::Bound::{Excluded, Included, Unbounded};
9
9
use core:: ops:: { Index , RangeBounds } ;
10
10
use core:: ptr;
11
11
12
+ use super :: borrow:: DormantMutRef ;
12
13
use super :: node:: { self , marker, ForceResult :: * , Handle , InsertResult :: * , NodeRef } ;
13
14
use super :: search:: { self , SearchResult :: * } ;
14
15
use super :: unwrap_unchecked;
@@ -229,24 +230,23 @@ where
229
230
}
230
231
231
232
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 ( ) ;
233
235
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
+ }
239
239
GoDown ( _) => None ,
240
240
}
241
241
}
242
242
243
243
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) {
246
247
Found ( handle) => Some ( mem:: replace ( handle. into_key_mut ( ) , key) ) ,
247
248
GoDown ( handle) => {
248
- VacantEntry { key, handle, length : & mut self . length , _marker : PhantomData }
249
- . insert ( ( ) ) ;
249
+ VacantEntry { key, handle, dormant_map, _marker : PhantomData } . insert ( ( ) ) ;
250
250
None
251
251
}
252
252
}
@@ -460,7 +460,7 @@ impl<K: Debug + Ord, V: Debug> Debug for Entry<'_, K, V> {
460
460
pub struct VacantEntry < ' a , K : ' a , V : ' a > {
461
461
key : K ,
462
462
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 > > ,
464
464
465
465
// Be invariant in `K` and `V`
466
466
_marker : PhantomData < & ' a mut ( K , V ) > ,
@@ -480,8 +480,7 @@ impl<K: Debug + Ord, V> Debug for VacantEntry<'_, K, V> {
480
480
#[ stable( feature = "rust1" , since = "1.0.0" ) ]
481
481
pub struct OccupiedEntry < ' a , K : ' a , V : ' a > {
482
482
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 > > ,
485
484
486
485
// Be invariant in `K` and `V`
487
486
_marker : PhantomData < & ' a mut ( K , V ) > ,
@@ -645,13 +644,10 @@ impl<K: Ord, V> BTreeMap<K, V> {
645
644
/// ```
646
645
#[ unstable( feature = "map_first_last" , issue = "62924" ) ]
647
646
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 ( ) ;
649
649
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 } )
655
651
}
656
652
657
653
/// Removes and returns the first element in the map.
@@ -722,13 +718,10 @@ impl<K: Ord, V> BTreeMap<K, V> {
722
718
/// ```
723
719
#[ unstable( feature = "map_first_last" , issue = "62924" ) ]
724
720
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 ( ) ;
726
723
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 } )
732
725
}
733
726
734
727
/// Removes and returns the last element in the map.
@@ -902,12 +895,12 @@ impl<K: Ord, V> BTreeMap<K, V> {
902
895
K : Borrow < Q > ,
903
896
Q : Ord ,
904
897
{
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 ( ) ;
906
900
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
+ }
911
904
GoDown ( _) => None ,
912
905
}
913
906
}
@@ -1074,13 +1067,12 @@ impl<K: Ord, V> BTreeMap<K, V> {
1074
1067
#[ stable( feature = "rust1" , since = "1.0.0" ) ]
1075
1068
pub fn entry ( & mut self , key : K ) -> Entry < ' _ , K , V > {
1076
1069
// 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 } ) ,
1082
1074
GoDown ( handle) => {
1083
- Vacant ( VacantEntry { key, handle, length : & mut self . length , _marker : PhantomData } )
1075
+ Vacant ( VacantEntry { key, handle, dormant_map , _marker : PhantomData } )
1084
1076
}
1085
1077
}
1086
1078
}
@@ -1285,9 +1277,17 @@ impl<K: Ord, V> BTreeMap<K, V> {
1285
1277
}
1286
1278
1287
1279
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
+ }
1291
1291
}
1292
1292
1293
1293
/// Creates a consuming iterator visiting all the keys, in sorted order.
@@ -1672,6 +1672,9 @@ where
1672
1672
/// of the predicate, thus also serving for BTreeSet::DrainFilter.
1673
1673
pub ( super ) struct DrainFilterInner < ' a , K : ' a , V : ' a > {
1674
1674
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.
1675
1678
cur_leaf_edge : Option < Handle < NodeRef < marker:: Mut < ' a > , K , V , marker:: Leaf > , marker:: Edge > > ,
1676
1679
}
1677
1680
@@ -1729,7 +1732,13 @@ impl<'a, K: 'a, V: 'a> DrainFilterInner<'a, K, V> {
1729
1732
let ( k, v) = kv. kv_mut ( ) ;
1730
1733
if pred ( k, v) {
1731
1734
* 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
+ } ) ;
1733
1742
self . cur_leaf_edge = Some ( pos) ;
1734
1743
return Some ( kv) ;
1735
1744
}
@@ -2570,13 +2579,20 @@ impl<'a, K: Ord, V> VacantEntry<'a, K, V> {
2570
2579
/// ```
2571
2580
#[ stable( feature = "rust1" , since = "1.0.0" ) ]
2572
2581
pub fn insert ( self , value : V ) -> & ' a mut V {
2573
- * self . length += 1 ;
2574
-
2575
2582
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
+ }
2577
2589
( 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 ( ) ;
2579
2594
root. push_internal_level ( ) . push ( ins. k , ins. v , ins. right ) ;
2595
+ map. length += 1 ;
2580
2596
val_ptr
2581
2597
}
2582
2598
} ;
@@ -2750,18 +2766,25 @@ impl<'a, K: Ord, V> OccupiedEntry<'a, K, V> {
2750
2766
2751
2767
// Body of `remove_entry`, separate to keep the above implementations short.
2752
2768
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
+ }
2756
2778
old_kv
2757
2779
}
2758
2780
}
2759
2781
2760
2782
impl < ' a , K : ' a , V : ' a > Handle < NodeRef < marker:: Mut < ' a > , K , V , marker:: LeafOrInternal > , marker:: KV > {
2761
2783
/// Removes a key/value-pair from the map, and returns that pair, as well as
2762
2784
/// the leaf edge corresponding to that former pair.
2763
- fn remove_kv_tracking (
2785
+ fn remove_kv_tracking < F : FnOnce ( ) > (
2764
2786
self ,
2787
+ handle_emptied_internal_root : F ,
2765
2788
) -> ( ( K , V ) , Handle < NodeRef < marker:: Mut < ' a > , K , V , marker:: Leaf > , marker:: Edge > ) {
2766
2789
let ( old_kv, mut pos, was_internal) = match self . force ( ) {
2767
2790
Leaf ( leaf) => {
@@ -2814,7 +2837,7 @@ impl<'a, K: 'a, V: 'a> Handle<NodeRef<marker::Mut<'a>, K, V, marker::LeafOrInter
2814
2837
// The parent that was just emptied must be the root,
2815
2838
// because nodes on a lower level would not have been
2816
2839
// left with a single child.
2817
- parent . into_root_mut ( ) . pop_internal_level ( ) ;
2840
+ handle_emptied_internal_root ( ) ;
2818
2841
break ;
2819
2842
} else {
2820
2843
cur_node = parent. forget_type ( ) ;
0 commit comments