Skip to content

Commit 80f84eb

Browse files
committed
Auto merge of #75058 - ssomers:btree_cleanup_insert_2, r=Mark-Simulacrum
Clarify reuse of a BTreeMap insert support function and treat split support likewise r? @Mark-Simulacrum
2 parents 60c2e8d + 532e7f4 commit 80f84eb

File tree

1 file changed

+42
-44
lines changed
  • library/alloc/src/collections/btree

1 file changed

+42
-44
lines changed

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

+42-44
Original file line numberDiff line numberDiff line change
@@ -819,13 +819,13 @@ impl<BorrowType, K, V, NodeType> Handle<NodeRef<BorrowType, K, V, NodeType>, mar
819819
}
820820
}
821821

822-
impl<'a, K, V> Handle<NodeRef<marker::Mut<'a>, K, V, marker::Leaf>, marker::Edge> {
822+
impl<'a, K, V, NodeType> Handle<NodeRef<marker::Mut<'a>, K, V, NodeType>, marker::Edge> {
823+
/// Helps implementations of `insert_fit` for a particular `NodeType`,
824+
/// by taking care of leaf data.
823825
/// Inserts a new key/value pair between the key/value pairs to the right and left of
824826
/// this edge. This method assumes that there is enough space in the node for the new
825827
/// pair to fit.
826-
///
827-
/// The returned pointer points to the inserted value.
828-
fn insert_fit(&mut self, key: K, val: V) -> *mut V {
828+
fn leafy_insert_fit(&mut self, key: K, val: V) {
829829
// Necessary for correctness, but in a private module
830830
debug_assert!(self.node.len() < CAPACITY);
831831

@@ -834,11 +834,23 @@ impl<'a, K, V> Handle<NodeRef<marker::Mut<'a>, K, V, marker::Leaf>, marker::Edge
834834
slice_insert(self.node.vals_mut(), self.idx, val);
835835

836836
(*self.node.as_leaf_mut()).len += 1;
837-
838-
self.node.vals_mut().get_unchecked_mut(self.idx)
839837
}
840838
}
839+
}
841840

841+
impl<'a, K, V> Handle<NodeRef<marker::Mut<'a>, K, V, marker::Leaf>, marker::Edge> {
842+
/// Inserts a new key/value pair between the key/value pairs to the right and left of
843+
/// this edge. This method assumes that there is enough space in the node for the new
844+
/// pair to fit.
845+
///
846+
/// The returned pointer points to the inserted value.
847+
fn insert_fit(&mut self, key: K, val: V) -> *mut V {
848+
self.leafy_insert_fit(key, val);
849+
unsafe { self.node.vals_mut().get_unchecked_mut(self.idx) }
850+
}
851+
}
852+
853+
impl<'a, K, V> Handle<NodeRef<marker::Mut<'a>, K, V, marker::Leaf>, marker::Edge> {
842854
/// Inserts a new key/value pair between the key/value pairs to the right and left of
843855
/// this edge. This method splits the node if there isn't enough room.
844856
///
@@ -880,14 +892,6 @@ impl<'a, K, V> Handle<NodeRef<marker::Mut<'a>, K, V, marker::Internal>, marker::
880892
}
881893
}
882894

883-
/// Unsafely asserts to the compiler some static information about whether the underlying
884-
/// node of this handle is a `Leaf` or an `Internal`.
885-
unsafe fn cast_unchecked<NewType>(
886-
&mut self,
887-
) -> Handle<NodeRef<marker::Mut<'_>, K, V, NewType>, marker::Edge> {
888-
unsafe { Handle::new_edge(self.node.cast_unchecked(), self.idx) }
889-
}
890-
891895
/// Inserts a new key/value pair and an edge that will go to the right of that new pair
892896
/// between this edge and the key/value pair to the right of this edge. This method assumes
893897
/// that there is enough space in the node for the new pair to fit.
@@ -897,8 +901,7 @@ impl<'a, K, V> Handle<NodeRef<marker::Mut<'a>, K, V, marker::Internal>, marker::
897901
debug_assert!(edge.height == self.node.height - 1);
898902

