1use core::{
5 cmp::Ordering,
6 fmt,
7 iter::FusedIterator,
8 ops::{Bound, ControlFlow},
9};
10
11use crate::{
12 allocator::{Allocator, Global},
13 map::{NonEmptyTree, DEFAULT_PREFIX_LEN},
14 raw::{
15 match_concrete_node_ptr, maximum_unchecked, minimum_unchecked,
16 AttemptOptimisticPrefixMatch, ConcreteNodePtr, InnerNode, LeafNode, NodePtr, OpaqueNodePtr,
17 PrefixMatchBehavior, RawIterator,
18 },
19 AsBytes, TreeMap,
20};
21
22pub(crate) struct InnerNodeSearchResult<K, V, const PREFIX_LEN: usize> {
25 pub node_ptr: OpaqueNodePtr<K, V, PREFIX_LEN>,
27
28 pub current_depth: usize,
31
32 pub node_prefix_comparison_to_search_key_segment: Ordering,
35
36 pub reason: InnerNodeSearchResultReason,
38}
39
40impl<K, V, const PREFIX_LEN: usize> fmt::Debug for InnerNodeSearchResult<K, V, PREFIX_LEN> {
41 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
42 f.debug_struct("InnerNodeSearchResult")
43 .field("node_ptr", &self.node_ptr)
44 .field("current_depth", &self.current_depth)
45 .field(
46 "node_prefix_comparison_to_search_key_segment",
47 &self.node_prefix_comparison_to_search_key_segment,
48 )
49 .field("reason", &self.reason)
50 .finish()
51 }
52}
53
54#[derive(Debug)]
56pub(crate) enum InnerNodeSearchResultReason {
57 PrefixMismatchOrInsufficientBytes,
61 MissingChild,
64}
65
66pub(crate) enum TerminatingNodeSearchResult<K, V, const PREFIX_LEN: usize> {
69 Leaf {
71 leaf_ptr: NodePtr<PREFIX_LEN, LeafNode<K, V, PREFIX_LEN>>,
73 leaf_key_comparison_to_search_key: Ordering,
75 },
76 InnerNode(InnerNodeSearchResult<K, V, PREFIX_LEN>),
78}
79
80impl<K, V, const PREFIX_LEN: usize> fmt::Debug for TerminatingNodeSearchResult<K, V, PREFIX_LEN> {
81 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
82 match self {
83 Self::Leaf {
84 leaf_ptr,
85 leaf_key_comparison_to_search_key,
86 } => f
87 .debug_struct("Leaf")
88 .field("leaf_ptr", leaf_ptr)
89 .field(
90 "leaf_key_comparison_to_search_key",
91 leaf_key_comparison_to_search_key,
92 )
93 .finish(),
94 Self::InnerNode(arg0) => f.debug_tuple("InnerNode").field(arg0).finish(),
95 }
96 }
97}
98
99pub(crate) unsafe fn find_terminating_node<K: AsBytes, V, const PREFIX_LEN: usize>(
107 root: OpaqueNodePtr<K, V, PREFIX_LEN>,
108 key_bytes: &[u8],
109) -> TerminatingNodeSearchResult<K, V, PREFIX_LEN> {
110 unsafe fn check_prefix_lookup_child<K, V, N, const PREFIX_LEN: usize>(
122 inner_ptr: NodePtr<PREFIX_LEN, N>,
123 key_bytes: &[u8],
124 current_depth: &mut usize,
125 prefix_match_behavior: &mut PrefixMatchBehavior,
126 ) -> ControlFlow<InnerNodeSearchResult<K, V, PREFIX_LEN>, OpaqueNodePtr<K, V, PREFIX_LEN>>
127 where
128 N: InnerNode<PREFIX_LEN, Key = K, Value = V>,
129 K: AsBytes,
130 {
131 let inner_node = unsafe { inner_ptr.as_ref() };
136 let match_prefix =
137 prefix_match_behavior.match_prefix(inner_node, &key_bytes[*current_depth..]);
138 match match_prefix {
139 Err(_) => {
140 let (full_prefix, _) = inner_node.read_full_prefix(*current_depth);
141 let upper_bound = (*current_depth + full_prefix.len()).min(key_bytes.len());
142 let key_segment = &key_bytes[(*current_depth)..upper_bound];
143
144 let node_prefix_comparison_to_search_key_segment = full_prefix.cmp(key_segment);
145
146 ControlFlow::Break(InnerNodeSearchResult {
147 node_ptr: inner_ptr.to_opaque(),
148 current_depth: *current_depth,
149 reason: InnerNodeSearchResultReason::PrefixMismatchOrInsufficientBytes,
150 node_prefix_comparison_to_search_key_segment,
151 })
152 },
153 Ok(AttemptOptimisticPrefixMatch { matched_bytes, .. }) => {
154 *current_depth += matched_bytes;
156
157 let next_key_fragment = if *current_depth < key_bytes.len() {
158 key_bytes[*current_depth]
159 } else {
160 return ControlFlow::Break(InnerNodeSearchResult {
164 node_ptr: inner_ptr.to_opaque(),
165 current_depth: *current_depth,
166 reason: InnerNodeSearchResultReason::PrefixMismatchOrInsufficientBytes,
167 node_prefix_comparison_to_search_key_segment: Ordering::Equal,
168 });
169 };
170
171 let child_lookup = inner_node.lookup_child(next_key_fragment);
172
173 match child_lookup {
174 Some(child_ptr) => {
175 *current_depth += 1;
178 ControlFlow::Continue(child_ptr)
179 },
180 None => ControlFlow::Break(InnerNodeSearchResult {
181 node_ptr: inner_ptr.to_opaque(),
182 current_depth: *current_depth,
183 reason: InnerNodeSearchResultReason::MissingChild,
184 node_prefix_comparison_to_search_key_segment: Ordering::Equal,
185 }),
186 }
187 },
188 }
189 }
190
191 let mut current_node = root;
192 let mut current_depth = 0;
193 let mut prefix_match_behavior = PrefixMatchBehavior::default();
194
195 loop {
196 let next_node = match_concrete_node_ptr!(match (current_node.to_node_ptr()) {
197 InnerNode(inner_ptr) => unsafe {
198 check_prefix_lookup_child(
201 inner_ptr,
202 key_bytes,
203 &mut current_depth,
204 &mut prefix_match_behavior,
205 )
206 },
207 LeafNode(leaf_ptr) => {
208 let leaf_node = unsafe { leaf_ptr.as_ref() };
211
212 let leaf_key_comparison_to_search_key =
213 prefix_match_behavior.compare_leaf_key(leaf_node, key_bytes, current_depth);
214
215 return TerminatingNodeSearchResult::Leaf {
216 leaf_ptr,
217 leaf_key_comparison_to_search_key,
218 };
219 },
220 });
221
222 match next_node {
223 ControlFlow::Continue(next_node) => {
224 current_node = next_node;
225 },
226 ControlFlow::Break(reason) => {
227 return TerminatingNodeSearchResult::InnerNode(reason);
228 },
229 }
230 }
231}
232
233#[track_caller]
235pub(crate) fn validate_range_bounds(start_bound: &Bound<&[u8]>, end_bound: &Bound<&[u8]>) {
236 match (*start_bound, *end_bound) {
237 (Bound::Excluded(s), Bound::Excluded(e)) if s == e => {
238 panic!("range start and end are equal and excluded: ({s:?})")
239 },
240 (Bound::Included(s) | Bound::Excluded(s), Bound::Included(e) | Bound::Excluded(e))
241 if s > e =>
242 {
243 panic!("range start ({s:?}) is greater than range end ({e:?})")
244 },
245 _ => {},
246 }
247}
248
249type KeyByteAndChild<K, V, const PREFIX_LEN: usize> = Option<(u8, OpaqueNodePtr<K, V, PREFIX_LEN>)>;
250
251pub(crate) unsafe fn find_leaf_pointer_for_bound<K: AsBytes, V, const PREFIX_LEN: usize>(
263 tree: &NonEmptyTree<K, V, PREFIX_LEN>,
264 bound: Bound<&[u8]>,
265 is_start: bool,
266) -> Option<NodePtr<PREFIX_LEN, LeafNode<K, V, PREFIX_LEN>>> {
267 Some(match bound {
268 Bound::Included(key_bytes) | Bound::Excluded(key_bytes) => {
269 let terminating_node = unsafe { find_terminating_node(tree.root, key_bytes) };
271
272 match terminating_node {
273 TerminatingNodeSearchResult::Leaf {
274 leaf_ptr,
275 leaf_key_comparison_to_search_key,
276 } => match leaf_key_comparison_to_search_key {
277 Ordering::Less => {
278 if is_start {
279 let leaf = unsafe { leaf_ptr.as_ref() };
281 leaf.next?
282 } else {
283 leaf_ptr
284 }
285 },
286 Ordering::Equal => {
287 if matches!(bound, Bound::Excluded(_)) {
288 let leaf = unsafe { leaf_ptr.as_ref() };
290 if is_start { leaf.next } else { leaf.previous }?
291 } else {
292 leaf_ptr
293 }
294 },
295 Ordering::Greater => {
296 if is_start {
297 leaf_ptr
298 } else {
299 let leaf = unsafe { leaf_ptr.as_ref() };
301 leaf.previous?
302 }
303 },
304 },
305 TerminatingNodeSearchResult::InnerNode(InnerNodeSearchResult {
306 node_ptr,
307 current_depth,
308 reason,
309 node_prefix_comparison_to_search_key_segment,
310 }) => match reason {
311 InnerNodeSearchResultReason::PrefixMismatchOrInsufficientBytes => {
312 match (is_start, node_prefix_comparison_to_search_key_segment) {
313 (true, Ordering::Equal | Ordering::Greater) => unsafe {
314 minimum_unchecked(node_ptr)
316 },
317 (true, Ordering::Less) => unsafe {
318 let max_leaf_ptr = maximum_unchecked(node_ptr);
320 let max_leaf = max_leaf_ptr.as_ref();
321 max_leaf.next?
322 },
323 (false, Ordering::Equal | Ordering::Less) => unsafe {
324 maximum_unchecked(node_ptr)
326 },
327 (false, Ordering::Greater) => unsafe {
328 let min_leaf_ptr = minimum_unchecked(node_ptr);
330 let min_leaf = min_leaf_ptr.as_ref();
331 min_leaf.previous?
332 },
333 }
334 },
335 InnerNodeSearchResultReason::MissingChild => {
336 fn access_closest_child<
337 const PREFIX_LEN: usize,
338 N: InnerNode<PREFIX_LEN>,
339 >(
340 inner_ptr: NodePtr<PREFIX_LEN, N>,
341 child_bounds: (Bound<u8>, Bound<u8>),
342 is_start: bool,
343 ) -> KeyByteAndChild<N::Key, N::Value, PREFIX_LEN> {
344 let inner = unsafe { inner_ptr.as_ref() };
346 let mut child_it = inner.range(child_bounds);
347 if is_start {
348 child_it.next()
349 } else {
350 child_it.next_back()
351 }
352 }
353
354 let child_bounds = if is_start {
355 (bound.map(|_| key_bytes[current_depth]), Bound::Unbounded)
356 } else {
357 (Bound::Unbounded, bound.map(|_| key_bytes[current_depth]))
358 };
359 let possible_next_child =
360 match_concrete_node_ptr!(match (node_ptr.to_node_ptr()) {
361 InnerNode(inner_ptr) => {
362 access_closest_child(inner_ptr, child_bounds, is_start)
363 },
364 LeafNode(_leaf) => unreachable!(
365 "This branch is unreachable because the \
366 TerminatingNodeSearchResult had the value InnerNode"
367 ),
368 });
369 let (_, next_child) = possible_next_child?;
370
371 if is_start {
372 unsafe { minimum_unchecked(next_child) }
374 } else {
375 unsafe { maximum_unchecked(next_child) }
377 }
378 },
379 },
380 }
381 },
382 Bound::Unbounded => {
383 if is_start {
384 tree.min_leaf
385 } else {
386 tree.max_leaf
387 }
388 },
389 })
390}
391
392macro_rules! implement_range_iter {
393 (
394 $(#[$outer:meta])*
395 struct $name:ident {
396 tree: $tree_ty:ty,
397 item: $item_ty:ty,
398 $leaf_accessor_func:ident
399 }
400 ) => {
401 $(#[$outer])*
402 pub struct $name<'a, K, V, const PREFIX_LEN: usize = DEFAULT_PREFIX_LEN, A: Allocator = Global> {
403 inner: RawIterator<K, V, PREFIX_LEN>,
404 _tree: $tree_ty,
405 }
406
407 impl<'a, K: AsBytes, V, const PREFIX_LEN: usize, A: Allocator> $name<'a, K, V, PREFIX_LEN, A> {
408 pub(crate) fn new(
415 tree: $tree_ty,
416 start_bound: Bound<&[u8]>,
417 end_bound: Bound<&[u8]>,
418 ) -> Self {
419 let Some(tree_state) = &tree.state else {
420 return Self {
421 _tree: tree,
422 inner: RawIterator::empty(),
423 };
424 };
425
426 validate_range_bounds(&start_bound, &end_bound);
429
430 let possible_start =
433 unsafe { find_leaf_pointer_for_bound(tree_state, start_bound, true) };
434 let Some(start) = possible_start else {
435 return Self {
436 _tree: tree,
437 inner: RawIterator::empty(),
438 };
439 };
440
441 let possible_end =
444 unsafe { find_leaf_pointer_for_bound(tree_state, end_bound, false) };
445 let Some(end) = possible_end else {
446 return Self {
447 _tree: tree,
448 inner: RawIterator::empty(),
449 };
450 };
451
452 unsafe {
456 let start_leaf_bytes = start.as_key_ref().as_bytes();
457 let end_leaf_bytes = end.as_key_ref().as_bytes();
458
459 if start_leaf_bytes > end_leaf_bytes {
460 return Self {
463 _tree: tree,
464 inner: RawIterator::empty(),
465 };
466 }
467 }
468
469 Self {
470 _tree: tree,
471 inner: unsafe { RawIterator::new(start, end) },
475 }
476 }
477 }
478
479 impl<'a, K, V, const PREFIX_LEN: usize, A: Allocator> Iterator for $name<'a, K, V, PREFIX_LEN, A> {
480 type Item = $item_ty;
481
482 fn next(&mut self) -> Option<Self::Item> {
483 let leaf_ptr = unsafe { self.inner.next()? };
486
487 Some(unsafe { leaf_ptr.$leaf_accessor_func() })
491 }
492 }
493
494 impl<'a, K, V, const PREFIX_LEN: usize, A: Allocator> DoubleEndedIterator
495 for $name<'a, K, V, PREFIX_LEN, A>
496 {
497 fn next_back(&mut self) -> Option<Self::Item> {
498 let leaf_ptr = unsafe { self.inner.next_back()? };
501
502 Some(unsafe { leaf_ptr.$leaf_accessor_func() })
506 }
507 }
508
509 impl<'a, K, V, const PREFIX_LEN: usize, A: Allocator> FusedIterator for $name<'a, K, V, PREFIX_LEN, A> {}
510 };
511}
512
513implement_range_iter!(
514 struct Range {
519 tree: &'a TreeMap<K, V, PREFIX_LEN, A>,
520 item: (&'a K, &'a V),
521 as_key_value_ref
522 }
523);
524
525unsafe impl<K, V, A, const PREFIX_LEN: usize> Send for Range<'_, K, V, PREFIX_LEN, A>
528where
529 K: Sync,
530 V: Sync,
531 A: Sync + Allocator,
532{
533}
534
535unsafe impl<K, V, A, const PREFIX_LEN: usize> Sync for Range<'_, K, V, PREFIX_LEN, A>
538where
539 K: Sync,
540 V: Sync,
541 A: Sync + Allocator,
542{
543}
544
545implement_range_iter!(
546 struct RangeMut {
551 tree: &'a mut TreeMap<K, V, PREFIX_LEN, A>,
552 item: (&'a K, &'a mut V),
553 as_key_ref_value_mut
554 }
555);
556
557unsafe impl<K, V, A, const PREFIX_LEN: usize> Send for RangeMut<'_, K, V, PREFIX_LEN, A>
561where
562 K: Send,
563 V: Send,
564 A: Send + Allocator,
565{
566}
567
568unsafe impl<K, V, A, const PREFIX_LEN: usize> Sync for RangeMut<'_, K, V, PREFIX_LEN, A>
571where
572 K: Sync,
573 V: Sync,
574 A: Sync + Allocator,
575{
576}
577
578#[cfg(test)]
579mod tests {
580 use alloc::{boxed::Box, vec::Vec};
581
582 use super::*;
583 use crate::testing::{generate_key_with_prefix, swap, PrefixExpansion};
584
585 #[test]
586 fn iterators_are_send_sync() {
587 fn is_send<T: Send>() {}
588 fn is_sync<T: Sync>() {}
589
590 fn range_is_send<'a, K: Sync + 'a, V: Sync + 'a, A: Sync + Allocator + 'a>() {
591 is_send::<Range<'a, K, V, DEFAULT_PREFIX_LEN, A>>();
592 }
593
594 fn range_is_sync<'a, K: Sync + 'a, V: Sync + 'a, A: Sync + Allocator + 'a>() {
595 is_sync::<Range<'a, K, V, DEFAULT_PREFIX_LEN, A>>();
596 }
597
598 range_is_send::<[u8; 3], usize, Global>();
599 range_is_sync::<[u8; 3], usize, Global>();
600
601 fn range_mut_is_send<'a, K: Send + 'a, V: Send + 'a, A: Send + Allocator + 'a>() {
602 is_send::<RangeMut<'a, K, V, DEFAULT_PREFIX_LEN, A>>();
603 }
604
605 fn range_mut_is_sync<'a, K: Sync + 'a, V: Sync + 'a, A: Sync + Allocator + 'a>() {
606 is_sync::<RangeMut<'a, K, V, DEFAULT_PREFIX_LEN, A>>();
607 }
608
609 range_mut_is_send::<[u8; 3], usize, Global>();
610 range_mut_is_sync::<[u8; 3], usize, Global>();
611 }
612
613 fn fixture_tree() -> TreeMap<[u8; 3], usize> {
614 [
615 [0, 0, 0],
616 [0, 0, u8::MAX],
617 [0, u8::MAX, 0],
618 [0, u8::MAX, u8::MAX],
619 [127, 127, 0],
620 [127, 127, 127],
621 [127, 127, u8::MAX],
622 [u8::MAX, 0, 0],
623 [u8::MAX, 0, u8::MAX],
624 [u8::MAX, u8::MAX, 0],
625 [u8::MAX, u8::MAX, u8::MAX],
626 ]
627 .into_iter()
628 .enumerate()
629 .map(swap)
630 .collect()
631 }
632
633 #[test]
634 fn range_iteration_normal_tree() {
635 let tree = fixture_tree();
636
637 let mut it = Range::new(
639 &tree,
640 Bound::Included([u8::MAX, u8::MAX, u8::MAX].as_slice()),
641 Bound::Unbounded,
642 )
643 .map(|(k, _)| k);
644 assert_eq!(it.next().unwrap(), &[u8::MAX, u8::MAX, u8::MAX]);
645 assert_eq!(it.next(), None);
646
647 let mut it = Range::new(
649 &tree,
650 Bound::Excluded([u8::MAX, u8::MAX, u8::MAX].as_slice()),
651 Bound::Unbounded,
652 )
653 .map(|(k, _)| k);
654 assert_eq!(it.next(), None);
655
656 let mut it = Range::new(
658 &tree,
659 Bound::Unbounded,
660 Bound::Included([0, 0, 0].as_slice()),
661 )
662 .map(|(k, _)| k);
663 assert_eq!(it.next().unwrap(), &[0, 0, 0]);
664 assert_eq!(it.next(), None);
665
666 let mut it = Range::new(
668 &tree,
669 Bound::Unbounded,
670 Bound::Excluded([0, 0, 0].as_slice()),
671 )
672 .map(|(k, _)| k);
673 assert_eq!(it.next(), None);
674 }
675
676 #[test]
677 fn range_iteration_on_key_prefix() {
678 let tree = fixture_tree();
679
680 let mut it = Range::new(
681 &tree,
682 Bound::Included([0].as_slice()),
683 Bound::Excluded([1].as_slice()),
684 )
685 .map(|(k, _)| k);
686
687 assert_eq!(it.next().unwrap(), &[0, 0, 0]);
688 assert_eq!(it.next().unwrap(), &[0, 0, u8::MAX]);
689 assert_eq!(it.next().unwrap(), &[0, u8::MAX, 0]);
690 assert_eq!(it.next().unwrap(), &[0, u8::MAX, u8::MAX]);
691 assert_eq!(it.next(), None);
692 }
693
694 #[test]
695 fn range_prefix_mismatch_or_insufficient_bytes_lower_bounds() {
696 let tree = fixture_tree();
697
698 let mut it = Range::new(
699 &tree,
700 Bound::Included([127, 126].as_slice()),
701 Bound::Excluded([128].as_slice()),
702 )
703 .map(|(k, _)| k);
704
705 assert!([127, 126].as_slice() < [127, 127, 0].as_slice());
708 assert_eq!(it.next().unwrap(), &[127, 127, 0]);
709 assert_eq!(it.next().unwrap(), &[127, 127, 127]);
710 assert_eq!(it.next().unwrap(), &[127, 127, u8::MAX]);
711 assert_eq!(it.next(), None);
712
713 let mut it = Range::new(
714 &tree,
715 Bound::Included([127, 128].as_slice()),
716 Bound::Excluded([128].as_slice()),
717 )
718 .map(|(k, _)| k);
719
720 assert!([127, 128].as_slice() > [127, 127, u8::MAX].as_slice());
723 assert_eq!(it.next(), None);
724
725 let mut it = Range::new(
726 &tree,
727 Bound::Included([127].as_slice()),
728 Bound::Excluded([128].as_slice()),
729 )
730 .map(|(k, _)| k);
731
732 assert!([127].as_slice() < [127, 127, 0].as_slice());
735 assert_eq!(it.next().unwrap(), &[127, 127, 0]);
736 assert_eq!(it.next().unwrap(), &[127, 127, 127]);
737 assert_eq!(it.next().unwrap(), &[127, 127, u8::MAX]);
738 assert_eq!(it.next(), None);
739
740 let mut it = Range::new(
741 &tree,
742 Bound::Included([127, 127].as_slice()),
743 Bound::Excluded([128].as_slice()),
744 )
745 .map(|(k, _)| k);
746
747 assert!([127, 127].as_slice() < [127, 127, 0].as_slice());
750 assert_eq!(it.next().unwrap(), &[127, 127, 0]);
751 assert_eq!(it.next().unwrap(), &[127, 127, 127]);
752 assert_eq!(it.next().unwrap(), &[127, 127, u8::MAX]);
753 assert_eq!(it.next(), None);
754 }
755
756 #[test]
757 fn range_prefix_mismatch_or_insufficient_bytes_upper_bounds() {
758 let tree = fixture_tree();
759
760 let mut it = Range::new(
761 &tree,
762 Bound::Excluded([126].as_slice()),
763 Bound::Excluded([128].as_slice()),
764 )
765 .map(|(k, _)| k);
766 assert_eq!(it.next().unwrap(), &[127, 127, 0]);
767 assert_eq!(it.next().unwrap(), &[127, 127, 127]);
768 assert_eq!(it.next().unwrap(), &[127, 127, u8::MAX]);
769 assert_eq!(it.next(), None);
770
771 let mut it = Range::new(
772 &tree,
773 Bound::Excluded([126].as_slice()),
774 Bound::Included([127, 127, u8::MAX].as_slice()),
775 )
776 .map(|(k, _)| k);
777 assert_eq!(it.next().unwrap(), &[127, 127, 0]);
778 assert_eq!(it.next().unwrap(), &[127, 127, 127]);
779 assert_eq!(it.next().unwrap(), &[127, 127, u8::MAX]);
780 assert_eq!(it.next(), None);
781
782 let mut it = Range::new(
783 &tree,
784 Bound::Excluded([126].as_slice()),
785 Bound::Included([127, 127, 0].as_slice()),
786 )
787 .map(|(k, _)| k);
788 assert_eq!(it.next().unwrap(), &[127, 127, 0]);
789 assert_eq!(it.next(), None);
790 }
791
792 #[test]
793 fn empty_tree_empty_iterator() {
794 let tree = TreeMap::<[u8; 3], usize>::new();
795
796 let it = Range::new(
797 &tree,
798 Bound::Excluded([1, 1, 1].as_slice()),
799 Bound::Excluded([1, 1, 1].as_slice()),
800 );
801
802 assert_eq!(it.count(), 0);
803 }
804
805 #[test]
806 #[should_panic(expected = "range start and end are equal and excluded: ([1, 1, 1])")]
807 fn equal_excluded_bounds_should_panic() {
808 let tree = fixture_tree();
809
810 let _it = Range::new(
811 &tree,
812 Bound::Excluded([1, 1, 1].as_slice()),
813 Bound::Excluded([1, 1, 1].as_slice()),
814 );
815 }
816
817 #[test]
818 #[should_panic(expected = "range start ([1, 1, 1]) is greater than range end ([0, 0, 0])")]
819 fn excluded_excluded_start_greater_than_end_should_panic() {
820 let tree = fixture_tree();
821
822 let _it = Range::new(
823 &tree,
824 Bound::Excluded([1, 1, 1].as_slice()),
825 Bound::Excluded([0, 0, 0].as_slice()),
826 );
827 }
828
829 #[test]
830 #[should_panic(expected = "range start ([1, 1, 1]) is greater than range end ([0, 0, 0])")]
831 fn included_included_start_greater_than_end_should_panic() {
832 let tree = fixture_tree();
833
834 let _it = Range::new(
835 &tree,
836 Bound::Included([1, 1, 1].as_slice()),
837 Bound::Included([0, 0, 0].as_slice()),
838 );
839 }
840
841 #[test]
842 fn excluded_excluded_empty_range_should_be_empty() {
843 let tree = fixture_tree();
844
845 let it = Range::new(
846 &tree,
847 Bound::Excluded([127, 127, 127].as_slice()),
848 Bound::Excluded([127, 127, 128].as_slice()),
849 );
850
851 assert_eq!(it.count(), 0);
852
853 let it = Range::new(
854 &tree,
855 Bound::Excluded([127, 127, 126].as_slice()),
856 Bound::Excluded([127, 127, 127].as_slice()),
857 );
858
859 assert_eq!(it.count(), 0);
860 }
861
862 #[test]
863 fn included_included_range_on_middle() {
864 let tree = fixture_tree();
865
866 let mut it = Range::new(
867 &tree,
868 Bound::Included([126, 0, 0].as_slice()),
869 Bound::Included([128, 0, 0].as_slice()),
870 )
871 .map(|(k, _)| k);
872
873 assert_eq!(it.next().unwrap(), &[127, 127, 0]);
874 assert_eq!(it.next().unwrap(), &[127, 127, 127]);
875 assert_eq!(it.next().unwrap(), &[127, 127, u8::MAX]);
876 assert_eq!(it.next(), None);
877 }
878
879 #[test]
880 fn range_mut_mutate_some_keys() {
881 let mut tree = fixture_tree();
882
883 tree.values_mut().for_each(|value| *value = 0);
884
885 tree.range_mut([126, 0, 0]..=[128u8, 0, 0])
886 .for_each(|(_, value)| *value = 1024);
887
888 assert_eq!(
889 tree.into_iter().collect::<Vec<_>>(),
890 [
891 ([0, 0, 0], 0),
892 ([0, 0, 255], 0),
893 ([0, 255, 0], 0),
894 ([0, 255, 255], 0),
895 ([127, 127, 0], 1024),
896 ([127, 127, 127], 1024),
897 ([127, 127, 255], 1024),
898 ([255, 0, 0], 0),
899 ([255, 0, 255], 0),
900 ([255, 255, 0], 0),
901 ([255, 255, 255], 0)
902 ]
903 );
904 }
905
906 #[test]
907 fn lookup_on_tree_with_implicit_prefix_bytes() {
908 let mut tree = TreeMap::<_, _, 0>::with_prefix_len();
909
910 for (key, value) in generate_key_with_prefix(
911 [3, 3, 3],
912 [PrefixExpansion {
913 base_index: 0,
914 expanded_length: 4,
915 }],
916 )
917 .enumerate()
918 .map(swap)
919 {
920 let _ = tree.try_insert(key, value).unwrap();
921 }
922
923 assert_eq!(
924 tree.range(Box::from([0u8, 0, 0, 0, 0, 0])..Box::from([0u8, 0, 0, 0, 0, 4]))
925 .collect::<Vec<_>>(),
926 &[
927 (&[0, 0, 0, 0, 0, 0].into(), &0),
928 (&[0, 0, 0, 0, 0, 1].into(), &1),
929 (&[0, 0, 0, 0, 0, 2].into(), &2),
930 (&[0, 0, 0, 0, 0, 3].into(), &3)
931 ]
932 );
933
934 assert_eq!(
935 tree.range(Box::from([0u8, 0])..Box::from([0u8, 0, 0, 0, 0, 4]))
936 .collect::<Vec<_>>(),
937 &[
938 (&[0, 0, 0, 0, 0, 0].into(), &0),
939 (&[0, 0, 0, 0, 0, 1].into(), &1),
940 (&[0, 0, 0, 0, 0, 2].into(), &2),
941 (&[0, 0, 0, 0, 0, 3].into(), &3)
942 ]
943 );
944 }
945}