Skip to content

Commit 2758023

Browse files
committed
BTree: refactor clone, mostly for readability
1 parent 44593ae commit 2758023

File tree

5 files changed

+78
-71
lines changed

5 files changed

+78
-71
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
use super::node::{marker, NodeRef};
2+
3+
/// Simple tree around a raw `NodeRef`, that provides a destructor.
4+
/// Unlike smarter sister `BTreeMap`, it does not keep track of element count,
5+
/// does not allow replacing the root, therefore can be statically tyoed by the
6+
/// node type of the root, and cannot represent a tree without root node
7+
/// (its `Option` exists only to disable the `drop` method when needed).
8+
pub struct BareTree<K, V, RootType>(Option<NodeRef<marker::Owned, K, V, RootType>>);
9+
10+
impl<K, V, RootType> Drop for BareTree<K, V, RootType> {
11+
fn drop(&mut self) {
12+
if let Some(root) = self.0.take() {
13+
let mut cur_edge = root.forget_type().into_dying().first_leaf_edge();
14+
while let Some((next_edge, kv)) = unsafe { cur_edge.deallocating_next() } {
15+
unsafe { kv.drop_key_val() };
16+
cur_edge = next_edge;
17+
}
18+
}
19+
}
20+
}
21+
22+
impl<K, V> BareTree<K, V, marker::Leaf> {
23+
/// Returns a new tree consisting of a single leaf that is initially empty.
24+
pub fn new_leaf() -> Self {
25+
Self(Some(NodeRef::new_leaf()))
26+
}
27+
}
28+
29+
impl<K, V> BareTree<K, V, marker::Internal> {
30+
/// Returns a new tree with an internal root, that initially has no elements
31+
/// and one child.
32+
pub fn new_internal(child: NodeRef<marker::Owned, K, V, marker::LeafOrInternal>) -> Self {
33+
Self(Some(NodeRef::new_internal(child)))
34+
}
35+
}
36+
37+
impl<K, V, RootType> BareTree<K, V, RootType> {
38+
/// Mutably borrows the owned root node.
39+
pub fn borrow_mut(&mut self) -> NodeRef<marker::Mut<'_>, K, V, RootType> {
40+
self.0.as_mut().unwrap().borrow_mut()
41+
}
42+
43+
/// Removes any static information asserting that the root is a `Leaf` or
44+
/// `Internal` node.
45+
pub fn forget_root_type(mut self) -> BareTree<K, V, marker::LeafOrInternal> {
46+
BareTree(self.0.take().map(NodeRef::forget_type))
47+
}
48+
49+
/// Consumes the tree, returning a `NodeRef` that still enforces ownership
50+
/// but lacks a destructor.
51+
pub fn into_inner(mut self) -> NodeRef<marker::Owned, K, V, RootType> {
52+
self.0.take().unwrap()
53+
}
54+
}

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

+14-41
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ use core::mem::{self, ManuallyDrop};
99
use core::ops::{Index, RangeBounds};
1010
use core::ptr;
1111

