Skip to content

Commit 0d1ceb8

Browse files
committed
BTreeMap: bundle the duplication of node references in navigate.rs
1 parent 85e355e commit 0d1ceb8

File tree

1 file changed

+16
-12
lines changed

1 file changed

+16
-12
lines changed

library/alloc/src/collections/btree/navigate.rs

+16-12
Original file line numberDiff line numberDiff line change
@@ -130,6 +130,16 @@ fn full_range<BorrowType, K, V>(
130130
}
131131
}
132132

133+
impl<BorrowType, K, V, Type> NodeRef<BorrowType, K, V, Type> {
134+
/// Duplicates a NodeRef, even for a non-immutable borrow type.
135+
/// # Safety
136+
/// Never visit the same KV twice, and never end up with overlapping
137+
/// value references.
138+
unsafe fn fork(self) -> (Self, Self) {
139+
unsafe { (ptr::read(&self), self) }
140+
}
141+
}
142+
133143
impl<'a, K: 'a, V: 'a> NodeRef<marker::Immut<'a>, K, V, marker::LeafOrInternal> {
134144
/// Creates a pair of leaf edges delimiting a specified range in or underneath a node.
135145
///
@@ -180,10 +190,8 @@ impl<'a, K: 'a, V: 'a> NodeRef<marker::ValMut<'a>, K, V, marker::LeafOrInternal>
180190
K: Borrow<Q>,
181191
R: RangeBounds<Q>,
182192
{
183-
// We duplicate the root NodeRef here -- we will never visit the same KV
184-
// twice, and never end up with overlapping value references.
185-
let self2 = unsafe { ptr::read(&self) };
186-
range_search(self, self2, range)
193+
let (self1, self2) = unsafe { self.fork() };
194+
range_search(self1, self2, range)
187195
}
188196

189197
/// Splits a unique reference into a pair of leaf edges delimiting the full range of the tree.
@@ -195,10 +203,8 @@ impl<'a, K: 'a, V: 'a> NodeRef<marker::ValMut<'a>, K, V, marker::LeafOrInternal>
195203
Handle<NodeRef<marker::ValMut<'a>, K, V, marker::Leaf>, marker::Edge>,
196204
Handle<NodeRef<marker::ValMut<'a>, K, V, marker::Leaf>, marker::Edge>,
197205
) {
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)
206+
let (self1, self2) = unsafe { self.fork() };
207+
full_range(self1, self2)
202208
}
203209
}
204210

@@ -212,10 +218,8 @@ impl<K, V> NodeRef<marker::Owned, K, V, marker::LeafOrInternal> {
212218
Handle<NodeRef<marker::Owned, K, V, marker::Leaf>, marker::Edge>,
213219
Handle<NodeRef<marker::Owned, K, V, marker::Leaf>, marker::Edge>,
214220
) {
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)
221+
let (self1, self2) = unsafe { self.fork() };
222+
full_range(self1, self2)
219223
}
220224
}
221225

0 commit comments

Comments
 (0)