@@ -3,151 +3,112 @@ use core::ptr;
3
3
use super :: node:: { marker, ForceResult :: * , Handle , NodeRef } ;
4
4
use super :: unwrap_unchecked;
5
5
6
- macro_rules! def_next {
7
- { unsafe fn $name: ident : $next_kv: ident $next_edge: ident $initial_leaf_edge: ident } => {
8
- /// Given a leaf edge handle into an immutable tree, returns a handle to the next
9
- /// leaf edge and references to the key and value between these edges.
10
- /// Unsafe because the caller must ensure that the given leaf edge has a successor.
11
- unsafe fn $name <' a, K : ' a, V : ' a>(
12
- leaf_edge: Handle <NodeRef <marker:: Immut <' a>, K , V , marker:: Leaf >, marker:: Edge >,
13
- ) -> ( Handle <NodeRef <marker:: Immut <' a>, K , V , marker:: Leaf >, marker:: Edge >, & ' a K , & ' a V ) {
14
- let mut cur_handle = match leaf_edge. $next_kv( ) {
15
- Ok ( leaf_kv) => {
16
- let ( k, v) = leaf_kv. into_kv( ) ;
17
- let next_leaf_edge = leaf_kv. $next_edge( ) ;
18
- return ( next_leaf_edge, k, v) ;
19
- }
20
- Err ( last_edge) => {
21
- let next_level = last_edge. into_node( ) . ascend( ) . ok( ) ;
22
- unwrap_unchecked( next_level)
23
- }
24
- } ;
25
-
26
- loop {
27
- cur_handle = match cur_handle. $next_kv( ) {
28
- Ok ( internal_kv) => {
29
- let ( k, v) = internal_kv. into_kv( ) ;
30
- let next_internal_edge = internal_kv. $next_edge( ) ;
31
- let next_leaf_edge = next_internal_edge. descend( ) . $initial_leaf_edge( ) ;
32
- return ( next_leaf_edge, k, v) ;
33
- }
34
- Err ( last_edge) => {
35
- let next_level = last_edge. into_node( ) . ascend( ) . ok( ) ;
36
- unwrap_unchecked( next_level)
37
- }
38
- }
6
+ impl < BorrowType , K , V > Handle < NodeRef < BorrowType , K , V , marker:: Leaf > , marker:: Edge > {
7
+ /// Given a leaf edge handle, returns [`Result::Ok`] with a handle to the neighboring KV
8
+ /// on the right side, which is either in the same leaf node or in an ancestor node.
9
+ /// If the leaf edge is the last one in the tree, returns [`Result::Err`] with the root node.
10
+ pub fn next_kv (
11
+ self ,
12
+ ) -> Result <
13
+ Handle < NodeRef < BorrowType , K , V , marker:: LeafOrInternal > , marker:: KV > ,
14
+ NodeRef < BorrowType , K , V , marker:: LeafOrInternal > ,
15
+ > {
16
+ let mut edge = self . forget_node_type ( ) ;
17
+ loop {
18
+ edge = match edge. right_kv ( ) {
19
+ Ok ( internal_kv) => return Ok ( internal_kv) ,
20
+ Err ( last_edge) => match last_edge. into_node ( ) . ascend ( ) {
21
+ Ok ( parent_edge) => parent_edge. forget_node_type ( ) ,
22
+ Err ( root) => return Err ( root. forget_type ( ) ) ,
23
+ } ,
39
24
}
40
25
}
41
- } ;
42
- }
43
-
44
- macro_rules! def_next_mut {
45
- { unsafe fn $name: ident : $next_kv: ident $next_edge: ident $initial_leaf_edge: ident } => {
46
- /// Given a leaf edge handle into a mutable tree, returns handles to the next
47
- /// leaf edge and to the KV between these edges.
48
- /// Unsafe for two reasons:
49
- /// - the caller must ensure that the given leaf edge has a successor;
50
- /// - both returned handles represent mutable references into the same tree
51
- /// that can easily invalidate each other, even on immutable use.
52
- unsafe fn $name <' a, K : ' a, V : ' a>(
53
- leaf_edge: Handle <NodeRef <marker:: Mut <' a>, K , V , marker:: Leaf >, marker:: Edge >,
54
- ) -> ( Handle <NodeRef <marker:: Mut <' a>, K , V , marker:: Leaf >, marker:: Edge >,
55
- Handle <NodeRef <marker:: Mut <' a>, K , V , marker:: LeafOrInternal >, marker:: KV >) {
56
- let mut cur_handle = match leaf_edge. $next_kv( ) {
57
- Ok ( leaf_kv) => {
58
- let next_leaf_edge = ptr:: read( & leaf_kv) . $next_edge( ) ;
59
- return ( next_leaf_edge, leaf_kv. forget_node_type( ) ) ;
60
- }
61
- Err ( last_edge) => {
62
- let next_level = last_edge. into_node( ) . ascend( ) . ok( ) ;
63
- unwrap_unchecked( next_level)
64
- }
65
- } ;
26
+ }
66
27
67
- loop {
68
- cur_handle = match cur_handle. $next_kv( ) {
69
- Ok ( internal_kv) => {
70
- let next_internal_edge = ptr:: read( & internal_kv) . $next_edge( ) ;
71
- let next_leaf_edge = next_internal_edge. descend( ) . $initial_leaf_edge( ) ;
72
- return ( next_leaf_edge, internal_kv. forget_node_type( ) ) ;
73
- }
74
- Err ( last_edge) => {
75
- let next_level = last_edge. into_node( ) . ascend( ) . ok( ) ;
76
- unwrap_unchecked( next_level)
77
- }
78
- }
28
+ /// Given a leaf edge handle, returns [`Result::Ok`] with a handle to the neighboring KV
29
+ /// on the left side, which is either in the same leaf node or in an ancestor node.
30
+ /// If the leaf edge is the first one in the tree, returns [`Result::Err`] with the root node.
31
+ pub fn next_back_kv (
32
+ self ,
33
+ ) -> Result <
34
+ Handle < NodeRef < BorrowType , K , V , marker:: LeafOrInternal > , marker:: KV > ,
35
+ NodeRef < BorrowType , K , V , marker:: LeafOrInternal > ,
36
+ > {
37
+ let mut edge = self . forget_node_type ( ) ;
38
+ loop {
39
+ edge = match edge. left_kv ( ) {
40
+ Ok ( internal_kv) => return Ok ( internal_kv) ,
41
+ Err ( last_edge) => match last_edge. into_node ( ) . ascend ( ) {
42
+ Ok ( parent_edge) => parent_edge. forget_node_type ( ) ,
43
+ Err ( root) => return Err ( root. forget_type ( ) ) ,
44
+ } ,
79
45
}
80
46
}
81
- } ;
47
+ }
82
48
}
83
49
84
- macro_rules! def_next_dealloc {
85
- { unsafe fn $name: ident : $next_kv: ident $next_edge: ident $initial_leaf_edge: ident } => {
86
- /// Given a leaf edge handle into an owned tree, returns a handle to the next
87
- /// leaf edge and the key and value between these edges, while deallocating
88
- /// any node left behind.
50
+ macro_rules! def_next_kv_uncheched_dealloc {
51
+ { unsafe fn $name: ident : $adjacent_kv: ident } => {
52
+ /// Given a leaf edge handle into an owned tree, returns a handle to the next KV,
53
+ /// while deallocating any node left behind.
89
54
/// Unsafe for two reasons:
90
- /// - the caller must ensure that the given leaf edge has a successor;
91
- /// - the node pointed at by the given handle, and its ancestors, may be deallocated,
55
+ /// - The caller must ensure that the leaf edge is not the last one in the tree.
56
+ /// - The node pointed at by the given handle, and its ancestors, may be deallocated,
92
57
/// while the reference to those nodes in the surviving ancestors is left dangling;
93
- /// thus using the returned handle is dangerous.
58
+ /// thus using the returned handle to navigate further is dangerous.
94
59
unsafe fn $name <K , V >(
95
60
leaf_edge: Handle <NodeRef <marker:: Owned , K , V , marker:: Leaf >, marker:: Edge >,
96
- ) -> ( Handle <NodeRef <marker:: Owned , K , V , marker:: Leaf >, marker:: Edge >, K , V ) {
97
- let mut cur_handle = match leaf_edge. $next_kv( ) {
98
- Ok ( leaf_kv) => {
99
- let k = ptr:: read( leaf_kv. reborrow( ) . into_kv( ) . 0 ) ;
100
- let v = ptr:: read( leaf_kv. reborrow( ) . into_kv( ) . 1 ) ;
101
- let next_leaf_edge = leaf_kv. $next_edge( ) ;
102
- return ( next_leaf_edge, k, v) ;
103
- }
104
- Err ( last_edge) => {
105
- unwrap_unchecked( last_edge. into_node( ) . deallocate_and_ascend( ) )
106
- }
107
- } ;
108
-
61
+ ) -> Handle <NodeRef <marker:: Owned , K , V , marker:: LeafOrInternal >, marker:: KV > {
62
+ let mut edge = leaf_edge. forget_node_type( ) ;
109
63
loop {
110
- cur_handle = match cur_handle. $next_kv( ) {
111
- Ok ( internal_kv) => {
112
- let k = ptr:: read( internal_kv. reborrow( ) . into_kv( ) . 0 ) ;
113
- let v = ptr:: read( internal_kv. reborrow( ) . into_kv( ) . 1 ) ;
114
- let next_internal_edge = internal_kv. $next_edge( ) ;
115
- let next_leaf_edge = next_internal_edge. descend( ) . $initial_leaf_edge( ) ;
116
- return ( next_leaf_edge, k, v) ;
117
- }
64
+ edge = match edge. $adjacent_kv( ) {
65
+ Ok ( internal_kv) => return internal_kv,
118
66
Err ( last_edge) => {
119
- unwrap_unchecked( last_edge. into_node( ) . deallocate_and_ascend( ) )
67
+ let parent_edge = last_edge. into_node( ) . deallocate_and_ascend( ) ;
68
+ unwrap_unchecked( parent_edge) . forget_node_type( )
120
69
}
121
70
}
122
71
}
123
72
}
124
73
} ;
125
74
}
126
75
127
- def_next ! { unsafe fn next_unchecked: right_kv right_edge first_leaf_edge}
128
- def_next ! { unsafe fn next_back_unchecked: left_kv left_edge last_leaf_edge}
129
- def_next_mut ! { unsafe fn next_unchecked_mut: right_kv right_edge first_leaf_edge}
130
- def_next_mut ! { unsafe fn next_back_unchecked_mut: left_kv left_edge last_leaf_edge}
131
- def_next_dealloc ! { unsafe fn next_unchecked_deallocating: right_kv right_edge first_leaf_edge}
132
- def_next_dealloc ! { unsafe fn next_back_unchecked_deallocating: left_kv left_edge last_leaf_edge}
76
+ def_next_kv_uncheched_dealloc ! { unsafe fn next_kv_unchecked_dealloc: right_kv}
77
+ def_next_kv_uncheched_dealloc ! { unsafe fn next_back_kv_unchecked_dealloc: left_kv}
78
+
79
+ /// This replaces the value behind the `v` unique reference by calling the
80
+ /// relevant function.
81
+ ///
82
+ /// Safety: The change closure must not panic.
83
+ #[ inline]
84
+ unsafe fn replace < T , R > ( v : & mut T , change : impl FnOnce ( T ) -> ( T , R ) ) -> R {
85
+ let value = ptr:: read ( v) ;
86
+ let ( new_value, ret) = change ( value) ;
87
+ ptr:: write ( v, new_value) ;
88
+ ret
89
+ }
133
90
134
91
impl < ' a , K , V > Handle < NodeRef < marker:: Immut < ' a > , K , V , marker:: Leaf > , marker:: Edge > {
135
92
/// Moves the leaf edge handle to the next leaf edge and returns references to the
136
93
/// key and value in between.
137
94
/// Unsafe because the caller must ensure that the leaf edge is not the last one in the tree.
138
95
pub unsafe fn next_unchecked ( & mut self ) -> ( & ' a K , & ' a V ) {
139
- let ( next_edge, k, v) = next_unchecked ( * self ) ;
140
- * self = next_edge;
141
- ( k, v)
96
+ replace ( self , |leaf_edge| {
97
+ let kv = leaf_edge. next_kv ( ) ;
98
+ let kv = unwrap_unchecked ( kv. ok ( ) ) ;
99
+ ( kv. next_leaf_edge ( ) , kv. into_kv ( ) )
100
+ } )
142
101
}
143
102
144
103
/// Moves the leaf edge handle to the previous leaf edge and returns references to the
145
104
/// key and value in between.
146
105
/// Unsafe because the caller must ensure that the leaf edge is not the first one in the tree.
147
106
pub unsafe fn next_back_unchecked ( & mut self ) -> ( & ' a K , & ' a V ) {
148
- let ( next_edge, k, v) = next_back_unchecked ( * self ) ;
149
- * self = next_edge;
150
- ( k, v)
107
+ replace ( self , |leaf_edge| {
108
+ let kv = leaf_edge. next_back_kv ( ) ;
109
+ let kv = unwrap_unchecked ( kv. ok ( ) ) ;
110
+ ( kv. next_back_leaf_edge ( ) , kv. into_kv ( ) )
111
+ } )
151
112
}
152
113
}
153
114
@@ -158,8 +119,11 @@ impl<'a, K, V> Handle<NodeRef<marker::Mut<'a>, K, V, marker::Leaf>, marker::Edge
158
119
/// - The caller must ensure that the leaf edge is not the last one in the tree.
159
120
/// - Using the updated handle may well invalidate the returned references.
160
121
pub unsafe fn next_unchecked ( & mut self ) -> ( & ' a mut K , & ' a mut V ) {
161
- let ( next_edge, kv) = next_unchecked_mut ( ptr:: read ( self ) ) ;
162
- * self = next_edge;
122
+ let kv = replace ( self , |leaf_edge| {
123
+ let kv = leaf_edge. next_kv ( ) ;
124
+ let kv = unwrap_unchecked ( kv. ok ( ) ) ;
125
+ ( ptr:: read ( & kv) . next_leaf_edge ( ) , kv)
126
+ } ) ;
163
127
// Doing the descend (and perhaps another move) invalidates the references
164
128
// returned by `into_kv_mut`, so we have to do this last.
165
129
kv. into_kv_mut ( )
@@ -171,8 +135,11 @@ impl<'a, K, V> Handle<NodeRef<marker::Mut<'a>, K, V, marker::Leaf>, marker::Edge
171
135
/// - The caller must ensure that the leaf edge is not the first one in the tree.
172
136
/// - Using the updated handle may well invalidate the returned references.
173
137
pub unsafe fn next_back_unchecked ( & mut self ) -> ( & ' a mut K , & ' a mut V ) {
174
- let ( next_edge, kv) = next_back_unchecked_mut ( ptr:: read ( self ) ) ;
175
- * self = next_edge;
138
+ let kv = replace ( self , |leaf_edge| {
139
+ let kv = leaf_edge. next_back_kv ( ) ;
140
+ let kv = unwrap_unchecked ( kv. ok ( ) ) ;
141
+ ( ptr:: read ( & kv) . next_back_leaf_edge ( ) , kv)
142
+ } ) ;
176
143
// Doing the descend (and perhaps another move) invalidates the references
177
144
// returned by `into_kv_mut`, so we have to do this last.
178
145
kv. into_kv_mut ( )
@@ -192,9 +159,12 @@ impl<K, V> Handle<NodeRef<marker::Owned, K, V, marker::Leaf>, marker::Edge> {
192
159
/// if the two preconditions above hold.
193
160
/// - Using the updated handle may well invalidate the returned references.
194
161
pub unsafe fn next_unchecked ( & mut self ) -> ( K , V ) {
195
- let ( next_edge, k, v) = next_unchecked_deallocating ( ptr:: read ( self ) ) ;
196
- * self = next_edge;
197
- ( k, v)
162
+ replace ( self , |leaf_edge| {
163
+ let kv = next_kv_unchecked_dealloc ( leaf_edge) ;
164
+ let k = ptr:: read ( kv. reborrow ( ) . into_kv ( ) . 0 ) ;
165
+ let v = ptr:: read ( kv. reborrow ( ) . into_kv ( ) . 1 ) ;
166
+ ( kv. next_leaf_edge ( ) , ( k, v) )
167
+ } )
198
168
}
199
169
200
170
/// Moves the leaf edge handle to the previous leaf edge and returns the key
@@ -209,9 +179,12 @@ impl<K, V> Handle<NodeRef<marker::Owned, K, V, marker::Leaf>, marker::Edge> {
209
179
/// if the two preconditions above hold.
210
180
/// - Using the updated handle may well invalidate the returned references.
211
181
pub unsafe fn next_back_unchecked ( & mut self ) -> ( K , V ) {
212
- let ( next_edge, k, v) = next_back_unchecked_deallocating ( ptr:: read ( self ) ) ;
213
- * self = next_edge;
214
- ( k, v)
182
+ replace ( self , |leaf_edge| {
183
+ let kv = next_back_kv_unchecked_dealloc ( leaf_edge) ;
184
+ let k = ptr:: read ( kv. reborrow ( ) . into_kv ( ) . 0 ) ;
185
+ let v = ptr:: read ( kv. reborrow ( ) . into_kv ( ) . 1 ) ;
186
+ ( kv. next_back_leaf_edge ( ) , ( k, v) )
187
+ } )
215
188
}
216
189
}
217
190
@@ -242,3 +215,29 @@ impl<BorrowType, K, V> NodeRef<BorrowType, K, V, marker::LeafOrInternal> {
242
215
}
243
216
}
244
217
}
218
+
219
+ impl < BorrowType , K , V > Handle < NodeRef < BorrowType , K , V , marker:: LeafOrInternal > , marker:: KV > {
220
+ /// Returns the leaf edge closest to a KV for forward navigation.
221
+ pub fn next_leaf_edge ( self ) -> Handle < NodeRef < BorrowType , K , V , marker:: Leaf > , marker:: Edge > {
222
+ match self . force ( ) {
223
+ Leaf ( leaf_kv) => leaf_kv. right_edge ( ) ,
224
+ Internal ( internal_kv) => {
225
+ let next_internal_edge = internal_kv. right_edge ( ) ;
226
+ next_internal_edge. descend ( ) . first_leaf_edge ( )
227
+ }
228
+ }
229
+ }
230
+
231
+ /// Returns the leaf edge closest to a KV for backward navigation.
232
+ pub fn next_back_leaf_edge (
233
+ self ,
234
+ ) -> Handle < NodeRef < BorrowType , K , V , marker:: Leaf > , marker:: Edge > {
235
+ match self . force ( ) {
236
+ Leaf ( leaf_kv) => leaf_kv. left_edge ( ) ,
237
+ Internal ( internal_kv) => {
238
+ let next_internal_edge = internal_kv. left_edge ( ) ;
239
+ next_internal_edge. descend ( ) . last_leaf_edge ( )
240
+ }
241
+ }
242
+ }
243
+ }
0 commit comments