@@ -104,34 +104,39 @@ where
104104 }
105105}
106106
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 ( ) ) ;
123126 }
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 ( ) )
127133 }
128- _ => unreachable ! ( "BTreeMap has different depths" ) ,
129- } ;
134+ }
130135 }
131136}
132137
133138impl < ' 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 .
135140 ///
136141 /// The result is meaningful only if the tree is ordered by key, like the tree
137142 /// in a `BTreeMap` is.
@@ -150,14 +155,15 @@ impl<'a, K: 'a, V: 'a> NodeRef<marker::Immut<'a>, K, V, marker::LeafOrInternal>
150155 range_search ( self , self , range)
151156 }
152157
153- /// Returns (self.first_leaf_edge(), self.last_leaf_edge()), but more efficiently .
158+ /// Finds the pair of leaf edges delimiting the entire tree .
154159 pub fn full_range (
155160 self ,
156161 ) -> (
157162 Handle < NodeRef < marker:: Immut < ' a > , K , V , marker:: Leaf > , marker:: Edge > ,
158163 Handle < NodeRef < marker:: Immut < ' a > , K , V , marker:: Leaf > , marker:: Edge > ,
159164 ) {
160- full_range ( self , self )
165+ // SAFETY: our borrow type is `Immut`.
166+ unsafe { self . find_leaf_edges_spanning_tree ( ) }
161167 }
162168}
163169
@@ -195,10 +201,9 @@ impl<'a, K: 'a, V: 'a> NodeRef<marker::ValMut<'a>, K, V, marker::LeafOrInternal>
195201 Handle < NodeRef < marker:: ValMut < ' a > , K , V , marker:: Leaf > , marker:: Edge > ,
196202 Handle < NodeRef < marker:: ValMut < ' a > , K , V , marker:: Leaf > , marker:: Edge > ,
197203 ) {
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 ( ) }
202207 }
203208}
204209
@@ -212,10 +217,9 @@ impl<K, V> NodeRef<marker::Owned, K, V, marker::LeafOrInternal> {
212217 Handle < NodeRef < marker:: Owned , K , V , marker:: Leaf > , marker:: Edge > ,
213218 Handle < NodeRef < marker:: Owned , K , V , marker:: Leaf > , marker:: Edge > ,
214219 ) {
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 ( ) }
219223 }
220224}
221225
0 commit comments