Skip to content

Commit 4cfa5bd

Browse files
committed
BTreeMap: avoid aliasing while handling underfull nodes
1 parent 55794e4 commit 4cfa5bd

File tree

7 files changed

+320
-203
lines changed

7 files changed

+320
-203
lines changed

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

+3-8
Original file line numberDiff line numberDiff line change
@@ -89,20 +89,15 @@ impl<K, V> Root<K, V> {
8989
let mut cur_node = self.node_as_mut();
9090
while let Internal(internal) = cur_node.force() {
9191
// Check if right-most child is underfull.
92-
let mut last_edge = internal.last_edge();
93-
let right_child_len = last_edge.reborrow().descend().len();
92+
let mut last_kv = internal.last_kv().consider_for_balancing();
93+
let right_child_len = last_kv.right_child_len();
9494
if right_child_len < MIN_LEN {
9595
// We need to steal.
96-
let mut last_kv = match last_edge.left_kv() {
97-
Ok(left) => left,
98-
Err(_) => unreachable!(),
99-
};
10096
last_kv.bulk_steal_left(MIN_LEN - right_child_len);
101-
last_edge = last_kv.right_edge();
10297
}
10398

10499
// Go further down.
105-
cur_node = last_edge.descend();
100+
cur_node = last_kv.into_right_child();
106101
}
107102
}
108103
}

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

+1
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ use core::ptr;
66
/// relevant function.
77
///
88
/// If a panic occurs in the `change` closure, the entire process will be aborted.
9+
#[allow(dead_code)] // keep as illustration and for future use
910
#[inline]
1011
pub fn take_mut<T>(v: &mut T, change: impl FnOnce(T) -> T) {
1112
replace(v, |value| (change(value), ()))

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

-14
Original file line numberDiff line numberDiff line change
@@ -362,20 +362,6 @@ impl<'a, K, V> Handle<NodeRef<marker::ValMut<'a>, K, V, marker::Leaf>, marker::E
362362
}
363363
}
364364

365-
impl<'a, K, V> Handle<NodeRef<marker::Mut<'a>, K, V, marker::Leaf>, marker::Edge> {
366-
/// Moves the leaf edge handle to the next leaf edge.
367-
///
368-
/// # Safety
369-
/// There must be another KV in the direction travelled.
370-
pub unsafe fn move_next_unchecked(&mut self) {
371-
super::mem::take_mut(self, |leaf_edge| {
372-
let kv = leaf_edge.next_kv();
373-
let kv = unsafe { unwrap_unchecked(kv.ok()) };
374-
kv.next_leaf_edge()
375-
})
376-
}
377-
}
378-
379365
impl<K, V> Handle<NodeRef<marker::Owned, K, V, marker::Leaf>, marker::Edge> {
380366
/// Moves the leaf edge handle to the next leaf edge and returns the key and value
381367
/// in between, deallocating any node left behind while leaving the corresponding

0 commit comments

Comments
 (0)