Skip to content

Commit 405b786

Browse files
committed
BTreeMap: lightly refactor range_search
1 parent cfba499 commit 405b786

File tree

1 file changed

+38
-24
lines changed

1 file changed

+38
-24
lines changed

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

+38-24
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
use core::borrow::Borrow;
22
use core::cmp::Ordering;
3-
use core::ops::Bound::{Excluded, Included, Unbounded};
4-
use core::ops::RangeBounds;
3+
use core::ops::{Bound, RangeBounds};
54
use core::ptr;
65

76
use super::node::{marker, ForceResult::*, Handle, NodeRef};
@@ -31,61 +30,76 @@ where
3130
let start = range.start_bound();
3231
let end = range.end_bound();
3332
match (start, end) {
34-
(Excluded(s), Excluded(e)) if s == e => {
33+
(Bound::Excluded(s), Bound::Excluded(e)) if s == e => {
3534
panic!("range start and end are equal and excluded in BTreeMap")
3635
}
37-
(Included(s) | Excluded(s), Included(e) | Excluded(e)) if s > e => {
36+
(Bound::Included(s) | Bound::Excluded(s), Bound::Included(e) | Bound::Excluded(e))
37+
if s > e =>
38+
{
3839
panic!("range start is greater than range end in BTreeMap")
3940
}
4041
_ => {}
4142
};
4243

44+
enum FullBound<T> {
45+
FullyIncluded,
46+
Included(T),
47+
Excluded(T),
48+
FullyExcluded,
49+
}
50+
use FullBound::*;
51+
impl<T> FullBound<T> {
52+
fn from(ops_bound: Bound<T>) -> Self {
53+
match ops_bound {
54+
Bound::Included(t) => Included(t),
55+
Bound::Excluded(t) => Excluded(t),
56+
Bound::Unbounded => FullyIncluded,
57+
}
58+
}
59+
}
60+
4361
let mut min_node = root1;
4462
let mut max_node = root2;
45-
let mut min_found = false;
46-
let mut max_found = false;
63+
let mut min_bound = FullBound::from(start);
64+
let mut max_bound = FullBound::from(end);
4765

4866
loop {
49-
// Using `range` again would be unsound (#81138)
50-
let front = match (min_found, start) {
51-
(false, Included(key)) => match min_node.search_node(key) {
67+
let front = match min_bound {
68+
Included(key) => match min_node.search_node(key) {
5269
SearchResult::Found(kv) => {
53-
min_found = true;
70+
min_bound = FullyExcluded;
5471
kv.left_edge()
5572
}
5673
SearchResult::GoDown(edge) => edge,
5774
},
58-
(false, Excluded(key)) => match min_node.search_node(key) {
75+
Excluded(key) => match min_node.search_node(key) {
5976
SearchResult::Found(kv) => {
60-
min_found = true;
77+
min_bound = FullyIncluded;
6178
kv.right_edge()
6279
}
6380
SearchResult::GoDown(edge) => edge,
6481
},
65-
(true, Included(_)) => min_node.last_edge(),
66-
(true, Excluded(_)) => min_node.first_edge(),
67-
(_, Unbounded) => min_node.first_edge(),
82+
FullyExcluded => min_node.last_edge(),
83+
FullyIncluded => min_node.first_edge(),
6884
};
6985

70-
// Using `range` again would be unsound (#81138)
71-
let back = match (max_found, end) {
72-
(false, Included(key)) => match max_node.search_node(key) {
86+
let back = match max_bound {
87+
Included(key) => match max_node.search_node(key) {
7388
SearchResult::Found(kv) => {
74-
max_found = true;
89+
max_bound = FullyExcluded;
7590
kv.right_edge()
7691
}
7792
SearchResult::GoDown(edge) => edge,
7893
},
79-
(false, Excluded(key)) => match max_node.search_node(key) {
94+
Excluded(key) => match max_node.search_node(key) {
8095
SearchResult::Found(kv) => {
81-
max_found = true;
96+
max_bound = FullyIncluded;
8297
kv.left_edge()
8398
}
8499
SearchResult::GoDown(edge) => edge,
85100
},
86-
(true, Included(_)) => max_node.first_edge(),
87-
(true, Excluded(_)) => max_node.last_edge(),
88-
(_, Unbounded) => max_node.last_edge(),
101+
FullyExcluded => max_node.first_edge(),
102+
FullyIncluded => max_node.last_edge(),
89103
};
90104

91105
if front.partial_cmp(&back) == Some(Ordering::Greater) {

0 commit comments

Comments
 (0)