Skip to content

Commit b6c26c4

Browse files
committed
BTreeMap: avoid aliasing while handling underfull nodes
1 parent 7ca6e8f commit b6c26c4

File tree

7 files changed

+320
-203
lines changed

7 files changed

+320
-203
lines changed

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

+3-8
Original file line numberDiff line numberDiff line change
@@ -1094,20 +1094,15 @@ impl<K: Ord, V> BTreeMap<K, V> {
10941094
let mut cur_node = root.node_as_mut();
10951095
while let Internal(internal) = cur_node.force() {
10961096
// Check if right-most child is underfull.
1097-
let mut last_edge = internal.last_edge();
1098-
let right_child_len = last_edge.reborrow().descend().len();
1097+
let mut last_kv = internal.last_kv().consider_for_balancing();
1098+
let right_child_len = last_kv.right_child_len();
10991099
if right_child_len < MIN_LEN {
11001100
// We need to steal.
1101-
let mut last_kv = match last_edge.left_kv() {
1102-
Ok(left) => left,
1103-
Err(_) => unreachable!(),
1104-
};
11051101
last_kv.bulk_steal_left(MIN_LEN - right_child_len);
1106-
last_edge = last_kv.right_edge();
11071102
}
11081103

11091104
// Go further down.
1110-
cur_node = last_edge.descend();
1105+
cur_node = last_kv.into_right_child();
11111106
}
11121107
}
11131108

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)