899903
unsafe {
900-
// This cast is a lie, but it allows us to reuse the key/value insertion logic.
901-
self.cast_unchecked::<marker::Leaf>().insert_fit(key, val);
904+
self.leafy_insert_fit(key, val);
902905

903906
slice_insert(
904907
slice::from_raw_parts_mut(
@@ -1030,18 +1033,11 @@ impl<'a, K, V, NodeType> Handle<NodeRef<marker::Mut<'a>, K, V, NodeType>, marker
10301033
}
10311034
}
10321035

1033-
impl<'a, K, V> Handle<NodeRef<marker::Mut<'a>, K, V, marker::Leaf>, marker::KV> {
1034-
/// Splits the underlying node into three parts:
1035-
///
1036-
/// - The node is truncated to only contain the key/value pairs to the right of
1037-
/// this handle.
1038-
/// - The key and value pointed to by this handle and extracted.
1039-
/// - All the key/value pairs to the right of this handle are put into a newly
1040-
/// allocated node.
1041-
pub fn split(mut self) -> (NodeRef<marker::Mut<'a>, K, V, marker::Leaf>, K, V, Root<K, V>) {
1036+
impl<'a, K, V, NodeType> Handle<NodeRef<marker::Mut<'a>, K, V, NodeType>, marker::KV> {
1037+
/// Helps implementations of `split` for a particular `NodeType`,
1038+
/// by taking care of leaf data.
1039+
fn leafy_split(&mut self, new_node: &mut LeafNode<K, V>) -> (K, V, usize) {
10421040
unsafe {
1043-
let mut new_node = Box::new(LeafNode::new());
1044-
10451041
let k = ptr::read(self.node.keys().get_unchecked(self.idx));
10461042
let v = ptr::read(self.node.vals().get_unchecked(self.idx));
10471043

@@ -1060,6 +1056,24 @@ impl<'a, K, V> Handle<NodeRef<marker::Mut<'a>, K, V, marker::Leaf>, marker::KV>
10601056

10611057
(*self.node.as_leaf_mut()).len = self.idx as u16;
10621058
new_node.len = new_len as u16;
1059+
(k, v, new_len)
1060+
}
1061+
}
1062+
}
1063+
1064+
impl<'a, K, V> Handle<NodeRef<marker::Mut<'a>, K, V, marker::Leaf>, marker::KV> {
1065+
/// Splits the underlying node into three parts:
1066+
///
1067+
/// - The node is truncated to only contain the key/value pairs to the right of
1068+
/// this handle.
1069+
/// - The key and value pointed to by this handle and extracted.
1070+
/// - All the key/value pairs to the right of this handle are put into a newly
1071+
/// allocated node.
1072+
pub fn split(mut self) -> (NodeRef<marker::Mut<'a>, K, V, marker::Leaf>, K, V, Root<K, V>) {
1073+
unsafe {
1074+
let mut new_node = Box::new(LeafNode::new());
1075+
1076+
let (k, v, _) = self.leafy_split(&mut new_node);
10631077

10641078
(self.node, k, v, Root { node: BoxedNode::from_leaf(new_node), height: 0 })
10651079
}
@@ -1091,31 +1105,15 @@ impl<'a, K, V> Handle<NodeRef<marker::Mut<'a>, K, V, marker::Internal>, marker::
10911105
unsafe {
10921106
let mut new_node = Box::new(InternalNode::new());
10931107

1094-
let k = ptr::read(self.node.keys().get_unchecked(self.idx));
1095-
let v = ptr::read(self.node.vals().get_unchecked(self.idx));
1096-
1108+
let (k, v, new_len) = self.leafy_split(&mut new_node.data);
10971109
let height = self.node.height;
1098-
let new_len = self.node.len() - self.idx - 1;
10991110

1100-
ptr::copy_nonoverlapping(
1101-
self.node.keys().as_ptr().add(self.idx + 1),
1102-
new_node.data.keys.as_mut_ptr() as *mut K,
1103-
new_len,
1104-
);
1105-
ptr::copy_nonoverlapping(
1106-
self.node.vals().as_ptr().add(self.idx + 1),
1107-
new_node.data.vals.as_mut_ptr() as *mut V,
1108-
new_len,
1109-
);
11101111
ptr::copy_nonoverlapping(
11111112
self.node.as_internal().edges.as_ptr().add(self.idx + 1),
11121113
new_node.edges.as_mut_ptr(),
11131114
new_len + 1,
11141115
);
11151116

1116-
(*self.node.as_leaf_mut()).len = self.idx as u16;
1117-
new_node.data.len = new_len as u16;
1118-
11191117
let mut new_root = Root { node: BoxedNode::from_internal(new_node), height };
11201118

11211119
for i in 0..(new_len + 1) {

0 commit comments

Comments
 (0)