12+
use super::bare_tree::BareTree;
1213
use super::borrow::DormantMutRef;
1314
use super::dedup_sorted_iter::DedupSortedIter;
1415
use super::navigate::{LazyLeafRange, LeafRange};
@@ -171,75 +172,47 @@ unsafe impl<#[may_dangle] K, #[may_dangle] V> Drop for BTreeMap<K, V> {
171172
#[stable(feature = "rust1", since = "1.0.0")]
172173
impl<K: Clone, V: Clone> Clone for BTreeMap<K, V> {
173174
fn clone(&self) -> BTreeMap<K, V> {
174-
fn clone_subtree<'a, K: Clone, V: Clone>(
175+
fn clone_subtree<'a, K: Clone + 'a, V: Clone + 'a>(
175176
node: NodeRef<marker::Immut<'a>, K, V, marker::LeafOrInternal>,
176-
) -> BTreeMap<K, V>
177-
where
178-
K: 'a,
179-
V: 'a,
180-
{
177+
) -> BareTree<K, V, marker::LeafOrInternal> {
181178
match node.force() {
182179
Leaf(leaf) => {
183-
let mut out_tree = BTreeMap { root: Some(Root::new()), length: 0 };
184-
180+
let mut out_tree = BareTree::new_leaf();
185181
{
186-
let root = out_tree.root.as_mut().unwrap(); // unwrap succeeds because we just wrapped
187-
let mut out_node = match root.borrow_mut().force() {
188-
Leaf(leaf) => leaf,
189-
Internal(_) => unreachable!(),
190-
};
191-
182+
let mut out_node = out_tree.borrow_mut();
192183
let mut in_edge = leaf.first_edge();
193184
while let Ok(kv) = in_edge.right_kv() {
194185
let (k, v) = kv.into_kv();
195186
in_edge = kv.right_edge();
196187

197188
out_node.push(k.clone(), v.clone());
198-
out_tree.length += 1;
199189
}
200190
}
201-
202-
out_tree
191+
out_tree.forget_root_type()
203192
}
204193
Internal(internal) => {
205-
let mut out_tree = clone_subtree(internal.first_edge().descend());
206-
194+
let mut in_edge = internal.first_edge();
195+
let first_child = clone_subtree(in_edge.descend());
196+
let mut out_tree = BareTree::new_internal(first_child.into_inner());
207197
{
208-
let out_root = BTreeMap::ensure_is_owned(&mut out_tree.root);
209-
let mut out_node = out_root.push_internal_level();
210-
let mut in_edge = internal.first_edge();
198+
let mut out_node = out_tree.borrow_mut();
211199
while let Ok(kv) = in_edge.right_kv() {
212200
let (k, v) = kv.into_kv();
213201
in_edge = kv.right_edge();
214202

215203
let k = (*k).clone();
216204
let v = (*v).clone();
217205
let subtree = clone_subtree(in_edge.descend());
218-
219-
// We can't destructure subtree directly
220-
// because BTreeMap implements Drop
221-
let (subroot, sublength) = unsafe {
222-
let subtree = ManuallyDrop::new(subtree);
223-
let root = ptr::read(&subtree.root);
224-
let length = subtree.length;
225-
(root, length)
226-
};
227-
228-
out_node.push(k, v, subroot.unwrap_or_else(Root::new));
229-
out_tree.length += 1 + sublength;
206+
out_node.push(k, v, subtree.into_inner());
230207
}
231208
}
232-
233-
out_tree
209+
out_tree.forget_root_type()
234210
}
235211
}
236212
}
237213

238-
if self.is_empty() {
239-
BTreeMap::new()
240-
} else {
241-
clone_subtree(self.root.as_ref().unwrap().reborrow()) // unwrap succeeds because not empty
242-
}
214+
let cloned_root = self.root.as_ref().map(|r| clone_subtree(r.reborrow()).into_inner());
215+
BTreeMap { root: cloned_root, length: self.length }
243216
}
244217
}
245218

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

+1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
mod append;
2+
mod bare_tree;
23
mod borrow;
34
mod dedup_sorted_iter;
45
mod fix;

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

