@@ -68,13 +68,16 @@ impl<BorrowType: marker::BorrowType, K, V> NodeRef<BorrowType, K, V, marker::Lea
6868 /// of the range is different from the edge matching the upper bound, i.e.,
6969 /// the nearest node that has at least one key contained in the range.
7070 ///
71- /// If found, returns an `Ok` with that node, the pair of edge indices in it
72- /// delimiting the range, and the corresponding pair of bounds for
73- /// continuing the search in the child nodes, in case the node is internal.
71+ /// If found, returns an `Ok` with that node, the strictly ascending pair of
72+ /// edge indices in the node delimiting the range, and the corresponding
73+ /// pair of bounds for continuing the search in the child nodes, in case
74+ /// the node is internal.
7475 ///
7576 /// If not found, returns an `Err` with the leaf edge matching the entire
7677 /// range.
7778 ///
79+ /// As a diagnostic service, panics if the range specifies impossible bounds.
80+ ///
7881 /// The result is meaningful only if the tree is ordered by key.
7982 pub fn search_tree_for_bifurcation < ' r , Q : ?Sized , R > (
8083 mut self ,
@@ -112,10 +115,8 @@ impl<BorrowType: marker::BorrowType, K, V> NodeRef<BorrowType, K, V, marker::Lea
112115 let mut upper_bound = SearchBound :: from_range ( end) ;
113116 loop {
114117 let ( lower_edge_idx, lower_child_bound) = self . find_lower_bound_index ( lower_bound) ;
115- let ( upper_edge_idx, upper_child_bound) = self . find_upper_bound_index ( upper_bound) ;
116- if lower_edge_idx > upper_edge_idx {
117- panic ! ( "Ord is ill-defined in BTreeMap range" )
118- }
118+ let ( upper_edge_idx, upper_child_bound) =
119+ unsafe { self . find_upper_bound_index ( upper_bound, lower_edge_idx) } ;
119120 if lower_edge_idx < upper_edge_idx {
120121 return Ok ( (
121122 self ,
@@ -125,6 +126,7 @@ impl<BorrowType: marker::BorrowType, K, V> NodeRef<BorrowType, K, V, marker::Lea
125126 upper_child_bound,
126127 ) ) ;
127128 }
129+ debug_assert_eq ! ( lower_edge_idx, upper_edge_idx) ;
128130 let common_edge = unsafe { Handle :: new_edge ( self , lower_edge_idx) } ;
129131 match common_edge. force ( ) {
130132 Leaf ( common_edge) => return Err ( common_edge) ,
@@ -164,7 +166,7 @@ impl<BorrowType: marker::BorrowType, K, V> NodeRef<BorrowType, K, V, marker::Lea
164166 Q : ?Sized + Ord ,
165167 K : Borrow < Q > ,
166168 {
167- let ( edge_idx, bound) = self . find_upper_bound_index ( bound) ;
169+ let ( edge_idx, bound) = unsafe { self . find_upper_bound_index ( bound, 0 ) } ;
168170 let edge = unsafe { Handle :: new_edge ( self , edge_idx) } ;
169171 ( edge, bound)
170172 }
@@ -183,29 +185,33 @@ impl<BorrowType, K, V, Type> NodeRef<BorrowType, K, V, Type> {
183185 Q : Ord ,
184186 K : Borrow < Q > ,
185187 {
186- match self . find_key_index ( key) {
188+ match unsafe { self . find_key_index ( key, 0 ) } {
187189 IndexResult :: KV ( idx) => Found ( unsafe { Handle :: new_kv ( self , idx) } ) ,
188190 IndexResult :: Edge ( idx) => GoDown ( unsafe { Handle :: new_edge ( self , idx) } ) ,
189191 }
190192 }
191193
192194 /// Returns either the KV index in the node at which the key (or an equivalent)
193- /// exists, or the edge index where the key belongs.
195+ /// exists, or the edge index where the key belongs, starting from a particular index .
194196 ///
195197 /// The result is meaningful only if the tree is ordered by key, like the tree
196198 /// in a `BTreeMap` is.
197- fn find_key_index < Q : ?Sized > ( & self , key : & Q ) -> IndexResult
199+ ///
200+ /// # Safety
201+ /// `start_index` must be a valid edge index for the node.
202+ unsafe fn find_key_index < Q : ?Sized > ( & self , key : & Q , start_index : usize ) -> IndexResult
198203 where
199204 Q : Ord ,
200205 K : Borrow < Q > ,
201206 {
202207 let node = self . reborrow ( ) ;
203208 let keys = node. keys ( ) ;
204- for ( i, k) in keys. iter ( ) . enumerate ( ) {
209+ debug_assert ! ( start_index <= keys. len( ) ) ;
210+ for ( offset, k) in unsafe { keys. get_unchecked ( start_index..) } . iter ( ) . enumerate ( ) {
205211 match key. cmp ( k. borrow ( ) ) {
206212 Ordering :: Greater => { }
207- Ordering :: Equal => return IndexResult :: KV ( i ) ,
208- Ordering :: Less => return IndexResult :: Edge ( i ) ,
213+ Ordering :: Equal => return IndexResult :: KV ( start_index + offset ) ,
214+ Ordering :: Less => return IndexResult :: Edge ( start_index + offset ) ,
209215 }
210216 }
211217 IndexResult :: Edge ( keys. len ( ) )
@@ -225,11 +231,11 @@ impl<BorrowType, K, V, Type> NodeRef<BorrowType, K, V, Type> {
225231 K : Borrow < Q > ,
226232 {
227233 match bound {
228- Included ( key) => match self . find_key_index ( key) {
234+ Included ( key) => match unsafe { self . find_key_index ( key, 0 ) } {
229235 IndexResult :: KV ( idx) => ( idx, AllExcluded ) ,
230236 IndexResult :: Edge ( idx) => ( idx, bound) ,
231237 } ,
232- Excluded ( key) => match self . find_key_index ( key) {
238+ Excluded ( key) => match unsafe { self . find_key_index ( key, 0 ) } {
233239 IndexResult :: KV ( idx) => ( idx + 1 , AllIncluded ) ,
234240 IndexResult :: Edge ( idx) => ( idx, bound) ,
235241 } ,
@@ -238,26 +244,31 @@ impl<BorrowType, K, V, Type> NodeRef<BorrowType, K, V, Type> {
238244 }
239245 }
240246
241- /// Clone of `find_lower_bound_index` for the upper bound.
242- fn find_upper_bound_index < ' r , Q > (
247+ /// Mirror image of `find_lower_bound_index` for the upper bound,
248+ /// with an additional parameter to skip part of the key array.
249+ ///
250+ /// # Safety
251+ /// `start_index` must be a valid edge index for the node.
252+ unsafe fn find_upper_bound_index < ' r , Q > (
243253 & self ,
244254 bound : SearchBound < & ' r Q > ,
255+ start_index : usize ,
245256 ) -> ( usize , SearchBound < & ' r Q > )
246257 where
247258 Q : ?Sized + Ord ,
248259 K : Borrow < Q > ,
249260 {
250261 match bound {
251- Included ( key) => match self . find_key_index ( key) {
262+ Included ( key) => match unsafe { self . find_key_index ( key, start_index ) } {
252263 IndexResult :: KV ( idx) => ( idx + 1 , AllExcluded ) ,
253264 IndexResult :: Edge ( idx) => ( idx, bound) ,
254265 } ,
255- Excluded ( key) => match self . find_key_index ( key) {
266+ Excluded ( key) => match unsafe { self . find_key_index ( key, start_index ) } {
256267 IndexResult :: KV ( idx) => ( idx, AllIncluded ) ,
257268 IndexResult :: Edge ( idx) => ( idx, bound) ,
258269 } ,
259270 AllIncluded => ( self . len ( ) , AllIncluded ) ,
260- AllExcluded => ( 0 , AllExcluded ) ,
271+ AllExcluded => ( start_index , AllExcluded ) ,
261272 }
262273 }
263274}
0 commit comments