1use core::borrow::Borrow;
2use core::cmp::Ordering;
3use core::ops::{Bound, RangeBounds};
4
5use SearchBound::*;
6use SearchResult::*;
7
8use super::node::ForceResult::*;
9use super::node::{Handle, NodeRef, marker};
10
11pub(super) enum SearchBound<T> {
12 Included(T),
14 Excluded(T),
16 AllIncluded,
18 AllExcluded,
20}
21
22impl<T> SearchBound<T> {
23 pub(super) fn from_range(range_bound: Bound<T>) -> Self {
24 match range_bound {
25 Bound::Included(t) => Included(t),
26 Bound::Excluded(t) => Excluded(t),
27 Bound::Unbounded => AllIncluded,
28 }
29 }
30}
31
32pub(super) enum SearchResult<BorrowType, K, V, FoundType, GoDownType> {
33 Found(Handle<NodeRef<BorrowType, K, V, FoundType>, marker::KV>),
34 GoDown(Handle<NodeRef<BorrowType, K, V, GoDownType>, marker::Edge>),
35}
36
37pub(super) enum IndexResult {
38 KV(usize),
39 Edge(usize),
40}
41
42impl<BorrowType: marker::BorrowType, K, V> NodeRef<BorrowType, K, V, marker::LeafOrInternal> {
43 pub(super) fn search_tree<Q: ?Sized>(
50 mut self,
51 key: &Q,
52 ) -> SearchResult<BorrowType, K, V, marker::LeafOrInternal, marker::Leaf>
53 where
54 Q: Ord,
55 K: Borrow<Q>,
56 {
57 loop {
58 self = match self.search_node(key) {
59 Found(handle) => return Found(handle),
60 GoDown(handle) => match handle.force() {
61 Leaf(leaf) => return GoDown(leaf),
62 Internal(internal) => internal.descend(),
63 },
64 }
65 }
66 }
67
68 pub(super) fn search_tree_for_bifurcation<'r, Q: ?Sized, R>(
84 mut self,
85 range: &'r R,
86 ) -> Result<
87 (
88 NodeRef<BorrowType, K, V, marker::LeafOrInternal>,
89 usize,
90 usize,
91 SearchBound<&'r Q>,
92 SearchBound<&'r Q>,
93 ),
94 Handle<NodeRef<BorrowType, K, V, marker::Leaf>, marker::Edge>,
95 >
96 where
97 Q: Ord,
98 K: Borrow<Q>,
99 R: RangeBounds<Q>,
100 {
101 let is_set = <V as super::set_val::IsSetVal>::is_set_val();
103
104 let (start, end) = (range.start_bound(), range.end_bound());
107 match (start, end) {
108 (Bound::Excluded(s), Bound::Excluded(e)) if s == e => {
109 if is_set {
110 {
::core::panicking::panic_fmt(format_args!("range start and end are equal and excluded in BTreeSet"));
}panic!("range start and end are equal and excluded in BTreeSet")
111 } else {
112 {
::core::panicking::panic_fmt(format_args!("range start and end are equal and excluded in BTreeMap"));
}panic!("range start and end are equal and excluded in BTreeMap")
113 }
114 }
115 (Bound::Included(s) | Bound::Excluded(s), Bound::Included(e) | Bound::Excluded(e))
116 if s > e =>
117 {
118 if is_set {
119 {
::core::panicking::panic_fmt(format_args!("range start is greater than range end in BTreeSet"));
}panic!("range start is greater than range end in BTreeSet")
120 } else {
121 {
::core::panicking::panic_fmt(format_args!("range start is greater than range end in BTreeMap"));
}panic!("range start is greater than range end in BTreeMap")
122 }
123 }
124 _ => {}
125 }
126 let mut lower_bound = SearchBound::from_range(start);
127 let mut upper_bound = SearchBound::from_range(end);
128 loop {
129 let (lower_edge_idx, lower_child_bound) = self.find_lower_bound_index(lower_bound);
130 let (upper_edge_idx, upper_child_bound) =
131 unsafe { self.find_upper_bound_index(upper_bound, lower_edge_idx) };
133 if lower_edge_idx < upper_edge_idx {
134 return Ok((
135 self,
136 lower_edge_idx,
137 upper_edge_idx,
138 lower_child_bound,
139 upper_child_bound,
140 ));
141 }
142 if true {
{
match (&lower_edge_idx, &upper_edge_idx) {
(left_val, right_val) => {
if !(*left_val == *right_val) {
let kind = ::core::panicking::AssertKind::Eq;
::core::panicking::assert_failed(kind, &*left_val,
&*right_val, ::core::option::Option::None);
}
}
}
};
};debug_assert_eq!(lower_edge_idx, upper_edge_idx);
143 let common_edge = unsafe { Handle::new_edge(self, lower_edge_idx) };
145 match common_edge.force() {
146 Leaf(common_edge) => return Err(common_edge),
147 Internal(common_edge) => {
148 self = common_edge.descend();
149 lower_bound = lower_child_bound;
150 upper_bound = upper_child_bound;
151 }
152 }
153 }
154 }
155
156 pub(super) fn find_lower_bound_edge<'r, Q>(
162 self,
163 bound: SearchBound<&'r Q>,
164 ) -> (Handle<Self, marker::Edge>, SearchBound<&'r Q>)
165 where
166 Q: ?Sized + Ord,
167 K: Borrow<Q>,
168 {
169 let (edge_idx, bound) = self.find_lower_bound_index(bound);
170 let edge = unsafe { Handle::new_edge(self, edge_idx) };
172 (edge, bound)
173 }
174
175 pub(super) fn find_upper_bound_edge<'r, Q>(
177 self,
178 bound: SearchBound<&'r Q>,
179 ) -> (Handle<Self, marker::Edge>, SearchBound<&'r Q>)
180 where
181 Q: ?Sized + Ord,
182 K: Borrow<Q>,
183 {
184 let (edge_idx, bound) = unsafe { self.find_upper_bound_index(bound, 0) };
186 let edge = unsafe { Handle::new_edge(self, edge_idx) };
188 (edge, bound)
189 }
190}
191
192impl<BorrowType, K, V, Type> NodeRef<BorrowType, K, V, Type> {
193 pub(super) fn search_node<Q: ?Sized>(
201 self,
202 key: &Q,
203 ) -> SearchResult<BorrowType, K, V, Type, Type>
204 where
205 Q: Ord,
206 K: Borrow<Q>,
207 {
208 match unsafe { self.find_key_index(key, 0) } {
210 IndexResult::KV(idx) => Found(unsafe { Handle::new_kv(self, idx) }),
212 IndexResult::Edge(idx) => GoDown(unsafe { Handle::new_edge(self, idx) }),
214 }
215 }
216
217 unsafe fn find_key_index<Q: ?Sized>(&self, key: &Q, start_index: usize) -> IndexResult
226 where
227 Q: Ord,
228 K: Borrow<Q>,
229 {
230 let node = self.reborrow();
231 let keys = node.keys();
232 if true {
if !(start_index <= keys.len()) {
::core::panicking::panic("assertion failed: start_index <= keys.len()")
};
};debug_assert!(start_index <= keys.len());
233 for (offset, k) in unsafe { keys.get_unchecked(start_index..) }.iter().enumerate() {
235 match key.cmp(k.borrow()) {
236 Ordering::Greater => {}
237 Ordering::Equal => return IndexResult::KV(start_index + offset),
238 Ordering::Less => return IndexResult::Edge(start_index + offset),
239 }
240 }
241 IndexResult::Edge(keys.len())
242 }
243
244 fn find_lower_bound_index<'r, Q>(
250 &self,
251 bound: SearchBound<&'r Q>,
252 ) -> (usize, SearchBound<&'r Q>)
253 where
254 Q: ?Sized + Ord,
255 K: Borrow<Q>,
256 {
257 match bound {
258 Included(key) => match unsafe { self.find_key_index(key, 0) } {
260 IndexResult::KV(idx) => (idx, AllExcluded),
261 IndexResult::Edge(idx) => (idx, bound),
262 },
263 Excluded(key) => match unsafe { self.find_key_index(key, 0) } {
265 IndexResult::KV(idx) => (idx + 1, AllIncluded),
266 IndexResult::Edge(idx) => (idx, bound),
267 },
268 AllIncluded => (0, AllIncluded),
269 AllExcluded => (self.len(), AllExcluded),
270 }
271 }
272
273 unsafe fn find_upper_bound_index<'r, Q>(
279 &self,
280 bound: SearchBound<&'r Q>,
281 start_index: usize,
282 ) -> (usize, SearchBound<&'r Q>)
283 where
284 Q: ?Sized + Ord,
285 K: Borrow<Q>,
286 {
287 match bound {
288 Included(key) => match unsafe { self.find_key_index(key, start_index) } {
290 IndexResult::KV(idx) => (idx + 1, AllExcluded),
291 IndexResult::Edge(idx) => (idx, bound),
292 },
293 Excluded(key) => match unsafe { self.find_key_index(key, start_index) } {
295 IndexResult::KV(idx) => (idx, AllIncluded),
296 IndexResult::Edge(idx) => (idx, bound),
297 },
298 AllIncluded => (self.len(), AllIncluded),
299 AllExcluded => (start_index, AllExcluded),
300 }
301 }
302}