Skip to content

Commit 73f233b

Browse files
committed
Auto merge of #81159 - ssomers:btree_cleanup_search, r=Mark-Simulacrum
BTreeMap: convert search functions to methods And further tweak the signature of `search_linear`, in preparation of a better #81094. r? `@Mark-Simulacrum`
2 parents 5e91c4e + de6e53a commit 73f233b

File tree

4 files changed

+83
-83
lines changed

4 files changed

+83
-83
lines changed

Diff for: library/alloc/src/collections/btree/map.rs

+9-9
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ use core::ptr;
1010

1111
use super::borrow::DormantMutRef;
1212
use super::node::{self, marker, ForceResult::*, Handle, NodeRef, Root};
13-
use super::search::{self, SearchResult::*};
13+
use super::search::SearchResult::*;
1414
use super::unwrap_unchecked;
1515

1616
mod entry;
@@ -230,7 +230,7 @@ where
230230

231231
fn get(&self, key: &Q) -> Option<&K> {
232232
let root_node = self.root.as_ref()?.reborrow();
233-
match search::search_tree(root_node, key) {
233+
match root_node.search_tree(key) {
234234
Found(handle) => Some(handle.into_kv().0),
235235
GoDown(_) => None,
236236
}
@@ -239,7 +239,7 @@ where
239239
fn take(&mut self, key: &Q) -> Option<K> {
240240
let (map, dormant_map) = DormantMutRef::new(self);
241241
let root_node = map.root.as_mut()?.borrow_mut();
242-
match search::search_tree(root_node, key) {
242+
match root_node.search_tree(key) {
243243
Found(handle) => {
244244
Some(OccupiedEntry { handle, dormant_map, _marker: PhantomData }.remove_kv().0)
245245
}
@@ -250,7 +250,7 @@ where
250250
fn replace(&mut self, key: K) -> Option<K> {
251251
let (map, dormant_map) = DormantMutRef::new(self);
252252
let root_node = Self::ensure_is_owned(&mut map.root).borrow_mut();
253-
match search::search_tree::<marker::Mut<'_>, K, (), K>(root_node, &key) {
253+
match root_node.search_tree::<K>(&key) {
254254
Found(mut kv) => Some(mem::replace(kv.key_mut(), key)),
255255
GoDown(handle) => {
256256
VacantEntry { key, handle, dormant_map, _marker: PhantomData }.insert(());
@@ -526,7 +526,7 @@ impl<K: Ord, V> BTreeMap<K, V> {
526526
Q: Ord,
527527
{
528528
let root_node = self.root.as_ref()?.reborrow();
529-
match search::search_tree(root_node, key) {
529+
match root_node.search_tree(key) {
530530
Found(handle) => Some(handle.into_kv().1),
531531
GoDown(_) => None,
532532
}
@@ -554,7 +554,7 @@ impl<K: Ord, V> BTreeMap<K, V> {
554554
Q: Ord,
555555
{
556556
let root_node = self.root.as_ref()?.reborrow();
557-
match search::search_tree(root_node, k) {
557+
match root_node.search_tree(k) {
558558
Found(handle) => Some(handle.into_kv()),
559559
GoDown(_) => None,
560560
}
@@ -762,7 +762,7 @@ impl<K: Ord, V> BTreeMap<K, V> {
762762
Q: Ord,
763763
{
764764
let root_node = self.root.as_mut()?.borrow_mut();
765-
match search::search_tree(root_node, key) {
765+
match root_node.search_tree(key) {
766766
Found(handle) => Some(handle.into_val_mut()),
767767
GoDown(_) => None,
768768
}
@@ -858,7 +858,7 @@ impl<K: Ord, V> BTreeMap<K, V> {
858858
{
859859
let (map, dormant_map) = DormantMutRef::new(self);
860860
let root_node = map.root.as_mut()?.borrow_mut();
861-
match search::search_tree(root_node, key) {
861+
match root_node.search_tree(key) {
862862
Found(handle) => {
863863
Some(OccupiedEntry { handle, dormant_map, _marker: PhantomData }.remove_entry())
864864
}
@@ -1051,7 +1051,7 @@ impl<K: Ord, V> BTreeMap<K, V> {
10511051
// FIXME(@porglezomp) Avoid allocating if we don't insert
10521052
let (map, dormant_map) = DormantMutRef::new(self);
10531053
let root_node = Self::ensure_is_owned(&mut map.root).borrow_mut();
1054-
match search::search_tree(root_node, &key) {
1054+
match root_node.search_tree(&key) {
10551055
Found(handle) => Occupied(OccupiedEntry { handle, dormant_map, _marker: PhantomData }),
10561056
GoDown(handle) => {
10571057
Vacant(VacantEntry { key, handle, dormant_map, _marker: PhantomData })

Diff for: library/alloc/src/collections/btree/navigate.rs

+5-5
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ use core::ops::RangeBounds;
55
use core::ptr;
66

77
use super::node::{marker, ForceResult::*, Handle, NodeRef};
8-
use super::search::{self, SearchResult};
8+
use super::search::SearchResult;
99
use super::unwrap_unchecked;
1010

1111
/// Finds the leaf edges delimiting a specified range in or underneath a node.
@@ -42,14 +42,14 @@ where
4242

4343
loop {
4444
let front = match (min_found, range.start_bound()) {
45-
(false, Included(key)) => match search::search_node(min_node, key) {
45+
(false, Included(key)) => match min_node.search_node(key) {
4646
SearchResult::Found(kv) => {
4747
min_found = true;
4848
kv.left_edge()
4949
}
5050
SearchResult::GoDown(edge) => edge,
5151
},
52-
(false, Excluded(key)) => match search::search_node(min_node, key) {
52+
(false, Excluded(key)) => match min_node.search_node(key) {
5353
SearchResult::Found(kv) => {
5454
min_found = true;
5555
kv.right_edge()
@@ -62,14 +62,14 @@ where
6262
};
6363

6464
let back = match (max_found, range.end_bound()) {
65-
(false, Included(key)) => match search::search_node(max_node, key) {
65+
(false, Included(key)) => match max_node.search_node(key) {
6666
SearchResult::Found(kv) => {
6767
max_found = true;
6868
kv.right_edge()
6969
}
7070
SearchResult::GoDown(edge) => edge,
7171
},
72-
(false, Excluded(key)) => match search::search_node(max_node, key) {
72+
(false, Excluded(key)) => match max_node.search_node(key) {
7373
SearchResult::Found(kv) => {
7474
max_found = true;
7575
kv.left_edge()

Diff for: library/alloc/src/collections/btree/search.rs

+67-67
Original file line numberDiff line numberDiff line change
@@ -10,79 +10,79 @@ pub enum SearchResult<BorrowType, K, V, FoundType, GoDownType> {
1010
GoDown(Handle<NodeRef<BorrowType, K, V, GoDownType>, marker::Edge>),
1111
}
1212

13-
/// Looks up a given key in a (sub)tree headed by the given node, recursively.
14-
/// Returns a `Found` with the handle of the matching KV, if any. Otherwise,
15-
/// returns a `GoDown` with the handle of the leaf edge where the key belongs.
16-
///
17-
/// The result is meaningful only if the tree is ordered by key, like the tree
18-
/// in a `BTreeMap` is.
19-
pub fn search_tree<BorrowType, K, V, Q: ?Sized>(
20-
mut node: NodeRef<BorrowType, K, V, marker::LeafOrInternal>,
21-
key: &Q,
22-
) -> SearchResult<BorrowType, K, V, marker::LeafOrInternal, marker::Leaf>
23-
where
24-
Q: Ord,
25-
K: Borrow<Q>,
26-
{
27-
loop {
28-
match search_node(node, key) {
29-
Found(handle) => return Found(handle),
30-
GoDown(handle) => match handle.force() {
31-
Leaf(leaf) => return GoDown(leaf),
32-
Internal(internal) => {
33-
node = internal.descend();
34-
continue;
35-
}
36-
},
13+
pub enum IndexResult {
14+
KV(usize),
15+
Edge(usize),
16+
}
17+
18+
impl<BorrowType, K, V> NodeRef<BorrowType, K, V, marker::LeafOrInternal> {
19+
/// Looks up a given key in a (sub)tree headed by the node, recursively.
20+
/// Returns a `Found` with the handle of the matching KV, if any. Otherwise,
21+
/// returns a `GoDown` with the handle of the leaf edge where the key belongs.
22+
///
23+
/// The result is meaningful only if the tree is ordered by key, like the tree
24+
/// in a `BTreeMap` is.
25+
pub fn search_tree<Q: ?Sized>(
26+
mut self,
27+
key: &Q,
28+
) -> SearchResult<BorrowType, K, V, marker::LeafOrInternal, marker::Leaf>
29+
where
30+
Q: Ord,
31+
K: Borrow<Q>,
32+
{
33+
loop {
34+
self = match self.search_node(key) {
35+
Found(handle) => return Found(handle),
36+
GoDown(handle) => match handle.force() {
37+
Leaf(leaf) => return GoDown(leaf),
38+
Internal(internal) => internal.descend(),
39+
},
40+
}
3741
}
3842
}
3943
}
4044

41-
/// Looks up a given key in a given node, without recursion.
42-
/// Returns a `Found` with the handle of the matching KV, if any. Otherwise,
43-
/// returns a `GoDown` with the handle of the edge where the key might be found
44-
/// (if the node is internal) or where the key can be inserted.
45-
///
46-
/// The result is meaningful only if the tree is ordered by key, like the tree
47-
/// in a `BTreeMap` is.
48-
pub fn search_node<BorrowType, K, V, Type, Q: ?Sized>(
49-
node: NodeRef<BorrowType, K, V, Type>,
50-
key: &Q,
51-
) -> SearchResult<BorrowType, K, V, Type, Type>
52-
where
53-
Q: Ord,
54-
K: Borrow<Q>,
55-
{
56-
match search_linear(&node, key) {
57-
(idx, true) => Found(unsafe { Handle::new_kv(node, idx) }),
58-
(idx, false) => GoDown(unsafe { Handle::new_edge(node, idx) }),
45+
impl<BorrowType, K, V, Type> NodeRef<BorrowType, K, V, Type> {
46+
/// Looks up a given key in the node, without recursion.
47+
/// Returns a `Found` with the handle of the matching KV, if any. Otherwise,
48+
/// returns a `GoDown` with the handle of the edge where the key might be found
49+
/// (if the node is internal) or where the key can be inserted.
50+
///
51+
/// The result is meaningful only if the tree is ordered by key, like the tree
52+
/// in a `BTreeMap` is.
53+
pub fn search_node<Q: ?Sized>(self, key: &Q) -> SearchResult<BorrowType, K, V, Type, Type>
54+
where
55+
Q: Ord,
56+
K: Borrow<Q>,
57+
{
58+
match self.find_index(key) {
59+
IndexResult::KV(idx) => Found(unsafe { Handle::new_kv(self, idx) }),
60+
IndexResult::Edge(idx) => GoDown(unsafe { Handle::new_edge(self, idx) }),
61+
}
5962
}
60-
}
6163

62-
/// Returns either the KV index in the node at which the key (or an equivalent)
63-
/// exists and `true`, or the edge index where the key belongs and `false`.
64-
///
65-
/// The result is meaningful only if the tree is ordered by key, like the tree
66-
/// in a `BTreeMap` is.
67-
fn search_linear<BorrowType, K, V, Type, Q: ?Sized>(
68-
node: &NodeRef<BorrowType, K, V, Type>,
69-
key: &Q,
70-
) -> (usize, bool)
71-
where
72-
Q: Ord,
73-
K: Borrow<Q>,
74-
{
75-
// This function is defined over all borrow types (immutable, mutable, owned).
76-
// Using `keys_at()` is fine here even if BorrowType is mutable, as all we return
77-
// is an index -- not a reference.
78-
let len = node.len();
79-
for i in 0..len {
80-
let k = unsafe { node.reborrow().key_at(i) };
81-
match key.cmp(k.borrow()) {
82-
Ordering::Greater => {}
83-
Ordering::Equal => return (i, true),
84-
Ordering::Less => return (i, false),
64+
/// Returns either the KV index in the node at which the key (or an equivalent)
65+
/// exists, or the edge index where the key belongs.
66+
///
67+
/// The result is meaningful only if the tree is ordered by key, like the tree
68+
/// in a `BTreeMap` is.
69+
fn find_index<Q: ?Sized>(&self, key: &Q) -> IndexResult
70+
where
71+
Q: Ord,
72+
K: Borrow<Q>,
73+
{
74+
// This function is defined over all borrow types (immutable, mutable, owned).
75+
// Using `keys_at()` is fine here even if BorrowType is mutable, as all we return
76+
// is an index -- not a reference.
77+
let len = self.len();
78+
for i in 0..len {
79+
let k = unsafe { self.reborrow().key_at(i) };
80+
match key.cmp(k.borrow()) {
81+
Ordering::Greater => {}
82+
Ordering::Equal => return IndexResult::KV(i),
83+
Ordering::Less => return IndexResult::Edge(i),
84+
}
8585
}
86+
IndexResult::Edge(len)
8687
}
87-
(len, false)
8888
}

Diff for: library/alloc/src/collections/btree/split.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
use super::map::MIN_LEN;
22
use super::node::{ForceResult::*, Root};
3-
use super::search::{search_node, SearchResult::*};
3+
use super::search::SearchResult::*;
44
use core::borrow::Borrow;
55

66
impl<K, V> Root<K, V> {
@@ -21,7 +21,7 @@ impl<K, V> Root<K, V> {
2121
let mut right_node = right_root.borrow_mut();
2222

2323
loop {
24-
let mut split_edge = match search_node(left_node, key) {
24+
let mut split_edge = match left_node.search_node(key) {
2525
// key is going to the right tree
2626
Found(kv) => kv.left_edge(),
2727
GoDown(edge) => edge,

0 commit comments

Comments
 (0)