1
+ use core:: borrow:: Borrow ;
2
+ use core:: cmp:: Ordering ;
1
3
use core:: intrinsics;
2
4
use core:: mem;
5
+ use core:: ops:: Bound :: { Excluded , Included , Unbounded } ;
6
+ use core:: ops:: RangeBounds ;
3
7
use core:: ptr;
4
8
5
9
use super :: node:: { marker, ForceResult :: * , Handle , NodeRef } ;
10
+ use super :: search:: { self , SearchResult } ;
6
11
use super :: unwrap_unchecked;
7
12
13
+ /// Finds the leaf edges delimiting a specified range in or underneath a node.
14
+ fn range_search < BorrowType , K , V , Q , R > (
15
+ root1 : NodeRef < BorrowType , K , V , marker:: LeafOrInternal > ,
16
+ root2 : NodeRef < BorrowType , K , V , marker:: LeafOrInternal > ,
17
+ range : R ,
18
+ ) -> (
19
+ Handle < NodeRef < BorrowType , K , V , marker:: Leaf > , marker:: Edge > ,
20
+ Handle < NodeRef < BorrowType , K , V , marker:: Leaf > , marker:: Edge > ,
21
+ )
22
+ where
23
+ Q : ?Sized + Ord ,
24
+ K : Borrow < Q > ,
25
+ R : RangeBounds < Q > ,
26
+ {
27
+ match ( range. start_bound ( ) , range. end_bound ( ) ) {
28
+ ( Excluded ( s) , Excluded ( e) ) if s == e => {
29
+ panic ! ( "range start and end are equal and excluded in BTreeMap" )
30
+ }
31
+ ( Included ( s) | Excluded ( s) , Included ( e) | Excluded ( e) ) if s > e => {
32
+ panic ! ( "range start is greater than range end in BTreeMap" )
33
+ }
34
+ _ => { }
35
+ } ;
36
+
37
+ let mut min_node = root1;
38
+ let mut max_node = root2;
39
+ let mut min_found = false ;
40
+ let mut max_found = false ;
41
+
42
+ loop {
43
+ let front = match ( min_found, range. start_bound ( ) ) {
44
+ ( false , Included ( key) ) => match search:: search_node ( min_node, key) {
45
+ SearchResult :: Found ( kv) => {
46
+ min_found = true ;
47
+ kv. left_edge ( )
48
+ }
49
+ SearchResult :: GoDown ( edge) => edge,
50
+ } ,
51
+ ( false , Excluded ( key) ) => match search:: search_node ( min_node, key) {
52
+ SearchResult :: Found ( kv) => {
53
+ min_found = true ;
54
+ kv. right_edge ( )
55
+ }
56
+ SearchResult :: GoDown ( edge) => edge,
57
+ } ,
58
+ ( true , Included ( _) ) => min_node. last_edge ( ) ,
59
+ ( true , Excluded ( _) ) => min_node. first_edge ( ) ,
60
+ ( _, Unbounded ) => min_node. first_edge ( ) ,
61
+ } ;
62
+
63
+ let back = match ( max_found, range. end_bound ( ) ) {
64
+ ( false , Included ( key) ) => match search:: search_node ( max_node, key) {
65
+ SearchResult :: Found ( kv) => {
66
+ max_found = true ;
67
+ kv. right_edge ( )
68
+ }
69
+ SearchResult :: GoDown ( edge) => edge,
70
+ } ,
71
+ ( false , Excluded ( key) ) => match search:: search_node ( max_node, key) {
72
+ SearchResult :: Found ( kv) => {
73
+ max_found = true ;
74
+ kv. left_edge ( )
75
+ }
76
+ SearchResult :: GoDown ( edge) => edge,
77
+ } ,
78
+ ( true , Included ( _) ) => max_node. first_edge ( ) ,
79
+ ( true , Excluded ( _) ) => max_node. last_edge ( ) ,
80
+ ( _, Unbounded ) => max_node. last_edge ( ) ,
81
+ } ;
82
+
83
+ if front. partial_cmp ( & back) == Some ( Ordering :: Greater ) {
84
+ panic ! ( "Ord is ill-defined in BTreeMap range" ) ;
85
+ }
86
+ match ( front. force ( ) , back. force ( ) ) {
87
+ ( Leaf ( f) , Leaf ( b) ) => {
88
+ return ( f, b) ;
89
+ }
90
+ ( Internal ( min_int) , Internal ( max_int) ) => {
91
+ min_node = min_int. descend ( ) ;
92
+ max_node = max_int. descend ( ) ;
93
+ }
94
+ _ => unreachable ! ( "BTreeMap has different depths" ) ,
95
+ } ;
96
+ }
97
+ }
98
+
99
+ /// Equivalent to `range_search(k, v, ..)` but without the `Ord` bound.
100
+ fn full_range < BorrowType , K , V > (
101
+ root1 : NodeRef < BorrowType , K , V , marker:: LeafOrInternal > ,
102
+ root2 : NodeRef < BorrowType , K , V , marker:: LeafOrInternal > ,
103
+ ) -> (
104
+ Handle < NodeRef < BorrowType , K , V , marker:: Leaf > , marker:: Edge > ,
105
+ Handle < NodeRef < BorrowType , K , V , marker:: Leaf > , marker:: Edge > ,
106
+ ) {
107
+ let mut min_node = root1;
108
+ let mut max_node = root2;
109
+ loop {
110
+ let front = min_node. first_edge ( ) ;
111
+ let back = max_node. last_edge ( ) ;
112
+ match ( front. force ( ) , back. force ( ) ) {
113
+ ( Leaf ( f) , Leaf ( b) ) => {
114
+ return ( f, b) ;
115
+ }
116
+ ( Internal ( min_int) , Internal ( max_int) ) => {
117
+ min_node = min_int. descend ( ) ;
118
+ max_node = max_int. descend ( ) ;
119
+ }
120
+ _ => unreachable ! ( "BTreeMap has different depths" ) ,
121
+ } ;
122
+ }
123
+ }
124
+
125
+ impl < ' a , K : ' a , V : ' a > NodeRef < marker:: Immut < ' a > , K , V , marker:: LeafOrInternal > {
126
+ /// Creates a pair of leaf edges delimiting a specified range in or underneath a node.
127
+ pub fn range_search < Q , R > (
128
+ self ,
129
+ range : R ,
130
+ ) -> (
131
+ Handle < NodeRef < marker:: Immut < ' a > , K , V , marker:: Leaf > , marker:: Edge > ,
132
+ Handle < NodeRef < marker:: Immut < ' a > , K , V , marker:: Leaf > , marker:: Edge > ,
133
+ )
134
+ where
135
+ Q : ?Sized + Ord ,
136
+ K : Borrow < Q > ,
137
+ R : RangeBounds < Q > ,
138
+ {
139
+ range_search ( self , self , range)
140
+ }
141
+
142
+ /// Returns (self.first_leaf_edge(), self.last_leaf_edge()), but more efficiently.
143
+ pub fn full_range (
144
+ self ,
145
+ ) -> (
146
+ Handle < NodeRef < marker:: Immut < ' a > , K , V , marker:: Leaf > , marker:: Edge > ,
147
+ Handle < NodeRef < marker:: Immut < ' a > , K , V , marker:: Leaf > , marker:: Edge > ,
148
+ ) {
149
+ full_range ( self , self )
150
+ }
151
+ }
152
+
153
+ impl < ' a , K : ' a , V : ' a > NodeRef < marker:: ValMut < ' a > , K , V , marker:: LeafOrInternal > {
154
+ /// Splits a unique reference into a pair of leaf edges delimiting a specified range.
155
+ /// The result are non-unique references allowing (some) mutation, which must be used
156
+ /// carefully.
157
+ pub fn range_search < Q , R > (
158
+ self ,
159
+ range : R ,
160
+ ) -> (
161
+ Handle < NodeRef < marker:: ValMut < ' a > , K , V , marker:: Leaf > , marker:: Edge > ,
162
+ Handle < NodeRef < marker:: ValMut < ' a > , K , V , marker:: Leaf > , marker:: Edge > ,
163
+ )
164
+ where
165
+ Q : ?Sized + Ord ,
166
+ K : Borrow < Q > ,
167
+ R : RangeBounds < Q > ,
168
+ {
169
+ // We duplicate the root NodeRef here -- we will never visit the same KV
170
+ // twice, and never end up with overlapping value references.
171
+ let self2 = unsafe { ptr:: read ( & self ) } ;
172
+ range_search ( self , self2, range)
173
+ }
174
+
175
+ /// Splits a unique reference into a pair of leaf edges delimiting the full range of the tree.
176
+ /// The results are non-unique references allowing mutation (of values only), so must be used
177
+ /// with care.
178
+ pub fn full_range (
179
+ self ,
180
+ ) -> (
181
+ Handle < NodeRef < marker:: ValMut < ' a > , K , V , marker:: Leaf > , marker:: Edge > ,
182
+ Handle < NodeRef < marker:: ValMut < ' a > , K , V , marker:: Leaf > , marker:: Edge > ,
183
+ ) {
184
+ // We duplicate the root NodeRef here -- we will never visit the same KV
185
+ // twice, and never end up with overlapping value references.
186
+ let self2 = unsafe { ptr:: read ( & self ) } ;
187
+ full_range ( self , self2)
188
+ }
189
+ }
190
+
191
+ impl < K , V > NodeRef < marker:: Owned , K , V , marker:: LeafOrInternal > {
192
+ /// Splits a unique reference into a pair of leaf edges delimiting the full range of the tree.
193
+ /// The results are non-unique references allowing massively destructive mutation, so must be
194
+ /// used with the utmost care.
195
+ pub fn full_range (
196
+ self ,
197
+ ) -> (
198
+ Handle < NodeRef < marker:: Owned , K , V , marker:: Leaf > , marker:: Edge > ,
199
+ Handle < NodeRef < marker:: Owned , K , V , marker:: Leaf > , marker:: Edge > ,
200
+ ) {
201
+ // We duplicate the root NodeRef here -- we will never access it in a way
202
+ // that overlaps references obtained from the root.
203
+ let self2 = unsafe { ptr:: read ( & self ) } ;
204
+ full_range ( self , self2)
205
+ }
206
+ }
207
+
8
208
impl < BorrowType , K , V > Handle < NodeRef < BorrowType , K , V , marker:: Leaf > , marker:: Edge > {
9
209
/// Given a leaf edge handle, returns [`Result::Ok`] with a handle to the neighboring KV
10
210
/// on the right side, which is either in the same leaf node or in an ancestor node.
@@ -75,12 +275,13 @@ impl<BorrowType, K, V> Handle<NodeRef<BorrowType, K, V, marker::Internal>, marke
75
275
macro_rules! def_next_kv_uncheched_dealloc {
76
276
{ unsafe fn $name: ident : $adjacent_kv: ident } => {
77
277
/// Given a leaf edge handle into an owned tree, returns a handle to the next KV,
78
- /// while deallocating any node left behind.
79
- /// Unsafe for two reasons:
80
- /// - The caller must ensure that the leaf edge is not the last one in the tree.
81
- /// - The node pointed at by the given handle, and its ancestors, may be deallocated,
82
- /// while the reference to those nodes in the surviving ancestors is left dangling;
83
- /// thus using the returned handle to navigate further is dangerous.
278
+ /// while deallocating any node left behind yet leaving the corresponding edge
279
+ /// in its parent node dangling.
280
+ ///
281
+ /// # Safety
282
+ /// - The leaf edge must not be the last one in the direction travelled.
283
+ /// - The node carrying the next KV returned must not have been deallocated by a
284
+ /// previous call on any handle obtained for this tree.
84
285
unsafe fn $name <K , V >(
85
286
leaf_edge: Handle <NodeRef <marker:: Owned , K , V , marker:: Leaf >, marker:: Edge >,
86
287
) -> Handle <NodeRef <marker:: Owned , K , V , marker:: LeafOrInternal >, marker:: KV > {
@@ -103,6 +304,15 @@ macro_rules! def_next_kv_uncheched_dealloc {
103
304
def_next_kv_uncheched_dealloc ! { unsafe fn next_kv_unchecked_dealloc: right_kv}
104
305
def_next_kv_uncheched_dealloc ! { unsafe fn next_back_kv_unchecked_dealloc: left_kv}
105
306
307
+ /// This replaces the value behind the `v` unique reference by calling the
308
+ /// relevant function.
309
+ ///
310
+ /// If a panic occurs in the `change` closure, the entire process will be aborted.
311
+ #[ inline]
312
+ fn take_mut < T > ( v : & mut T , change : impl FnOnce ( T ) -> T ) {
313
+ replace ( v, |value| ( change ( value) , ( ) ) )
314
+ }
315
+
106
316
/// This replaces the value behind the `v` unique reference by calling the
107
317
/// relevant function, and returns a result obtained along the way.
108
318
///
@@ -128,7 +338,9 @@ fn replace<T, R>(v: &mut T, change: impl FnOnce(T) -> (T, R)) -> R {
128
338
impl < ' a , K , V > Handle < NodeRef < marker:: Immut < ' a > , K , V , marker:: Leaf > , marker:: Edge > {
129
339
/// Moves the leaf edge handle to the next leaf edge and returns references to the
130
340
/// key and value in between.
131
- /// Unsafe because the caller must ensure that the leaf edge is not the last one in the tree.
341
+ ///
342
+ /// # Safety
343
+ /// There must be another KV in the direction travelled.
132
344
pub unsafe fn next_unchecked ( & mut self ) -> ( & ' a K , & ' a V ) {
133
345
replace ( self , |leaf_edge| {
134
346
let kv = leaf_edge. next_kv ( ) ;
@@ -139,7 +351,9 @@ impl<'a, K, V> Handle<NodeRef<marker::Immut<'a>, K, V, marker::Leaf>, marker::Ed
139
351
140
352
/// Moves the leaf edge handle to the previous leaf edge and returns references to the
141
353
/// key and value in between.
142
- /// Unsafe because the caller must ensure that the leaf edge is not the first one in the tree.
354
+ ///
355
+ /// # Safety
356
+ /// There must be another KV in the direction travelled.
143
357
pub unsafe fn next_back_unchecked ( & mut self ) -> ( & ' a K , & ' a V ) {
144
358
replace ( self , |leaf_edge| {
145
359
let kv = leaf_edge. next_back_kv ( ) ;
@@ -149,53 +363,69 @@ impl<'a, K, V> Handle<NodeRef<marker::Immut<'a>, K, V, marker::Leaf>, marker::Ed
149
363
}
150
364
}
151
365
152
- impl < ' a , K , V > Handle < NodeRef < marker:: Mut < ' a > , K , V , marker:: Leaf > , marker:: Edge > {
366
+ impl < ' a , K , V > Handle < NodeRef < marker:: ValMut < ' a > , K , V , marker:: Leaf > , marker:: Edge > {
153
367
/// Moves the leaf edge handle to the next leaf edge and returns references to the
154
368
/// key and value in between.
155
- /// Unsafe for two reasons:
156
- /// - The caller must ensure that the leaf edge is not the last one in the tree.
157
- /// - Using the updated handle may well invalidate the returned references.
158
- pub unsafe fn next_unchecked ( & mut self ) -> ( & ' a mut K , & ' a mut V ) {
369
+ /// The returned references might be invalidated when the updated handle is used again.
370
+ ///
371
+ /// # Safety
372
+ /// There must be another KV in the direction travelled.
373
+ pub unsafe fn next_unchecked ( & mut self ) -> ( & ' a K , & ' a mut V ) {
159
374
let kv = replace ( self , |leaf_edge| {
160
375
let kv = leaf_edge. next_kv ( ) ;
161
376
let kv = unsafe { unwrap_unchecked ( kv. ok ( ) ) } ;
162
377
( unsafe { ptr:: read ( & kv) } . next_leaf_edge ( ) , kv)
163
378
} ) ;
164
379
// Doing the descend (and perhaps another move) invalidates the references
165
- // returned by `into_kv_mut `, so we have to do this last.
166
- kv. into_kv_mut ( )
380
+ // returned by `into_kv_valmut `, so we have to do this last.
381
+ kv. into_kv_valmut ( )
167
382
}
168
383
169
384
/// Moves the leaf edge handle to the previous leaf and returns references to the
170
385
/// key and value in between.
171
- /// Unsafe for two reasons:
172
- /// - The caller must ensure that the leaf edge is not the first one in the tree.
173
- /// - Using the updated handle may well invalidate the returned references.
174
- pub unsafe fn next_back_unchecked ( & mut self ) -> ( & ' a mut K , & ' a mut V ) {
386
+ /// The returned references might be invalidated when the updated handle is used again.
387
+ ///
388
+ /// # Safety
389
+ /// There must be another KV in the direction travelled.
390
+ pub unsafe fn next_back_unchecked ( & mut self ) -> ( & ' a K , & ' a mut V ) {
175
391
let kv = replace ( self , |leaf_edge| {
176
392
let kv = leaf_edge. next_back_kv ( ) ;
177
393
let kv = unsafe { unwrap_unchecked ( kv. ok ( ) ) } ;
178
394
( unsafe { ptr:: read ( & kv) } . next_back_leaf_edge ( ) , kv)
179
395
} ) ;
180
396
// Doing the descend (and perhaps another move) invalidates the references
181
- // returned by `into_kv_mut`, so we have to do this last.
182
- kv. into_kv_mut ( )
397
+ // returned by `into_kv_valmut`, so we have to do this last.
398
+ kv. into_kv_valmut ( )
399
+ }
400
+ }
401
+
402
+ impl < ' a , K , V > Handle < NodeRef < marker:: Mut < ' a > , K , V , marker:: Leaf > , marker:: Edge > {
403
+ /// Moves the leaf edge handle to the next leaf edge.
404
+ ///
405
+ /// # Safety
406
+ /// There must be another KV in the direction travelled.
407
+ pub unsafe fn move_next_unchecked ( & mut self ) {
408
+ take_mut ( self , |leaf_edge| {
409
+ let kv = leaf_edge. next_kv ( ) ;
410
+ let kv = unsafe { unwrap_unchecked ( kv. ok ( ) ) } ;
411
+ kv. next_leaf_edge ( )
412
+ } )
183
413
}
184
414
}
185
415
186
416
impl < K , V > Handle < NodeRef < marker:: Owned , K , V , marker:: Leaf > , marker:: Edge > {
187
417
/// Moves the leaf edge handle to the next leaf edge and returns the key and value
188
- /// in between, while deallocating any node left behind.
189
- /// Unsafe for two reasons:
190
- /// - The caller must ensure that the leaf edge is not the last one in the tree
191
- /// and is not a handle previously resulting from counterpart `next_back_unchecked`.
192
- /// - Further use of the updated leaf edge handle is very dangerous. In particular,
193
- /// if the leaf edge is the last edge of a node, that node and possibly ancestors
194
- /// will be deallocated, while the reference to those nodes in the surviving ancestor
195
- /// is left dangling.
196
- /// The only safe way to proceed with the updated handle is to compare it, drop it,
197
- /// call this method again subject to both preconditions listed in the first point,
198
- /// or call counterpart `next_back_unchecked` subject to its preconditions .
418
+ /// in between, deallocating any node left behind while leaving the corresponding
419
+ /// edge in its parent node dangling.
420
+ ///
421
+ /// # Safety
422
+ /// - There must be another KV in the direction travelled.
423
+ /// - That KV was not previously returned by counterpart `next_back_unchecked`
424
+ /// on any copy of the handles being used to traverse the tree.
425
+ ///
426
+ /// The only safe way to proceed with the updated handle is to compare it, drop it,
427
+ /// call this method again subject to its safety conditions, or call counterpart
428
+ /// `next_back_unchecked` subject to its safety conditions .
199
429
pub unsafe fn next_unchecked ( & mut self ) -> ( K , V ) {
200
430
replace ( self , |leaf_edge| {
201
431
let kv = unsafe { next_kv_unchecked_dealloc ( leaf_edge) } ;
@@ -205,18 +435,18 @@ impl<K, V> Handle<NodeRef<marker::Owned, K, V, marker::Leaf>, marker::Edge> {
205
435
} )
206
436
}
207
437
208
- /// Moves the leaf edge handle to the previous leaf edge and returns the key
209
- /// and value in between, while deallocating any node left behind.
210
- /// Unsafe for two reasons:
211
- /// - The caller must ensure that the leaf edge is not the first one in the tree
212
- /// and is not a handle previously resulting from counterpart `next_unchecked`.
213
- /// - Further use of the updated leaf edge handle is very dangerous. In particular,
214
- /// if the leaf edge is the first edge of a node, that node and possibly ancestors
215
- /// will be deallocated, while the reference to those nodes in the surviving ancestor
216
- /// is left dangling.
217
- /// The only safe way to proceed with the updated handle is to compare it, drop it,
218
- /// call this method again subject to both preconditions listed in the first point,
219
- /// or call counterpart `next_unchecked` subject to its preconditions .
438
+ /// Moves the leaf edge handle to the previous leaf edge and returns the key and value
439
+ /// in between, deallocating any node left behind while leaving the corresponding
440
+ /// edge in its parent node dangling.
441
+ ///
442
+ /// # Safety
443
+ /// - There must be another KV in the direction travelled.
444
+ /// - That leaf edge was not previously returned by counterpart `next_unchecked`
445
+ /// on any copy of the handles being used to traverse the tree.
446
+ ///
447
+ /// The only safe way to proceed with the updated handle is to compare it, drop it,
448
+ /// call this method again subject to its safety conditions, or call counterpart
449
+ /// `next_unchecked` subject to its safety conditions .
220
450
pub unsafe fn next_back_unchecked ( & mut self ) -> ( K , V ) {
221
451
replace ( self , |leaf_edge| {
222
452
let kv = unsafe { next_back_kv_unchecked_dealloc ( leaf_edge) } ;
0 commit comments