Skip to content

Commit 76c466a

Browse files
committed
BTreeMap: less sharing, more similarity between leaf and internal nodes
1 parent 7829e18 commit 76c466a

File tree

1 file changed

+36
-45
lines changed
  • library/alloc/src/collections/btree

1 file changed

+36
-45
lines changed

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

+36-45
Original file line numberDiff line numberDiff line change
@@ -611,7 +611,7 @@ impl<'a, K: 'a, V: 'a> NodeRef<marker::Mut<'a>, K, V, marker::Leaf> {
611611

612612
/// Adds a key/value pair to the beginning of the node.
613613
fn push_front(&mut self, key: K, val: V) {
614-
debug_assert!(self.len() < CAPACITY);
614+
assert!(self.len() < CAPACITY);
615615

616616
unsafe {
617617
slice_insert(self.keys_mut(), 0, key);
@@ -664,14 +664,7 @@ impl<'a, K: 'a, V: 'a> NodeRef<marker::Mut<'a>, K, V, marker::Internal> {
664664
unsafe {
665665
slice_insert(self.keys_mut(), 0, key);
666666
slice_insert(self.vals_mut(), 0, val);
667-
slice_insert(
668-
slice::from_raw_parts_mut(
669-
MaybeUninit::slice_as_mut_ptr(&mut self.as_internal_mut().edges),
670-
self.len() + 1,
671-
),
672-
0,
673-
edge.node,
674-
);
667+
slice_insert(self.edges_mut(), 0, edge.node);
675668
}
676669

677670
self.as_leaf_mut().len += 1;
@@ -921,33 +914,22 @@ fn splitpoint(edge_idx: usize) -> (usize, InsertionPlace) {
921914
}
922915
}
923916

924-
impl<'a, K: 'a, V: 'a, NodeType> Handle<NodeRef<marker::Mut<'a>, K, V, NodeType>, marker::Edge> {
925-
/// Helps implementations of `insert_fit` for a particular `NodeType`,
926-
/// by taking care of leaf data.
917+
impl<'a, K: 'a, V: 'a> Handle<NodeRef<marker::Mut<'a>, K, V, marker::Leaf>, marker::Edge> {
927918
/// Inserts a new key/value pair between the key/value pairs to the right and left of
928919
/// this edge. This method assumes that there is enough space in the node for the new
929920
/// pair to fit.
930-
fn leafy_insert_fit(&mut self, key: K, val: V) {
921+
///
922+
/// The returned pointer points to the inserted value.
923+
fn insert_fit(&mut self, key: K, val: V) -> *mut V {
931924
debug_assert!(self.node.len() < CAPACITY);
932925

933926
unsafe {
934927
slice_insert(self.node.keys_mut(), self.idx, key);
935928
slice_insert(self.node.vals_mut(), self.idx, val);
936-
937929
self.node.as_leaf_mut().len += 1;
938-
}
939-
}
940-
}
941930

942-
impl<'a, K: 'a, V: 'a> Handle<NodeRef<marker::Mut<'a>, K, V, marker::Leaf>, marker::Edge> {
943-
/// Inserts a new key/value pair between the key/value pairs to the right and left of
944-
/// this edge. This method assumes that there is enough space in the node for the new
945-
/// pair to fit.
946-
///
947-
/// The returned pointer points to the inserted value.
948-
fn insert_fit(&mut self, key: K, val: V) -> *mut V {
949-
self.leafy_insert_fit(key, val);
950-
unsafe { self.node.val_mut_at(self.idx) }
931+
self.node.val_mut_at(self.idx)
932+
}
951933
}
952934
}
953935

@@ -996,11 +978,14 @@ impl<'a, K: 'a, V: 'a> Handle<NodeRef<marker::Mut<'a>, K, V, marker::Internal>,
996978
/// between this edge and the key/value pair to the right of this edge. This method assumes
997979
/// that there is enough space in the node for the new pair to fit.
998980
fn insert_fit(&mut self, key: K, val: V, edge: Root<K, V>) {
981+
debug_assert!(self.node.len() < CAPACITY);
999982
debug_assert!(edge.height == self.node.height - 1);
1000983

1001984
unsafe {
985+
slice_insert(self.node.keys_mut(), self.idx, key);
986+
slice_insert(self.node.vals_mut(), self.idx, val);
1002987
slice_insert(self.node.edges_mut(), self.idx + 1, edge.node);
1003-
self.leafy_insert_fit(key, val);
988+
self.node.as_leaf_mut().len += 1;
1004989

1005990
self.node.correct_childrens_parent_links((self.idx + 1)..=self.node.len());
1006991
}
@@ -1131,15 +1116,21 @@ impl<'a, K: 'a, V: 'a, NodeType> Handle<NodeRef<marker::Mut<'a>, K, V, NodeType>
11311116
}
11321117

11331118
impl<'a, K: 'a, V: 'a, NodeType> Handle<NodeRef<marker::Mut<'a>, K, V, NodeType>, marker::KV> {
1119+
/// Helps implementations of `split` for a particular `NodeType`,
1120+
/// by calculating the length of the new node.
1121+
fn split_new_node_len(&self) -> usize {
1122+
debug_assert!(self.idx < self.node.len());
1123+
self.node.len() - self.idx - 1
1124+
}
1125+
11341126
/// Helps implementations of `split` for a particular `NodeType`,
11351127
/// by taking care of leaf data.
1136-
fn leafy_split(&mut self, new_node: &mut LeafNode<K, V>) -> (K, V, usize) {
1128+
fn split_leaf_data(&mut self, new_node: &mut LeafNode<K, V>) -> (K, V) {
1129+
let new_len = self.split_new_node_len();
11371130
unsafe {
11381131
let k = ptr::read(self.node.key_at(self.idx));
11391132
let v = ptr::read(self.node.val_at(self.idx));
11401133

1141-
let new_len = self.node.len() - self.idx - 1;
1142-
11431134
ptr::copy_nonoverlapping(
11441135
self.node.key_at(self.idx + 1),
11451136
MaybeUninit::slice_as_mut_ptr(&mut new_node.keys),
@@ -1153,15 +1144,15 @@ impl<'a, K: 'a, V: 'a, NodeType> Handle<NodeRef<marker::Mut<'a>, K, V, NodeType>
11531144

11541145
self.node.as_leaf_mut().len = self.idx as u16;
11551146
new_node.len = new_len as u16;
1156-
(k, v, new_len)
1147+
(k, v)
11571148
}
11581149
}
11591150
}
11601151

11611152
impl<'a, K: 'a, V: 'a> Handle<NodeRef<marker::Mut<'a>, K, V, marker::Leaf>, marker::KV> {
11621153
/// Splits the underlying node into three parts:
11631154
///
1164-
/// - The node is truncated to only contain the key/value pairs to the right of
1155+
/// - The node is truncated to only contain the key/value pairs to the left of
11651156
/// this handle.
11661157
/// - The key and value pointed to by this handle are extracted.
11671158
/// - All the key/value pairs to the right of this handle are put into a newly
@@ -1170,9 +1161,10 @@ impl<'a, K: 'a, V: 'a> Handle<NodeRef<marker::Mut<'a>, K, V, marker::Leaf>, mark
11701161
unsafe {
11711162
let mut new_node = Box::new(LeafNode::new());
11721163

1173-
let (k, v, _) = self.leafy_split(&mut new_node);
1164+
let (k, v) = self.split_leaf_data(&mut new_node);
11741165

1175-
(self.node, k, v, Root { node: BoxedNode::from_leaf(new_node), height: 0 })
1166+
let right = Root { node: BoxedNode::from_leaf(new_node), height: 0 };
1167+
(self.node, k, v, right)
11761168
}
11771169
}
11781170

@@ -1206,29 +1198,28 @@ impl<'a, K: 'a, V: 'a> Handle<NodeRef<marker::Mut<'a>, K, V, marker::Internal>,
12061198
/// Splits the underlying node into three parts:
12071199
///
12081200
/// - The node is truncated to only contain the edges and key/value pairs to the
1209-
/// right of this handle.
1201+
/// left of this handle.
12101202
/// - The key and value pointed to by this handle are extracted.
12111203
/// - All the edges and key/value pairs to the right of this handle are put into
12121204
/// a newly allocated node.
12131205
pub fn split(mut self) -> (NodeRef<marker::Mut<'a>, K, V, marker::Internal>, K, V, Root<K, V>) {
12141206
unsafe {
12151207
let mut new_node = Box::new(InternalNode::new());
1216-
1217-
let (k, v, new_len) = self.leafy_split(&mut new_node.data);
1218-
let height = self.node.height;
1219-
let old_node = &*self.node.as_internal_ptr();
1220-
1208+
// Move edges out before reducing length:
1209+
let new_len = self.split_new_node_len();
12211210
ptr::copy_nonoverlapping(
1222-
old_node.edges.as_ptr().add(self.idx + 1),
1223-
new_node.edges.as_mut_ptr(),
1211+
self.node.edge_at(self.idx + 1),
1212+
MaybeUninit::slice_as_mut_ptr(&mut new_node.edges),
12241213
new_len + 1,
12251214
);
1215+
let (k, v) = self.split_leaf_data(&mut new_node.data);
12261216

1227-
let mut new_root = Root { node: BoxedNode::from_internal(new_node), height };
1217+
let height = self.node.height;
1218+
let mut right = Root { node: BoxedNode::from_internal(new_node), height };
12281219

1229-
new_root.internal_node_as_mut().correct_childrens_parent_links(0..=new_len);
1220+
right.internal_node_as_mut().correct_childrens_parent_links(0..=new_len);
12301221

1231-
(self.node, k, v, new_root)
1222+
(self.node, k, v, right)
12321223
}
12331224
}
12341225

0 commit comments

Comments
 (0)