+1-1
Original file line numberDiff line numberDiff line change
@@ -441,7 +441,7 @@ impl<K, V> Handle<NodeRef<marker::Dying, K, V, marker::Leaf>, marker::Edge> {
441441
/// `deallocating_next_back`.
442442
/// - The returned KV handle is only valid to access the key and value,
443443
/// and only valid until the next call to a `deallocating_` method.
444-
unsafe fn deallocating_next(
444+
pub unsafe fn deallocating_next(
445445
self,
446446
) -> Option<(Self, Handle<NodeRef<marker::Dying, K, V, marker::LeafOrInternal>, marker::KV>)>
447447
{

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

+8-29
Original file line numberDiff line numberDiff line change
@@ -213,7 +213,8 @@ unsafe impl<K: Send, V: Send, Type> Send for NodeRef<marker::Owned, K, V, Type>
213213
unsafe impl<K: Send, V: Send, Type> Send for NodeRef<marker::Dying, K, V, Type> {}
214214

215215
impl<K, V> NodeRef<marker::Owned, K, V, marker::Leaf> {
216-
fn new_leaf() -> Self {
216+
/// Returns a new owned leaf node, that is initially empty.
217+
pub fn new_leaf() -> Self {
217218
Self::from_new_leaf(LeafNode::new())
218219
}
219220

@@ -223,7 +224,8 @@ impl<K, V> NodeRef<marker::Owned, K, V, marker::Leaf> {
223224
}
224225

225226
impl<K, V> NodeRef<marker::Owned, K, V, marker::Internal> {
226-
fn new_internal(child: Root<K, V>) -> Self {
227+
/// Returns a new owned internal node, that initially has no elements and one child.
228+
pub fn new_internal(child: Root<K, V>) -> Self {
227229
let mut new_node = unsafe { InternalNode::new() };
228230
new_node.edges[0].write(child.node);
229231
unsafe { NodeRef::from_new_internal(new_node, child.height + 1) }
@@ -651,15 +653,8 @@ impl<'a, K: 'a, V: 'a> NodeRef<marker::Mut<'a>, K, V, marker::Internal> {
651653
}
652654
}
653655

654-
impl<BorrowType, K, V> NodeRef<BorrowType, K, V, marker::Leaf> {
655-
/// Removes any static information asserting that this node is a `Leaf` node.
656-
pub fn forget_type(self) -> NodeRef<BorrowType, K, V, marker::LeafOrInternal> {
657-
NodeRef { height: self.height, node: self.node, _marker: PhantomData }
658-
}
659-
}
660-
661-
impl<BorrowType, K, V> NodeRef<BorrowType, K, V, marker::Internal> {
662-
/// Removes any static information asserting that this node is an `Internal` node.
656+
impl<BorrowType, K, V, NodeType> NodeRef<BorrowType, K, V, NodeType> {
657+
/// Removes any static information asserting that this node is a `Leaf` or `Internal` node.
663658
pub fn forget_type(self) -> NodeRef<BorrowType, K, V, marker::LeafOrInternal> {
664659
NodeRef { height: self.height, node: self.node, _marker: PhantomData }
665660
}
@@ -1505,31 +1500,15 @@ impl<'a, K: 'a, V: 'a> BalancingContext<'a, K, V> {
15051500
}
15061501
}
15071502

1508-
impl<BorrowType, K, V> Handle<NodeRef<BorrowType, K, V, marker::Leaf>, marker::Edge> {
1509-
pub fn forget_node_type(
1510-
self,
1511-
) -> Handle<NodeRef<BorrowType, K, V, marker::LeafOrInternal>, marker::Edge> {
1512-
unsafe { Handle::new_edge(self.node.forget_type(), self.idx) }
1513-
}
1514-
}
1515-
1516-
impl<BorrowType, K, V> Handle<NodeRef<BorrowType, K, V, marker::Internal>, marker::Edge> {
1503+
impl<BorrowType, K, V, NodeType> Handle<NodeRef<BorrowType, K, V, NodeType>, marker::Edge> {
15171504
pub fn forget_node_type(
15181505
self,
15191506
) -> Handle<NodeRef<BorrowType, K, V, marker::LeafOrInternal>, marker::Edge> {
15201507
unsafe { Handle::new_edge(self.node.forget_type(), self.idx) }
15211508
}
15221509
}
15231510

1524-
impl<BorrowType, K, V> Handle<NodeRef<BorrowType, K, V, marker::Leaf>, marker::KV> {
1525-
pub fn forget_node_type(
1526-
self,
1527-
) -> Handle<NodeRef<BorrowType, K, V, marker::LeafOrInternal>, marker::KV> {
1528-
unsafe { Handle::new_kv(self.node.forget_type(), self.idx) }
1529-
}
1530-
}
1531-
1532-
impl<BorrowType, K, V> Handle<NodeRef<BorrowType, K, V, marker::Internal>, marker::KV> {
1511+
impl<BorrowType, K, V, NodeType> Handle<NodeRef<BorrowType, K, V, NodeType>, marker::KV> {
15331512
pub fn forget_node_type(
15341513
self,
15351514
) -> Handle<NodeRef<BorrowType, K, V, marker::LeafOrInternal>, marker::KV> {

0 commit comments

Comments
 (0)