@@ -76,9 +76,7 @@ impl<BorrowType: marker::BorrowType, K, V> NodeRef<BorrowType, K, V, marker::Lea
76
76
/// If not found, returns an `Err` with the leaf edge matching the entire
77
77
/// range.
78
78
///
79
- /// As a diagnostic service, panics if the range specifies impossible bounds
80
- /// or if it witnesses that the `Ord` implementation of `Q` violates total
81
- /// order or is inconsistent with the `Ord` implementation of `K`.
79
+ /// As a diagnostic service, panics if the range specifies impossible bounds.
82
80
///
83
81
/// The result is meaningful only if the tree is ordered by key.
84
82
pub fn search_tree_for_bifurcation < ' r , Q : ?Sized , R > (
@@ -118,14 +116,8 @@ impl<BorrowType: marker::BorrowType, K, V> NodeRef<BorrowType, K, V, marker::Lea
118
116
let mut upper_bound = SearchBound :: from_range ( end) ;
119
117
loop {
120
118
let ( lower_edge_idx, lower_child_bound) = self . find_lower_bound_index ( lower_bound) ;
121
- let ( upper_edge_idx, upper_child_bound) = self . find_upper_bound_index ( upper_bound) ;
122
- if lower_edge_idx > upper_edge_idx {
123
- // Since we already checked the range bounds, this can only
124
- // happen if `Q: Ord` does not implement a total order or does
125
- // not correspond to the `K: Ord` implementation that is used
126
- // while populating the tree.
127
- panic ! ( "Ord is ill-defined in BTreeMap range" )
128
- }
119
+ let ( upper_edge_idx, upper_child_bound) =
120
+ unsafe { self . find_upper_bound_index ( upper_bound, lower_edge_idx) } ;
129
121
if lower_edge_idx < upper_edge_idx {
130
122
return Ok ( (
131
123
self ,
@@ -135,6 +127,7 @@ impl<BorrowType: marker::BorrowType, K, V> NodeRef<BorrowType, K, V, marker::Lea
135
127
upper_child_bound,
136
128
) ) ;
137
129
}
130
+ debug_assert_eq ! ( lower_edge_idx, upper_edge_idx) ;
138
131
let common_edge = unsafe { Handle :: new_edge ( self , lower_edge_idx) } ;
139
132
match common_edge. force ( ) {
140
133
Leaf ( common_edge) => return Err ( common_edge) ,
@@ -174,7 +167,7 @@ impl<BorrowType: marker::BorrowType, K, V> NodeRef<BorrowType, K, V, marker::Lea
174
167
Q : ?Sized + Ord ,
175
168
K : Borrow < Q > ,
176
169
{
177
- let ( edge_idx, bound) = self . find_upper_bound_index ( bound) ;
170
+ let ( edge_idx, bound) = unsafe { self . find_upper_bound_index ( bound, 0 ) } ;
178
171
let edge = unsafe { Handle :: new_edge ( self , edge_idx) } ;
179
172
( edge, bound)
180
173
}
@@ -193,29 +186,33 @@ impl<BorrowType, K, V, Type> NodeRef<BorrowType, K, V, Type> {
193
186
Q : Ord ,
194
187
K : Borrow < Q > ,
195
188
{
196
- match self . find_key_index ( key) {
189
+ match unsafe { self . find_key_index ( key, 0 ) } {
197
190
IndexResult :: KV ( idx) => Found ( unsafe { Handle :: new_kv ( self , idx) } ) ,
198
191
IndexResult :: Edge ( idx) => GoDown ( unsafe { Handle :: new_edge ( self , idx) } ) ,
199
192
}
200
193
}
201
194
202
195
/// Returns either the KV index in the node at which the key (or an equivalent)
203
- /// exists, or the edge index where the key belongs.
196
+ /// exists, or the edge index where the key belongs, starting from a particular index .
204
197
///
205
198
/// The result is meaningful only if the tree is ordered by key, like the tree
206
199
/// in a `BTreeMap` is.
207
- fn find_key_index < Q : ?Sized > ( & self , key : & Q ) -> IndexResult
200
+ ///
201
+ /// # Safety
202
+ /// `start_index` must be a valid edge index for the node.
203
+ unsafe fn find_key_index < Q : ?Sized > ( & self , key : & Q , start_index : usize ) -> IndexResult
208
204
where
209
205
Q : Ord ,
210
206
K : Borrow < Q > ,
211
207
{
212
208
let node = self . reborrow ( ) ;
213
209
let keys = node. keys ( ) ;
214
- for ( i, k) in keys. iter ( ) . enumerate ( ) {
210
+ debug_assert ! ( start_index <= keys. len( ) ) ;
211
+ for ( offset, k) in unsafe { keys. get_unchecked ( start_index..) } . iter ( ) . enumerate ( ) {
215
212
match key. cmp ( k. borrow ( ) ) {
216
213
Ordering :: Greater => { }
217
- Ordering :: Equal => return IndexResult :: KV ( i ) ,
218
- Ordering :: Less => return IndexResult :: Edge ( i ) ,
214
+ Ordering :: Equal => return IndexResult :: KV ( start_index + offset ) ,
215
+ Ordering :: Less => return IndexResult :: Edge ( start_index + offset ) ,
219
216
}
220
217
}
221
218
IndexResult :: Edge ( keys. len ( ) )
@@ -235,11 +232,11 @@ impl<BorrowType, K, V, Type> NodeRef<BorrowType, K, V, Type> {
235
232
K : Borrow < Q > ,
236
233
{
237
234
match bound {
238
- Included ( key) => match self . find_key_index ( key) {
235
+ Included ( key) => match unsafe { self . find_key_index ( key, 0 ) } {
239
236
IndexResult :: KV ( idx) => ( idx, AllExcluded ) ,
240
237
IndexResult :: Edge ( idx) => ( idx, bound) ,
241
238
} ,
242
- Excluded ( key) => match self . find_key_index ( key) {
239
+ Excluded ( key) => match unsafe { self . find_key_index ( key, 0 ) } {
243
240
IndexResult :: KV ( idx) => ( idx + 1 , AllIncluded ) ,
244
241
IndexResult :: Edge ( idx) => ( idx, bound) ,
245
242
} ,
@@ -248,26 +245,31 @@ impl<BorrowType, K, V, Type> NodeRef<BorrowType, K, V, Type> {
248
245
}
249
246
}
250
247
251
- /// Clone of `find_lower_bound_index` for the upper bound.
252
- fn find_upper_bound_index < ' r , Q > (
248
+ /// Mirror image of `find_lower_bound_index` for the upper bound,
249
+ /// with an additional parameter to skip part of the key array.
250
+ ///
251
+ /// # Safety
252
+ /// `start_index` must be a valid edge index for the node.
253
+ unsafe fn find_upper_bound_index < ' r , Q > (
253
254
& self ,
254
255
bound : SearchBound < & ' r Q > ,
256
+ start_index : usize ,
255
257
) -> ( usize , SearchBound < & ' r Q > )
256
258
where
257
259
Q : ?Sized + Ord ,
258
260
K : Borrow < Q > ,
259
261
{
260
262
match bound {
261
- Included ( key) => match self . find_key_index ( key) {
263
+ Included ( key) => match unsafe { self . find_key_index ( key, start_index ) } {
262
264
IndexResult :: KV ( idx) => ( idx + 1 , AllExcluded ) ,
263
265
IndexResult :: Edge ( idx) => ( idx, bound) ,
264
266
} ,
265
- Excluded ( key) => match self . find_key_index ( key) {
267
+ Excluded ( key) => match unsafe { self . find_key_index ( key, start_index ) } {
266
268
IndexResult :: KV ( idx) => ( idx, AllIncluded ) ,
267
269
IndexResult :: Edge ( idx) => ( idx, bound) ,
268
270
} ,
269
271
AllIncluded => ( self . len ( ) , AllIncluded ) ,
270
- AllExcluded => ( 0 , AllExcluded ) ,
272
+ AllExcluded => ( start_index , AllExcluded ) ,
271
273
}
272
274
}
273
275
}
0 commit comments