generic_btree/generic_impl/
len_finder.rs1use std::fmt::Debug;
2
3use thunderdome::Index;
4
5use crate::rle::HasLength;
6use crate::{BTreeTrait, FindResult, Query};
7
8pub struct LengthFinder {
10 pub left: usize,
11 pub slot: u8,
12 pub parent: Option<Index>,
13}
14
15impl LengthFinder {
16 #[inline(always)]
17 pub fn new() -> Self {
18 Self {
19 left: 0,
20 slot: 0,
21 parent: None,
22 }
23 }
24}
25
26impl Default for LengthFinder {
27 #[inline(always)]
28 fn default() -> Self {
29 Self::new()
30 }
31}
32
33pub trait UseLengthFinder<B: BTreeTrait> {
34 fn get_len(cache: &B::Cache) -> usize;
35}
36
37impl<Elem: HasLength + Debug, B: BTreeTrait<Elem = Elem> + UseLengthFinder<B>> Query<B>
38 for LengthFinder
39{
40 type QueryArg = usize;
41
42 #[inline(always)]
43 fn init(target: &Self::QueryArg) -> Self {
44 Self {
45 left: *target,
46 slot: 0,
47 parent: None,
48 }
49 }
50
51 #[inline(always)]
52 fn find_node(
53 &mut self,
54 _: &Self::QueryArg,
55 child_caches: &[crate::Child<B>],
56 ) -> crate::FindResult {
57 let mut last_left = self.left;
58 let is_internal = child_caches.first().unwrap().is_internal();
59 for (i, cache) in child_caches.iter().enumerate() {
60 let len = B::get_len(&cache.cache);
61 if self.left >= len {
62 last_left = self.left;
63 self.left -= len;
64 } else {
65 if is_internal {
66 self.parent = Some(cache.arena.unwrap());
67 } else {
68 self.slot = i as u8;
69 }
70 return FindResult::new_found(i, self.left);
71 }
72 }
73
74 self.left = last_left;
75 if is_internal {
76 self.parent = Some(child_caches.last().unwrap().arena.unwrap());
77 } else {
78 self.slot = child_caches.len() as u8 - 1;
79 }
80 FindResult::new_missing(child_caches.len() - 1, last_left)
81 }
82
83 #[inline(always)]
84 fn confirm_elem(
85 &mut self,
86 _: &Self::QueryArg,
87 elem: &<B as BTreeTrait>::Elem,
88 ) -> (usize, bool) {
89 (self.left, self.left < elem.rle_len())
90 }
91}