Skip to content

Commit 2df9277

Browse files
committed
BTreeMap: reuse NodeRef as Root, keep BoxedNode confined to edges
1 parent 17a4c43 commit 2df9277

File tree

6 files changed

+75
-72
lines changed

6 files changed

+75
-72
lines changed

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

+1-1
Original file line numberDiff line numberDiff line change
@@ -1418,7 +1418,7 @@ impl<K, V> IntoIterator for BTreeMap<K, V> {
14181418
fn into_iter(self) -> IntoIter<K, V> {
14191419
let mut me = ManuallyDrop::new(self);
14201420
if let Some(root) = me.root.take() {
1421-
let (f, b) = root.into_ref().full_range();
1421+
let (f, b) = root.full_range();
14221422

14231423
IntoIter { front: Some(f), back: Some(b), length: me.length }
14241424
} else {

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

+58-58
Original file line numberDiff line numberDiff line change
@@ -119,85 +119,83 @@ struct BoxedNode<K, V> {
119119
}
120120

121121
impl<K, V> BoxedNode<K, V> {
122-
fn from_leaf(node: Box<LeafNode<K, V>>) -> Self {
123-
BoxedNode { ptr: Box::into_unique(node) }
122+
fn from_owned(mut node: NonNull<LeafNode<K, V>>) -> Self {
123+
BoxedNode { ptr: unsafe { Unique::new_unchecked(node.as_mut()) } }
124124
}
125125

126-
fn from_internal(node: Box<InternalNode<K, V>>) -> Self {
127-
BoxedNode { ptr: Unique::from(&mut Box::leak(node).data) }
128-
}
129-
130-
fn as_ptr(&self) -> NonNull<LeafNode<K, V>> {
126+
fn as_nonnull(&self) -> NonNull<LeafNode<K, V>> {
131127
NonNull::from(self.ptr)
132128
}
133129
}
134130

135131
/// An owned tree.
136132
///
137133
/// Note that this does not have a destructor, and must be cleaned up manually.
138-
pub struct Root<K, V> {
139-
node: BoxedNode<K, V>,
140-
/// The number of levels below the root node.
141-
height: usize,
142-
}
134+
pub type Root<K, V> = NodeRef<marker::Owned, K, V, marker::LeafOrInternal>;
143135

144136
unsafe impl<K: Sync, V: Sync> Sync for Root<K, V> {}
145137
unsafe impl<K: Send, V: Send> Send for Root<K, V> {}
146138

147139
impl<K, V> Root<K, V> {
148-
/// Returns the number of levels below the root.
149-
pub fn height(&self) -> usize {
150-
self.height
140+
/// Returns a new root node that is initially empty.
141+
pub fn new_leaf() -> Self {
142+
Self::from_leaf(Box::new(unsafe { LeafNode::new() }))
151143
}
152144

153-
/// Returns a new owned tree, with its own root node that is initially empty.
154-
pub fn new_leaf() -> Self {
155-
Root { node: BoxedNode::from_leaf(Box::new(unsafe { LeafNode::new() })), height: 0 }
145+
fn from_leaf(leaf: Box<LeafNode<K, V>>) -> Self {
146+
NodeRef { height: 0, node: NonNull::from(Box::leak(leaf)), _marker: PhantomData }
147+
}
148+
149+
fn from_internal(internal: Box<InternalNode<K, V>>, height: usize) -> Self {
150+
NodeRef { height, node: NonNull::from(&mut Box::leak(internal).data), _marker: PhantomData }
156151
}
157152

158-
/// Borrows and returns an immutable reference to the node owned by the root.
153+
/// Reborrows the owned node as an immutable reference.
159154
pub fn node_as_ref(&self) -> NodeRef<marker::Immut<'_>, K, V, marker::LeafOrInternal> {
160-
NodeRef { height: self.height, node: self.node.as_ptr(), _marker: PhantomData }
155+
NodeRef { height: self.height, node: self.node, _marker: PhantomData }
161156
}
162157

163-
/// Borrows and returns a mutable reference to the node owned by the root.
158+
/// Reborrows the owned node as a mutable reference.
164159
pub fn node_as_mut(&mut self) -> NodeRef<marker::Mut<'_>, K, V, marker::LeafOrInternal> {
165-
NodeRef { height: self.height, node: self.node.as_ptr(), _marker: PhantomData }
160+
NodeRef { height: self.height, node: self.node, _marker: PhantomData }
166161
}
167162

168-
/// Borrows and returns a mutable reference to the leaf node owned by the root.
163+
/// Reborrows the owned leaf node as a mutable reference.
169164
/// # Safety
170-
/// The root node is a leaf.
165+
/// The owned node must be a leaf.
171166
unsafe fn leaf_node_as_mut(&mut self) -> NodeRef<marker::Mut<'_>, K, V, marker::Leaf> {
172167
debug_assert!(self.height == 0);
173-
NodeRef { height: self.height, node: self.node.as_ptr(), _marker: PhantomData }
168+
NodeRef { height: self.height, node: self.node, _marker: PhantomData }
174169
}
175170

176-
/// Borrows and returns a mutable reference to the internal node owned by the root.
171+
/// Reborrows the owned internal node as a mutable reference.
177172
/// # Safety
178-
/// The root node is not a leaf.
173+
/// The owned node must not be a leaf.
179174
unsafe fn internal_node_as_mut(&mut self) -> NodeRef<marker::Mut<'_>, K, V, marker::Internal> {
180175
debug_assert!(self.height > 0);
181-
NodeRef { height: self.height, node: self.node.as_ptr(), _marker: PhantomData }
176+
NodeRef { height: self.height, node: self.node, _marker: PhantomData }
182177
}
183178

179+
/// Reborrows the owned internal node as a slightly mutable reference.
184180
pub fn node_as_valmut(&mut self) -> NodeRef<marker::ValMut<'_>, K, V, marker::LeafOrInternal> {
185-
NodeRef { height: self.height, node: self.node.as_ptr(), _marker: PhantomData }
181+
NodeRef { height: self.height, node: self.node, _marker: PhantomData }
186182
}
187183

188-
pub fn into_ref(self) -> NodeRef<marker::Owned, K, V, marker::LeafOrInternal> {
189-
NodeRef { height: self.height, node: self.node.as_ptr(), _marker: PhantomData }
184+
/// Narrows the type-specific node reference to a type-agnostic pointer.
185+
fn into_boxed_node(self) -> BoxedNode<K, V> {
186+
BoxedNode::from_owned(self.node)
190187
}
191188

192189
/// Adds a new internal node with a single edge pointing to the previous root node,
193190
/// make that new node the root node, and return it. This increases the height by 1
194191
/// and is the opposite of `pop_internal_level`.
195192
pub fn push_internal_level(&mut self) -> NodeRef<marker::Mut<'_>, K, V, marker::Internal> {
196193
let mut new_node = Box::new(unsafe { InternalNode::new() });
197-
new_node.edges[0].write(unsafe { ptr::read(&mut self.node) });
198-
199-
self.node = BoxedNode::from_internal(new_node);
200-
self.height += 1;
194+
let new_height = self.height + 1;
195+
super::mem::take_mut(self, |root| {
196+
new_node.edges[0].write(root.into_boxed_node());
197+
Root::from_internal(new_node, new_height)
198+
});
201199

202200
unsafe {
203201
let mut ret = self.internal_node_as_mut();
@@ -218,15 +216,14 @@ impl<K, V> Root<K, V> {
218216
pub fn pop_internal_level(&mut self) {
219217
assert!(self.height > 0);
220218

221-
let top = self.node.ptr;
219+
let top = self.node;
222220

223-
let mut internal_node = unsafe { self.internal_node_as_mut() };
224-
self.node = unsafe { internal_node.as_internal_mut().edges[0].assume_init_read() };
225-
self.height -= 1;
221+
let internal_node = NodeRef { height: self.height, node: self.node, _marker: PhantomData };
222+
*self = internal_node.first_edge().descend();
226223
self.node_as_mut().as_leaf_mut().parent = None;
227224

228225
unsafe {
229-
Global.dealloc(NonNull::from(top).cast(), Layout::new::<InternalNode<K, V>>());
226+
Global.dealloc(top.cast(), Layout::new::<InternalNode<K, V>>());
230227
}
231228
}
232229
}
@@ -368,6 +365,10 @@ impl<BorrowType, K, V> NodeRef<BorrowType, K, V, marker::Internal> {
368365
}
369366

370367
impl<BorrowType, K, V, Type> NodeRef<BorrowType, K, V, Type> {
368+
fn from_boxed_node(edge: BoxedNode<K, V>, height: usize) -> Self {
369+
NodeRef { height, node: edge.as_nonnull(), _marker: PhantomData }
370+
}
371+
371372
/// Finds the parent of the current node. Returns `Ok(handle)` if the current
372373
/// node actually has a parent, where `handle` points to the edge of the parent
373374
/// that points to the current node. Returns `Err(self)` if the current node has
@@ -650,7 +651,7 @@ impl<'a, K: 'a, V: 'a> NodeRef<marker::Mut<'a>, K, V, marker::Internal> {
650651
unsafe {
651652
ptr::write(self.key_mut_at(idx), key);
652653
ptr::write(self.val_mut_at(idx), val);
653-
self.as_internal_mut().edges.get_unchecked_mut(idx + 1).write(edge.node);
654+
self.as_internal_mut().edges.get_unchecked_mut(idx + 1).write(edge.into_boxed_node());
654655
Handle::new_edge(self.reborrow_mut(), idx + 1).correct_parent_link();
655656
}
656657
}
@@ -664,7 +665,7 @@ impl<'a, K: 'a, V: 'a> NodeRef<marker::Mut<'a>, K, V, marker::Internal> {
664665
unsafe {
665666
slice_insert(self.keys_mut(), 0, key);
666667
slice_insert(self.vals_mut(), 0, val);
667-
slice_insert(self.edges_mut(), 0, edge.node);
668+
slice_insert(self.edges_mut(), 0, edge.into_boxed_node());
668669
}
669670

670671
self.as_leaf_mut().len += 1;
@@ -688,10 +689,10 @@ impl<'a, K: 'a, V: 'a> NodeRef<marker::Mut<'a>, K, V, marker::LeafOrInternal> {
688689
let edge = match self.reborrow_mut().force() {
689690
ForceResult::Leaf(_) => None,
690691
ForceResult::Internal(internal) => {
691-
let edge = ptr::read(internal.edge_at(idx + 1));
692-
let mut new_root = Root { node: edge, height: internal.height - 1 };
693-
new_root.node_as_mut().as_leaf_mut().parent = None;
694-
Some(new_root)
692+
let boxed_node = ptr::read(internal.edge_at(idx + 1));
693+
let mut edge = Root::from_boxed_node(boxed_node, internal.height - 1);
694+
edge.node_as_mut().as_leaf_mut().parent = None;
695+
Some(edge)
695696
}
696697
};
697698

@@ -714,13 +715,13 @@ impl<'a, K: 'a, V: 'a> NodeRef<marker::Mut<'a>, K, V, marker::LeafOrInternal> {
714715
let edge = match self.reborrow_mut().force() {
715716
ForceResult::Leaf(_) => None,
716717
ForceResult::Internal(mut internal) => {
717-
let edge = slice_remove(internal.edges_mut(), 0);
718-
let mut new_root = Root { node: edge, height: internal.height - 1 };
719-
new_root.node_as_mut().as_leaf_mut().parent = None;
718+
let boxed_node = slice_remove(internal.edges_mut(), 0);
719+
let mut edge = Root::from_boxed_node(boxed_node, internal.height - 1);
720+
edge.node_as_mut().as_leaf_mut().parent = None;
720721

721722
internal.correct_childrens_parent_links(0..old_len);
722723

723-
Some(new_root)
724+
Some(edge)
724725
}
725726
};
726727

@@ -984,7 +985,7 @@ impl<'a, K: 'a, V: 'a> Handle<NodeRef<marker::Mut<'a>, K, V, marker::Internal>,
984985
unsafe {
985986
slice_insert(self.node.keys_mut(), self.idx, key);
986987
slice_insert(self.node.vals_mut(), self.idx, val);
987-
slice_insert(self.node.edges_mut(), self.idx + 1, edge.node);
988+
slice_insert(self.node.edges_mut(), self.idx + 1, edge.into_boxed_node());
988989
self.node.as_leaf_mut().len += 1;
989990

990991
self.node.correct_childrens_parent_links((self.idx + 1)..=self.node.len());
@@ -1074,11 +1075,10 @@ impl<BorrowType, K, V> Handle<NodeRef<BorrowType, K, V, marker::Internal>, marke
10741075
// reference (Rust issue #73987) and invalidate any other references
10751076
// to or inside the array, should any be around.
10761077
let internal_node = self.node.as_internal_ptr();
1077-
NodeRef {
1078-
height: self.node.height - 1,
1079-
node: unsafe { (&*(*internal_node).edges.get_unchecked(self.idx).as_ptr()).as_ptr() },
1080-
_marker: PhantomData,
1081-
}
1078+
NodeRef::from_boxed_node(
1079+
unsafe { (*internal_node).edges.get_unchecked(self.idx).assume_init_read() },
1080+
self.node.height - 1,
1081+
)
10821082
}
10831083
}
10841084

@@ -1163,7 +1163,7 @@ impl<'a, K: 'a, V: 'a> Handle<NodeRef<marker::Mut<'a>, K, V, marker::Leaf>, mark
11631163

11641164
let (k, v) = self.split_leaf_data(&mut new_node);
11651165

1166-
let right = Root { node: BoxedNode::from_leaf(new_node), height: 0 };
1166+
let right = Root::from_leaf(new_node);
11671167
(self.node, k, v, right)
11681168
}
11691169
}
@@ -1215,7 +1215,7 @@ impl<'a, K: 'a, V: 'a> Handle<NodeRef<marker::Mut<'a>, K, V, marker::Internal>,
12151215
let (k, v) = self.split_leaf_data(&mut new_node.data);
12161216

12171217
let height = self.node.height;
1218-
let mut right = Root { node: BoxedNode::from_internal(new_node), height };
1218+
let mut right = Root::from_internal(new_node, height);
12191219

12201220
right.internal_node_as_mut().correct_childrens_parent_links(0..=new_len);
12211221

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

+2-2
Original file line numberDiff line numberDiff line change
@@ -134,8 +134,8 @@ fn test_partial_cmp_eq() {
134134
assert_eq!(top_edge_1.partial_cmp(&top_edge_2), None);
135135

136136
root1.pop_internal_level();
137-
unsafe { root1.into_ref().deallocate_and_ascend() };
138-
unsafe { root2.into_ref().deallocate_and_ascend() };
137+
unsafe { root1.deallocate_and_ascend() };
138+
unsafe { root2.deallocate_and_ascend() };
139139
}
140140

141141
#[test]

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

+2-2
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ impl<K, V> Root<K, V> {
99
K: Borrow<Q>,
1010
{
1111
debug_assert!(right_root.height() == 0);
12-
debug_assert!(right_root.node_as_ref().len() == 0);
12+
debug_assert!(right_root.len() == 0);
1313

1414
let left_root = self;
1515
for _ in 0..left_root.height() {
@@ -48,7 +48,7 @@ impl<K, V> Root<K, V> {
4848

4949
/// Removes empty levels on the top, but keeps an empty leaf if the entire tree is empty.
5050
fn fix_top(&mut self) {
51-
while self.height() > 0 && self.node_as_ref().len() == 0 {
51+
while self.height() > 0 && self.len() == 0 {
5252
self.pop_internal_level();
5353
}
5454
}

src/etc/gdb_providers.py

+10-7
Original file line numberDiff line numberDiff line change
@@ -207,25 +207,25 @@ def children(self):
207207
yield "borrow", self.borrow
208208

209209

210-
# Yields children (in a provider's sense of the word) for a tree headed by a BoxedNode.
210+
# Yields children (in a provider's sense of the word) for a tree headed by a node.
211211
# In particular, yields each key/value pair in the node and in any child nodes.
212-
def children_of_node(boxed_node, height):
212+
def children_of_node(node_ptr, height):
213213
def cast_to_internal(node):
214214
internal_type_name = node.type.target().name.replace("LeafNode", "InternalNode", 1)
215215
internal_type = lookup_type(internal_type_name)
216216
return node.cast(internal_type.pointer())
217217

218-
node_ptr = unwrap_unique_or_non_null(boxed_node["ptr"])
219218
leaf = node_ptr.dereference()
220219
keys = leaf["keys"]
221220
vals = leaf["vals"]
222221
edges = cast_to_internal(node_ptr)["edges"] if height > 0 else None
223-
length = int(leaf["len"])
222+
length = leaf["len"]
224223

225224
for i in xrange(0, length + 1):
226225
if height > 0:
227226
boxed_child_node = edges[i]["value"]["value"]
228-
for child in children_of_node(boxed_child_node, height - 1):
227+
child_node = unwrap_unique_or_non_null(boxed_child_node["ptr"])
228+
for child in children_of_node(child_node, height - 1):
229229
yield child
230230
if i < length:
231231
# Avoid "Cannot perform pointer math on incomplete type" on zero-sized arrays.
@@ -240,9 +240,12 @@ def children_of_map(map):
240240
root = map["root"]
241241
if root.type.name.startswith("core::option::Option<"):
242242
root = root.cast(gdb.lookup_type(root.type.name[21:-1]))
243-
boxed_root_node = root["node"]
243+
node_ptr = root["node"]
244+
if node_ptr.type.name.startswith("alloc::collections::btree::node::BoxedNode<"):
245+
node_ptr = node_ptr["ptr"]
246+
node_ptr = unwrap_unique_or_non_null(node_ptr)
244247
height = root["height"]
245-
for child in children_of_node(boxed_root_node, height):
248+
for child in children_of_node(node_ptr, height):
246249
yield child
247250

248251

src/test/debuginfo/pretty-std-collections.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -101,15 +101,15 @@ fn main() {
101101
btree_set.insert(i);
102102
}
103103

104-
let mut empty_btree_set: BTreeSet<i32> = BTreeSet::new();
104+
let empty_btree_set: BTreeSet<i32> = BTreeSet::new();
105105

106106
// BTreeMap
107107
let mut btree_map = BTreeMap::new();
108108
for i in 0..15 {
109109
btree_map.insert(i, i);
110110
}
111111

112-
let mut empty_btree_map: BTreeMap<i32, u32> = BTreeMap::new();
112+
let empty_btree_map: BTreeMap<i32, u32> = BTreeMap::new();
113113

114114
let mut option_btree_map: BTreeMap<bool, Option<bool>> = BTreeMap::new();
115115
option_btree_map.insert(false, None);

0 commit comments

Comments
 (0)