Skip to content

Commit

Permalink
Auto merge of #81083 - ssomers:btree_drainy_refactor_1, r=Mark-Simula…
Browse files Browse the repository at this point in the history
…crum

BTreeMap: expose new_internal function and sanitize from_new_internal

`new_internal` is the functional core of the imperative `push_internal_level`, and `from_new_internal` can easily do a proper job instead of returning a half-baked node.

r? `@Mark-Simulacrum`
  • Loading branch information
bors committed Jan 17, 2021
2 parents 49d7889 + d199c5b commit d51cf96
Show file tree
Hide file tree
Showing 2 changed files with 14 additions and 13 deletions.
21 changes: 12 additions & 9 deletions library/alloc/src/collections/btree/node.rs
Original file line number Diff line number Diff line change
Expand Up @@ -142,8 +142,17 @@ impl<K, V> NodeRef<marker::Owned, K, V, marker::Leaf> {
}

impl<K, V> NodeRef<marker::Owned, K, V, marker::Internal> {
fn new_internal(child: Root<K, V>) -> Self {
let mut new_node = Box::new(unsafe { InternalNode::new() });
new_node.edges[0].write(child.node);
NodeRef::from_new_internal(new_node, child.height + 1)
}

fn from_new_internal(internal: Box<InternalNode<K, V>>, height: usize) -> Self {
NodeRef { height, node: NonNull::from(Box::leak(internal)).cast(), _marker: PhantomData }
let node = NonNull::from(Box::leak(internal)).cast();
let mut this = NodeRef { height, node, _marker: PhantomData };
this.borrow_mut().correct_all_childrens_parent_links();
this
}
}

Expand All @@ -167,11 +176,7 @@ impl<K, V> NodeRef<marker::Owned, K, V, marker::LeafOrInternal> {
/// make that new node the root node, and return it. This increases the height by 1
/// and is the opposite of `pop_internal_level`.
pub fn push_internal_level(&mut self) -> NodeRef<marker::Mut<'_>, K, V, marker::Internal> {
let mut new_node = Box::new(unsafe { InternalNode::new() });
new_node.edges[0].write(self.node);
let mut new_root = NodeRef::from_new_internal(new_node, self.height + 1);
new_root.borrow_mut().first_edge().correct_parent_link();
*self = new_root.forget_type();
super::mem::take_mut(self, |old_root| NodeRef::new_internal(old_root).forget_type());

// `self.borrow_mut()`, except that we just forgot we're internal now:
NodeRef { height: self.height, node: self.node, _marker: PhantomData }
Expand Down Expand Up @@ -1193,9 +1198,7 @@ impl<'a, K: 'a, V: 'a> Handle<NodeRef<marker::Mut<'a>, K, V, marker::Internal>,
);

let height = self.node.height;
let mut right = NodeRef::from_new_internal(new_node, height);

right.borrow_mut().correct_childrens_parent_links(0..new_len + 1);
let right = NodeRef::from_new_internal(new_node, height);

SplitResult { left: self.node, kv, right }
}
Expand Down
6 changes: 2 additions & 4 deletions library/alloc/src/collections/btree/node/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -79,10 +79,8 @@ fn test_splitpoint() {
#[test]
fn test_partial_cmp_eq() {
let mut root1 = NodeRef::new_leaf();
let mut leaf1 = root1.borrow_mut();
leaf1.push(1, ());
let mut root1 = root1.forget_type();
root1.push_internal_level();
root1.borrow_mut().push(1, ());
let mut root1 = NodeRef::new_internal(root1.forget_type()).forget_type();
let root2 = Root::new();
root1.reborrow().assert_back_pointers();
root2.reborrow().assert_back_pointers();
Expand Down

0 comments on commit d51cf96

Please sign in to comment.