Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

BTreeMap: type-specific variants of node_as_mut and cast_unchecked #77569

Merged
merged 1 commit into from
Oct 14, 2020
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
52 changes: 28 additions & 24 deletions library/alloc/src/collections/btree/node.rs
Original file line number Diff line number Diff line change
Expand Up @@ -170,6 +170,22 @@ impl<K, V> Root<K, V> {
NodeRef { height: self.height, node: self.node.as_ptr(), _marker: PhantomData }
}

/// Borrows and returns a mutable reference to the leaf node owned by the root.
/// # Safety
/// The root node is a leaf.
unsafe fn leaf_node_as_mut(&mut self) -> NodeRef<marker::Mut<'_>, K, V, marker::Leaf> {
debug_assert!(self.height == 0);
NodeRef { height: self.height, node: self.node.as_ptr(), _marker: PhantomData }
}

/// Borrows and returns a mutable reference to the internal node owned by the root.
/// # Safety
/// The root node is not a leaf.
unsafe fn internal_node_as_mut(&mut self) -> NodeRef<marker::Mut<'_>, K, V, marker::Internal> {
debug_assert!(self.height > 0);
NodeRef { height: self.height, node: self.node.as_ptr(), _marker: PhantomData }
}

pub fn node_as_valmut(&mut self) -> NodeRef<marker::ValMut<'_>, K, V, marker::LeafOrInternal> {
NodeRef { height: self.height, node: self.node.as_ptr(), _marker: PhantomData }
}
Expand All @@ -188,14 +204,11 @@ impl<K, V> Root<K, V> {
self.node = BoxedNode::from_internal(new_node);
self.height += 1;

let mut ret =
NodeRef { height: self.height, node: self.node.as_ptr(), _marker: PhantomData };

unsafe {
let mut ret = self.internal_node_as_mut();
ret.reborrow_mut().first_edge().correct_parent_link();
ret
}

ret
}

/// Removes the internal root node, using its first child as the new root node.
Expand All @@ -212,11 +225,8 @@ impl<K, V> Root<K, V> {

let top = self.node.ptr;

self.node = unsafe {
BoxedNode::from_ptr(
self.node_as_mut().cast_unchecked::<marker::Internal>().first_edge().descend().node,
)
};
let internal_node = unsafe { self.internal_node_as_mut() };
self.node = unsafe { BoxedNode::from_ptr(internal_node.first_edge().descend().node) };
self.height -= 1;
self.node_as_mut().as_leaf_mut().parent = None;

Expand Down Expand Up @@ -443,9 +453,9 @@ impl<K, V> NodeRef<marker::Owned, K, V, marker::LeafOrInternal> {
}

impl<'a, K, V, Type> NodeRef<marker::Mut<'a>, K, V, Type> {
/// Unsafely asserts to the compiler some static information about whether this
/// node is a `Leaf` or an `Internal`.
unsafe fn cast_unchecked<NewType>(self) -> NodeRef<marker::Mut<'a>, K, V, NewType> {
/// Unsafely asserts to the compiler the static information that this node is an `Internal`.
unsafe fn cast_to_internal_unchecked(self) -> NodeRef<marker::Mut<'a>, K, V, marker::Internal> {
debug_assert!(self.height > 0);
NodeRef { height: self.height, node: self.node, _marker: PhantomData }
}

Expand Down Expand Up @@ -943,10 +953,7 @@ impl<'a, K: 'a, V: 'a> Handle<NodeRef<marker::Mut<'a>, K, V, marker::Leaf>, mark
Handle::new_edge(left.reborrow_mut(), insert_idx)
},
InsertionPlace::Right(insert_idx) => unsafe {
Handle::new_edge(
right.node_as_mut().cast_unchecked::<marker::Leaf>(),
insert_idx,
)
Handle::new_edge(right.leaf_node_as_mut(), insert_idx)
},
};
let val_ptr = insertion_edge.insert_fit(key, val);
Expand Down Expand Up @@ -1006,10 +1013,7 @@ impl<'a, K: 'a, V: 'a> Handle<NodeRef<marker::Mut<'a>, K, V, marker::Internal>,
Handle::new_edge(left.reborrow_mut(), insert_idx)
},
InsertionPlace::Right(insert_idx) => unsafe {
Handle::new_edge(
right.node_as_mut().cast_unchecked::<marker::Internal>(),
insert_idx,
)
Handle::new_edge(right.internal_node_as_mut(), insert_idx)
},
};
insertion_edge.insert_fit(key, val, edge);
Expand Down Expand Up @@ -1205,7 +1209,7 @@ impl<'a, K: 'a, V: 'a> Handle<NodeRef<marker::Mut<'a>, K, V, marker::Internal>,

let mut new_root = Root { node: BoxedNode::from_internal(new_node), height };

new_root.node_as_mut().cast_unchecked().correct_childrens_parent_links(0..=new_len);
new_root.internal_node_as_mut().correct_childrens_parent_links(0..=new_len);

(self.node, k, v, new_root)
}
Expand Down Expand Up @@ -1258,8 +1262,8 @@ impl<'a, K: 'a, V: 'a> Handle<NodeRef<marker::Mut<'a>, K, V, marker::Internal>,
if self.node.height > 1 {
// SAFETY: the height of the nodes being merged is one below the height
// of the node of this edge, thus above zero, so they are internal.
let mut left_node = left_node.cast_unchecked::<marker::Internal>();
let right_node = right_node.cast_unchecked::<marker::Internal>();
let mut left_node = left_node.cast_to_internal_unchecked();
let right_node = right_node.cast_to_internal_unchecked();
ptr::copy_nonoverlapping(
right_node.edge_at(0),
left_node.edges_mut().as_mut_ptr().add(left_len + 1),
Expand Down