@@ -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