@@ -76,9 +76,7 @@ impl<BorrowType: marker::BorrowType, K, V> NodeRef<BorrowType, K, V, marker::Lea
7676 /// If not found, returns an `Err` with the leaf edge matching the entire
7777 /// range.
7878 ///
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.
8280 ///
8381 /// The result is meaningful only if the tree is ordered by key.
8482 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
118116 let mut upper_bound = SearchBound :: from_range ( end) ;
119117 loop {
120118 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) } ;
129121 if lower_edge_idx < upper_edge_idx {
130122 return Ok ( (
131123 self ,
@@ -135,6 +127,7 @@ impl<BorrowType: marker::BorrowType, K, V> NodeRef<BorrowType, K, V, marker::Lea
135127 upper_child_bound,
136128 ) ) ;
137129 }
130+ debug_assert_eq ! ( lower_edge_idx, upper_edge_idx) ;
138131 let common_edge = unsafe { Handle :: new_edge ( self , lower_edge_idx) } ;
139132 match common_edge. force ( ) {
140133 Leaf ( common_edge) => return Err ( common_edge) ,
@@ -174,7 +167,7 @@ impl<BorrowType: marker::BorrowType, K, V> NodeRef<BorrowType, K, V, marker::Lea
174167 Q : ?Sized + Ord ,
175168 K : Borrow < Q > ,
176169 {
177- let ( edge_idx, bound) = self . find_upper_bound_index ( bound) ;
170+ let ( edge_idx, bound) = unsafe { self . find_upper_bound_index ( bound, 0 ) } ;
178171 let edge = unsafe { Handle :: new_edge ( self , edge_idx) } ;
179172 ( edge, bound)
180173 }
@@ -193,29 +186,33 @@ impl<BorrowType, K, V, Type> NodeRef<BorrowType, K, V, Type> {
193186 Q : Ord ,
194187 K : Borrow < Q > ,
195188 {
196- match self . find_key_index ( key) {
189+ match unsafe { self . find_key_index ( key, 0 ) } {
197190 IndexResult :: KV ( idx) => Found ( unsafe { Handle :: new_kv ( self , idx) } ) ,
198191 IndexResult :: Edge ( idx) => GoDown ( unsafe { Handle :: new_edge ( self , idx) } ) ,
199192 }
200193 }
201194
202195 /// 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 .
204197 ///
205198 /// The result is meaningful only if the tree is ordered by key, like the tree
206199 /// 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
208204 where
209205 Q : Ord ,
210206 K : Borrow < Q > ,
211207 {
212208 let node = self . reborrow ( ) ;
213209 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 ( ) {
215212 match key. cmp ( k. borrow ( ) ) {
216213 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 ) ,
219216 }
220217 }
221218 IndexResult :: Edge ( keys. len ( ) )
@@ -235,11 +232,11 @@ impl<BorrowType, K, V, Type> NodeRef<BorrowType, K, V, Type> {
235232 K : Borrow < Q > ,
236233 {
237234 match bound {
238- Included ( key) => match self . find_key_index ( key) {
235+ Included ( key) => match unsafe { self . find_key_index ( key, 0 ) } {
239236 IndexResult :: KV ( idx) => ( idx, AllExcluded ) ,
240237 IndexResult :: Edge ( idx) => ( idx, bound) ,
241238 } ,
242- Excluded ( key) => match self . find_key_index ( key) {
239+ Excluded ( key) => match unsafe { self . find_key_index ( key, 0 ) } {
243240 IndexResult :: KV ( idx) => ( idx + 1 , AllIncluded ) ,
244241 IndexResult :: Edge ( idx) => ( idx, bound) ,
245242 } ,
@@ -248,26 +245,31 @@ impl<BorrowType, K, V, Type> NodeRef<BorrowType, K, V, Type> {
248245 }
249246 }
250247
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 > (
253254 & self ,
254255 bound : SearchBound < & ' r Q > ,
256+ start_index : usize ,
255257 ) -> ( usize , SearchBound < & ' r Q > )
256258 where
257259 Q : ?Sized + Ord ,
258260 K : Borrow < Q > ,
259261 {
260262 match bound {
261- Included ( key) => match self . find_key_index ( key) {
263+ Included ( key) => match unsafe { self . find_key_index ( key, start_index ) } {
262264 IndexResult :: KV ( idx) => ( idx + 1 , AllExcluded ) ,
263265 IndexResult :: Edge ( idx) => ( idx, bound) ,
264266 } ,
265- Excluded ( key) => match self . find_key_index ( key) {
267+ Excluded ( key) => match unsafe { self . find_key_index ( key, start_index ) } {
266268 IndexResult :: KV ( idx) => ( idx, AllIncluded ) ,
267269 IndexResult :: Edge ( idx) => ( idx, bound) ,
268270 } ,
269271 AllIncluded => ( self . len ( ) , AllIncluded ) ,
270- AllExcluded => ( 0 , AllExcluded ) ,
272+ AllExcluded => ( start_index , AllExcluded ) ,
271273 }
272274 }
273275}
0 commit comments