@@ -104,34 +104,39 @@ where
104
104
}
105
105
}
106
106
107
- /// Equivalent to `range_search(k, v, ..)` but without the `Ord` bound.
108
- fn full_range < BorrowType , K , V > (
109
- root1 : NodeRef < BorrowType , K , V , marker:: LeafOrInternal > ,
110
- root2 : NodeRef < BorrowType , K , V , marker:: LeafOrInternal > ,
111
- ) -> (
112
- Handle < NodeRef < BorrowType , K , V , marker:: Leaf > , marker:: Edge > ,
113
- Handle < NodeRef < BorrowType , K , V , marker:: Leaf > , marker:: Edge > ,
114
- ) {
115
- let mut min_node = root1;
116
- let mut max_node = root2;
117
- loop {
118
- let front = min_node. first_edge ( ) ;
119
- let back = max_node. last_edge ( ) ;
120
- match ( front. force ( ) , back. force ( ) ) {
121
- ( Leaf ( f) , Leaf ( b) ) => {
122
- return ( f, b) ;
107
+ /// Equivalent to `range_search(self, self, ..)` but without the `Ord` bound.
108
+ /// Equivalent to `(self.first_leaf_edge(), self.last_leaf_edge())` but
109
+ /// duplicating `self` and more efficient.
110
+ /// # Safety
111
+ /// - Do not expose for `BorrowType` `Mut`, because one handle could destroy the
112
+ /// edge or node referred to by the other.
113
+ /// - Unless `BorrowType` is `Immut`, do not use the two handles to visit the
114
+ /// same KV twice.
115
+ impl < BorrowType , K , V > NodeRef < BorrowType , K , V , marker:: LeafOrInternal > {
116
+ unsafe fn find_leaf_edges_spanning_tree (
117
+ self ,
118
+ ) -> (
119
+ Handle < NodeRef < BorrowType , K , V , marker:: Leaf > , marker:: Edge > ,
120
+ Handle < NodeRef < BorrowType , K , V , marker:: Leaf > , marker:: Edge > ,
121
+ ) {
122
+ match self . force ( ) {
123
+ Leaf ( root1) => {
124
+ let root2 = unsafe { ptr:: read ( & root1) } ;
125
+ return ( root1. first_edge ( ) , root2. last_edge ( ) ) ;
123
126
}
124
- ( Internal ( min_int) , Internal ( max_int) ) => {
125
- min_node = min_int. descend ( ) ;
126
- max_node = max_int. descend ( ) ;
127
+ Internal ( root1) => {
128
+ let root2 = unsafe { ptr:: read ( & root1) } ;
129
+ // Read both ends of the edges array jointly.
130
+ let first_child = root1. first_edge ( ) . descend ( ) ;
131
+ let last_child = root2. last_edge ( ) . descend ( ) ;
132
+ ( first_child. first_leaf_edge ( ) , last_child. last_leaf_edge ( ) )
127
133
}
128
- _ => unreachable ! ( "BTreeMap has different depths" ) ,
129
- } ;
134
+ }
130
135
}
131
136
}
132
137
133
138
impl < ' a , K : ' a , V : ' a > NodeRef < marker:: Immut < ' a > , K , V , marker:: LeafOrInternal > {
134
- /// Creates a pair of leaf edges delimiting a specified range in or underneath a node .
139
+ /// Finds the pair of leaf edges delimiting a specified range in the tree .
135
140
///
136
141
/// The result is meaningful only if the tree is ordered by key, like the tree
137
142
/// in a `BTreeMap` is.
@@ -150,14 +155,15 @@ impl<'a, K: 'a, V: 'a> NodeRef<marker::Immut<'a>, K, V, marker::LeafOrInternal>
150
155
range_search ( self , self , range)
151
156
}
152
157
153
- /// Returns (self.first_leaf_edge(), self.last_leaf_edge()), but more efficiently .
158
+ /// Finds the pair of leaf edges delimiting the entire tree .
154
159
pub fn full_range (
155
160
self ,
156
161
) -> (
157
162
Handle < NodeRef < marker:: Immut < ' a > , K , V , marker:: Leaf > , marker:: Edge > ,
158
163
Handle < NodeRef < marker:: Immut < ' a > , K , V , marker:: Leaf > , marker:: Edge > ,
159
164
) {
160
- full_range ( self , self )
165
+ // SAFETY: our borrow type is `Immut`.
166
+ unsafe { self . find_leaf_edges_spanning_tree ( ) }
161
167
}
162
168
}
163
169
@@ -195,10 +201,9 @@ impl<'a, K: 'a, V: 'a> NodeRef<marker::ValMut<'a>, K, V, marker::LeafOrInternal>
195
201
Handle < NodeRef < marker:: ValMut < ' a > , K , V , marker:: Leaf > , marker:: Edge > ,
196
202
Handle < NodeRef < marker:: ValMut < ' a > , K , V , marker:: Leaf > , marker:: Edge > ,
197
203
) {
198
- // We duplicate the root NodeRef here -- we will never visit the same KV
199
- // twice, and never end up with overlapping value references.
200
- let self2 = unsafe { ptr:: read ( & self ) } ;
201
- full_range ( self , self2)
204
+ // SAFETY: we will never visit the same KV twice,
205
+ // and never end up with overlapping value references.
206
+ unsafe { self . find_leaf_edges_spanning_tree ( ) }
202
207
}
203
208
}
204
209
@@ -212,10 +217,9 @@ impl<K, V> NodeRef<marker::Owned, K, V, marker::LeafOrInternal> {
212
217
Handle < NodeRef < marker:: Owned , K , V , marker:: Leaf > , marker:: Edge > ,
213
218
Handle < NodeRef < marker:: Owned , K , V , marker:: Leaf > , marker:: Edge > ,
214
219
) {
215
- // We duplicate the root NodeRef here -- we will never access it in a way
216
- // that overlaps references obtained from the root.
217
- let self2 = unsafe { ptr:: read ( & self ) } ;
218
- full_range ( self , self2)
220
+ // SAFETY: we will never visit the same KV twice,
221
+ // because we only visit any KV to drop it.
222
+ unsafe { self . find_leaf_edges_spanning_tree ( ) }
219
223
}
220
224
}
221
225
0 commit comments