Skip to content

Commit

Permalink
Auto merge of #98178 - RalfJung:btree-alloc, r=thomcc
Browse files Browse the repository at this point in the history
btree: avoid forcing the allocator to be a reference

The previous code forces the actual allocator used to be some `&A`. This generalizes the code to allow any `A: Copy`. If people truly want to use a reference, they can use `&A` themselves.

Fixes rust-lang/rust#98176
  • Loading branch information
bors committed Jun 18, 2022
2 parents d3cd707 + 315938c commit 81b0162
Show file tree
Hide file tree
Showing 10 changed files with 270 additions and 241 deletions.
12 changes: 6 additions & 6 deletions alloc/src/collections/btree/append.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,12 +15,12 @@ impl<K, V> Root<K, V> {
/// a `BTreeMap`, both iterators should produce keys in strictly ascending
/// order, each greater than all keys in the tree, including any keys
/// already in the tree upon entry.
pub fn append_from_sorted_iters<I, A: Allocator>(
pub fn append_from_sorted_iters<I, A: Allocator + Clone>(
&mut self,
left: I,
right: I,
length: &mut usize,
alloc: &A,
alloc: A,
) where
K: Ord,
I: Iterator<Item = (K, V)> + FusedIterator,
Expand All @@ -35,7 +35,7 @@ impl<K, V> Root<K, V> {
/// Pushes all key-value pairs to the end of the tree, incrementing a
/// `length` variable along the way. The latter makes it easier for the
/// caller to avoid a leak when the iterator panicks.
pub fn bulk_push<I, A: Allocator>(&mut self, iter: I, length: &mut usize, alloc: &A)
pub fn bulk_push<I, A: Allocator + Clone>(&mut self, iter: I, length: &mut usize, alloc: A)
where
I: Iterator<Item = (K, V)>,
{
Expand Down Expand Up @@ -64,17 +64,17 @@ impl<K, V> Root<K, V> {
}
Err(_) => {
// We are at the top, create a new root node and push there.
open_node = self.push_internal_level(alloc);
open_node = self.push_internal_level(alloc.clone());
break;
}
}
}

// Push key-value pair and new right subtree.
let tree_height = open_node.height() - 1;
let mut right_tree = Root::new(alloc);
let mut right_tree = Root::new(alloc.clone());
for _ in 0..tree_height {
right_tree.push_internal_level(alloc);
right_tree.push_internal_level(alloc.clone());
}
open_node.push(key, value, right_tree);

Expand Down
40 changes: 20 additions & 20 deletions alloc/src/collections/btree/fix.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,9 @@ impl<'a, K: 'a, V: 'a> NodeRef<marker::Mut<'a>, K, V, marker::LeafOrInternal> {
/// sibling. If successful but at the cost of shrinking the parent node,
/// returns that shrunk parent node. Returns an `Err` if the node is
/// an empty root.
fn fix_node_through_parent<A: Allocator>(
fn fix_node_through_parent<A: Allocator + Clone>(
self,
alloc: &A,
alloc: A,
) -> Result<Option<NodeRef<marker::Mut<'a>, K, V, marker::Internal>>, Self> {
let len = self.len();
if len >= MIN_LEN {
Expand Down Expand Up @@ -54,9 +54,9 @@ impl<'a, K: 'a, V: 'a> NodeRef<marker::Mut<'a>, K, V, marker::LeafOrInternal> {
///
/// This method does not expect ancestors to already be underfull upon entry
/// and panics if it encounters an empty ancestor.
pub fn fix_node_and_affected_ancestors<A: Allocator>(mut self, alloc: &A) -> bool {
pub fn fix_node_and_affected_ancestors<A: Allocator + Clone>(mut self, alloc: A) -> bool {
loop {
match self.fix_node_through_parent(alloc) {
match self.fix_node_through_parent(alloc.clone()) {
Ok(Some(parent)) => self = parent.forget_type(),
Ok(None) => return true,
Err(_) => return false,
Expand All @@ -67,28 +67,28 @@ impl<'a, K: 'a, V: 'a> NodeRef<marker::Mut<'a>, K, V, marker::LeafOrInternal> {

impl<K, V> Root<K, V> {
/// Removes empty levels on the top, but keeps an empty leaf if the entire tree is empty.
pub fn fix_top<A: Allocator>(&mut self, alloc: &A) {
pub fn fix_top<A: Allocator + Clone>(&mut self, alloc: A) {
while self.height() > 0 && self.len() == 0 {
self.pop_internal_level(alloc);
self.pop_internal_level(alloc.clone());
}
}

/// Stocks up or merge away any underfull nodes on the right border of the
/// tree. The other nodes, those that are not the root nor a rightmost edge,
/// must already have at least MIN_LEN elements.
pub fn fix_right_border<A: Allocator>(&mut self, alloc: &A) {
self.fix_top(alloc);
pub fn fix_right_border<A: Allocator + Clone>(&mut self, alloc: A) {
self.fix_top(alloc.clone());
if self.len() > 0 {
self.borrow_mut().last_kv().fix_right_border_of_right_edge(alloc);
self.borrow_mut().last_kv().fix_right_border_of_right_edge(alloc.clone());
self.fix_top(alloc);
}
}

/// The symmetric clone of `fix_right_border`.
pub fn fix_left_border<A: Allocator>(&mut self, alloc: &A) {
self.fix_top(alloc);
pub fn fix_left_border<A: Allocator + Clone>(&mut self, alloc: A) {
self.fix_top(alloc.clone());
if self.len() > 0 {
self.borrow_mut().first_kv().fix_left_border_of_left_edge(alloc);
self.borrow_mut().first_kv().fix_left_border_of_left_edge(alloc.clone());
self.fix_top(alloc);
}
}
Expand All @@ -115,16 +115,16 @@ impl<K, V> Root<K, V> {
}

impl<'a, K: 'a, V: 'a> Handle<NodeRef<marker::Mut<'a>, K, V, marker::LeafOrInternal>, marker::KV> {
fn fix_left_border_of_left_edge<A: Allocator>(mut self, alloc: &A) {
fn fix_left_border_of_left_edge<A: Allocator + Clone>(mut self, alloc: A) {
while let Internal(internal_kv) = self.force() {
self = internal_kv.fix_left_child(alloc).first_kv();
self = internal_kv.fix_left_child(alloc.clone()).first_kv();
debug_assert!(self.reborrow().into_node().len() > MIN_LEN);
}
}

fn fix_right_border_of_right_edge<A: Allocator>(mut self, alloc: &A) {
fn fix_right_border_of_right_edge<A: Allocator + Clone>(mut self, alloc: A) {
while let Internal(internal_kv) = self.force() {
self = internal_kv.fix_right_child(alloc).last_kv();
self = internal_kv.fix_right_child(alloc.clone()).last_kv();
debug_assert!(self.reborrow().into_node().len() > MIN_LEN);
}
}
Expand All @@ -135,9 +135,9 @@ impl<'a, K: 'a, V: 'a> Handle<NodeRef<marker::Mut<'a>, K, V, marker::Internal>,
/// provisions an extra element to allow merging its children in turn
/// without becoming underfull.
/// Returns the left child.
fn fix_left_child<A: Allocator>(
fn fix_left_child<A: Allocator + Clone>(
self,
alloc: &A,
alloc: A,
) -> NodeRef<marker::Mut<'a>, K, V, marker::LeafOrInternal> {
let mut internal_kv = self.consider_for_balancing();
let left_len = internal_kv.left_child_len();
Expand All @@ -158,9 +158,9 @@ impl<'a, K: 'a, V: 'a> Handle<NodeRef<marker::Mut<'a>, K, V, marker::Internal>,
/// provisions an extra element to allow merging its children in turn
/// without becoming underfull.
/// Returns wherever the right child ended up.
fn fix_right_child<A: Allocator>(
fn fix_right_child<A: Allocator + Clone>(
self,
alloc: &A,
alloc: A,
) -> NodeRef<marker::Mut<'a>, K, V, marker::LeafOrInternal> {
let mut internal_kv = self.consider_for_balancing();
let right_len = internal_kv.right_child_len();
Expand Down
Loading

0 comments on commit 81b0162

Please sign in to comment.