Skip to content

Commit 1b9daa6

Browse files
committedJun 16, 2022
Auto merge of rust-lang#98103 - exrook:btreemap-alloc, r=Amanieu
BTreeMap: Support custom allocators (v1.5) Related: rust-lang/wg-allocators#7 https://github.com/TimDiekmann/alloc-wg Blocked on: ~~rust-lang#77187~~ ~~rust-lang#78459~~ ~~rust-lang#95036~~ previous: rust-lang#77438
2 parents 5bc82c0 + 1f7023a commit 1b9daa6

File tree

12 files changed

+675
-348
lines changed

12 files changed

+675
-348
lines changed
 

‎library/alloc/src/collections/btree/append.rs

+13-7
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
use super::merge_iter::MergeIterInner;
22
use super::node::{self, Root};
3+
use core::alloc::Allocator;
34
use core::iter::FusedIterator;
45

56
impl<K, V> Root<K, V> {
@@ -14,22 +15,27 @@ impl<K, V> Root<K, V> {
1415
/// a `BTreeMap`, both iterators should produce keys in strictly ascending
1516
/// order, each greater than all keys in the tree, including any keys
1617
/// already in the tree upon entry.
17-
pub fn append_from_sorted_iters<I>(&mut self, left: I, right: I, length: &mut usize)
18-
where
18+
pub fn append_from_sorted_iters<I, A: Allocator>(
19+
&mut self,
20+
left: I,
21+
right: I,
22+
length: &mut usize,
23+
alloc: &A,
24+
) where
1925
K: Ord,
2026
I: Iterator<Item = (K, V)> + FusedIterator,
2127
{
2228
// We prepare to merge `left` and `right` into a sorted sequence in linear time.
2329
let iter = MergeIter(MergeIterInner::new(left, right));
2430

2531
// Meanwhile, we build a tree from the sorted sequence in linear time.
26-
self.bulk_push(iter, length)
32+
self.bulk_push(iter, length, alloc)
2733
}
2834

2935
/// Pushes all key-value pairs to the end of the tree, incrementing a
3036
/// `length` variable along the way. The latter makes it easier for the
3137
/// caller to avoid a leak when the iterator panicks.
32-
pub fn bulk_push<I>(&mut self, iter: I, length: &mut usize)
38+
pub fn bulk_push<I, A: Allocator>(&mut self, iter: I, length: &mut usize, alloc: &A)
3339
where
3440
I: Iterator<Item = (K, V)>,
3541
{
@@ -58,17 +64,17 @@ impl<K, V> Root<K, V> {
5864
}
5965
Err(_) => {
6066
// We are at the top, create a new root node and push there.
61-
open_node = self.push_internal_level();
67+
open_node = self.push_internal_level(alloc);
6268
break;
6369
}
6470
}
6571
}
6672

6773
// Push key-value pair and new right subtree.
6874
let tree_height = open_node.height() - 1;
69-
let mut right_tree = Root::new();
75+
let mut right_tree = Root::new(alloc);
7076
for _ in 0..tree_height {
71-
right_tree.push_internal_level();
77+
right_tree.push_internal_level(alloc);
7278
}
7379
open_node.push(key, value, right_tree);
7480

‎library/alloc/src/collections/btree/fix.rs

+31-23
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,15 @@
11
use super::map::MIN_LEN;
22
use super::node::{marker, ForceResult::*, Handle, LeftOrRight::*, NodeRef, Root};
3+
use core::alloc::Allocator;
34

45
impl<'a, K: 'a, V: 'a> NodeRef<marker::Mut<'a>, K, V, marker::LeafOrInternal> {
56
/// Stocks up a possibly underfull node by merging with or stealing from a
67
/// sibling. If successful but at the cost of shrinking the parent node,
78
/// returns that shrunk parent node. Returns an `Err` if the node is
89
/// an empty root.
9-
fn fix_node_through_parent(
10+
fn fix_node_through_parent<A: Allocator>(
1011
self,
12+
alloc: &A,
1113
) -> Result<Option<NodeRef<marker::Mut<'a>, K, V, marker::Internal>>, Self> {
1214
let len = self.len();
1315
if len >= MIN_LEN {
@@ -16,7 +18,7 @@ impl<'a, K: 'a, V: 'a> NodeRef<marker::Mut<'a>, K, V, marker::LeafOrInternal> {
1618
match self.choose_parent_kv() {
1719
Ok(Left(mut left_parent_kv)) => {
1820
if left_parent_kv.can_merge() {
19-
let parent = left_parent_kv.merge_tracking_parent();
21+
let parent = left_parent_kv.merge_tracking_parent(alloc);
2022
Ok(Some(parent))
2123
} else {
2224
left_parent_kv.bulk_steal_left(MIN_LEN - len);
@@ -25,7 +27,7 @@ impl<'a, K: 'a, V: 'a> NodeRef<marker::Mut<'a>, K, V, marker::LeafOrInternal> {
2527
}
2628
Ok(Right(mut right_parent_kv)) => {
2729
if right_parent_kv.can_merge() {
28-
let parent = right_parent_kv.merge_tracking_parent();
30+
let parent = right_parent_kv.merge_tracking_parent(alloc);
2931
Ok(Some(parent))
3032
} else {
3133
right_parent_kv.bulk_steal_right(MIN_LEN - len);
@@ -52,9 +54,9 @@ impl<'a, K: 'a, V: 'a> NodeRef<marker::Mut<'a>, K, V, marker::LeafOrInternal> {
5254
///
5355
/// This method does not expect ancestors to already be underfull upon entry
5456
/// and panics if it encounters an empty ancestor.
55-
pub fn fix_node_and_affected_ancestors(mut self) -> bool {
57+
pub fn fix_node_and_affected_ancestors<A: Allocator>(mut self, alloc: &A) -> bool {
5658
loop {
57-
match self.fix_node_through_parent() {
59+
match self.fix_node_through_parent(alloc) {
5860
Ok(Some(parent)) => self = parent.forget_type(),
5961
Ok(None) => return true,
6062
Err(_) => return false,
@@ -65,29 +67,29 @@ impl<'a, K: 'a, V: 'a> NodeRef<marker::Mut<'a>, K, V, marker::LeafOrInternal> {
6567

6668
impl<K, V> Root<K, V> {
6769
/// Removes empty levels on the top, but keeps an empty leaf if the entire tree is empty.
68-
pub fn fix_top(&mut self) {
70+
pub fn fix_top<A: Allocator>(&mut self, alloc: &A) {
6971
while self.height() > 0 && self.len() == 0 {
70-
self.pop_internal_level();
72+
self.pop_internal_level(alloc);
7173
}
7274
}
7375

7476
/// Stocks up or merge away any underfull nodes on the right border of the
7577
/// tree. The other nodes, those that are not the root nor a rightmost edge,
7678
/// must already have at least MIN_LEN elements.
77-
pub fn fix_right_border(&mut self) {
78-
self.fix_top();
79+
pub fn fix_right_border<A: Allocator>(&mut self, alloc: &A) {
80+
self.fix_top(alloc);
7981
if self.len() > 0 {
80-
self.borrow_mut().last_kv().fix_right_border_of_right_edge();
81-
self.fix_top();
82+
self.borrow_mut().last_kv().fix_right_border_of_right_edge(alloc);
83+
self.fix_top(alloc);
8284
}
8385
}
8486

8587
/// The symmetric clone of `fix_right_border`.
86-
pub fn fix_left_border(&mut self) {
87-
self.fix_top();
88+
pub fn fix_left_border<A: Allocator>(&mut self, alloc: &A) {
89+
self.fix_top(alloc);
8890
if self.len() > 0 {
89-
self.borrow_mut().first_kv().fix_left_border_of_left_edge();
90-
self.fix_top();
91+
self.borrow_mut().first_kv().fix_left_border_of_left_edge(alloc);
92+
self.fix_top(alloc);
9193
}
9294
}
9395

@@ -113,16 +115,16 @@ impl<K, V> Root<K, V> {
113115
}
114116

115117
impl<'a, K: 'a, V: 'a> Handle<NodeRef<marker::Mut<'a>, K, V, marker::LeafOrInternal>, marker::KV> {
116-
fn fix_left_border_of_left_edge(mut self) {
118+
fn fix_left_border_of_left_edge<A: Allocator>(mut self, alloc: &A) {
117119
while let Internal(internal_kv) = self.force() {
118-
self = internal_kv.fix_left_child().first_kv();
120+
self = internal_kv.fix_left_child(alloc).first_kv();
119121
debug_assert!(self.reborrow().into_node().len() > MIN_LEN);
120122
}
121123
}
122124

123-
fn fix_right_border_of_right_edge(mut self) {
125+
fn fix_right_border_of_right_edge<A: Allocator>(mut self, alloc: &A) {
124126
while let Internal(internal_kv) = self.force() {
125-
self = internal_kv.fix_right_child().last_kv();
127+
self = internal_kv.fix_right_child(alloc).last_kv();
126128
debug_assert!(self.reborrow().into_node().len() > MIN_LEN);
127129
}
128130
}
@@ -133,12 +135,15 @@ impl<'a, K: 'a, V: 'a> Handle<NodeRef<marker::Mut<'a>, K, V, marker::Internal>,
133135
/// provisions an extra element to allow merging its children in turn
134136
/// without becoming underfull.
135137
/// Returns the left child.
136-
fn fix_left_child(self) -> NodeRef<marker::Mut<'a>, K, V, marker::LeafOrInternal> {
138+
fn fix_left_child<A: Allocator>(
139+
self,
140+
alloc: &A,
141+
) -> NodeRef<marker::Mut<'a>, K, V, marker::LeafOrInternal> {
137142
let mut internal_kv = self.consider_for_balancing();
138143
let left_len = internal_kv.left_child_len();
139144
debug_assert!(internal_kv.right_child_len() >= MIN_LEN);
140145
if internal_kv.can_merge() {
141-
internal_kv.merge_tracking_child()
146+
internal_kv.merge_tracking_child(alloc)
142147
} else {
143148
// `MIN_LEN + 1` to avoid readjust if merge happens on the next level.
144149
let count = (MIN_LEN + 1).saturating_sub(left_len);
@@ -153,12 +158,15 @@ impl<'a, K: 'a, V: 'a> Handle<NodeRef<marker::Mut<'a>, K, V, marker::Internal>,
153158
/// provisions an extra element to allow merging its children in turn
154159
/// without becoming underfull.
155160
/// Returns wherever the right child ended up.
156-
fn fix_right_child(self) -> NodeRef<marker::Mut<'a>, K, V, marker::LeafOrInternal> {
161+
fn fix_right_child<A: Allocator>(
162+
self,
163+
alloc: &A,
164+
) -> NodeRef<marker::Mut<'a>, K, V, marker::LeafOrInternal> {
157165
let mut internal_kv = self.consider_for_balancing();
158166
let right_len = internal_kv.right_child_len();
159167
debug_assert!(internal_kv.left_child_len() >= MIN_LEN);
160168
if internal_kv.can_merge() {
161-
internal_kv.merge_tracking_child()
169+
internal_kv.merge_tracking_child(alloc)
162170
} else {
163171
// `MIN_LEN + 1` to avoid readjust if merge happens on the next level.
164172
let count = (MIN_LEN + 1).saturating_sub(right_len);

0 commit comments

Comments
 (0)
Please sign in to comment.