b_tree/
node.rs

1use std::borrow::Borrow;
2use std::cmp::Ordering;
3use std::fmt;
4
5#[cfg(feature = "stream")]
6use async_trait::async_trait;
7use collate::{Collate, Overlap, OverlapsValue};
8#[cfg(feature = "stream")]
9use destream::{de, en};
10use get_size::GetSize;
11use uuid::Uuid;
12
13use super::range::Range;
14use super::Collator;
15
16const UUID_SIZE: usize = 16;
17
18/// An ordered set of keys in a [`Node`].
19pub trait Block<V> {
20    type Key;
21
22    fn bisect<C, BV>(&self, range: &Range<BV>, collator: &Collator<C>) -> (usize, usize)
23    where
24        C: Collate<Value = V>,
25        BV: Borrow<V>;
26
27    fn bisect_left<C, BV>(&self, key: &[BV], collator: &Collator<C>) -> usize
28    where
29        C: Collate<Value = V>,
30        BV: Borrow<V>;
31
32    fn bisect_right<C, BV>(&self, key: &[BV], collator: &Collator<C>) -> usize
33    where
34        C: Collate<Value = V>,
35        BV: Borrow<V>;
36}
37
38impl<V: fmt::Debug> Block<V> for Vec<Vec<V>> {
39    type Key = Vec<V>;
40
41    fn bisect<C, BV>(&self, range: &Range<BV>, collator: &Collator<C>) -> (usize, usize)
42    where
43        C: Collate<Value = V>,
44        BV: Borrow<V>,
45    {
46        // handle common edge cases
47
48        if range.is_default() {
49            return (0, self.len());
50        }
51
52        if let Some(first) = self.first() {
53            if range.overlaps_value(first, collator) == Overlap::Less {
54                return (0, 0);
55            }
56        }
57
58        if let Some(last) = self.last() {
59            if range.overlaps_value(last, collator) == Overlap::Greater {
60                return (self.len(), self.len());
61            }
62        }
63
64        // bisect range left
65        let mut lo = 0;
66        let mut hi = self.len();
67
68        while lo < hi {
69            let mid = (lo + hi) >> 1;
70            match range.overlaps_value(&self[mid], collator) {
71                Overlap::Greater => lo = mid + 1,
72                _ => hi = mid,
73            }
74        }
75
76        let left = lo;
77
78        // bisect range right
79        let mut lo = 0;
80        let mut hi = self.len();
81
82        while lo < hi {
83            let mid = (lo + hi) >> 1;
84            match range.overlaps_value(&self[mid], collator) {
85                Overlap::Less => hi = mid,
86                _ => lo = mid + 1,
87            }
88        }
89
90        let right = hi;
91
92        // return
93        (left, right)
94    }
95
96    fn bisect_left<C, BV>(&self, key: &[BV], collator: &Collator<C>) -> usize
97    where
98        C: Collate<Value = V>,
99        BV: Borrow<V>,
100    {
101        let mut lo = 0;
102        let mut hi = self.len();
103
104        while lo < hi {
105            let mid = (lo + hi) >> 1;
106            match collator.cmp_slices(&self[mid], key) {
107                Ordering::Less => lo = mid + 1,
108                _ => hi = mid,
109            }
110        }
111
112        lo
113    }
114
115    fn bisect_right<C, BV>(&self, key: &[BV], collator: &Collator<C>) -> usize
116    where
117        C: Collate<Value = V>,
118        BV: Borrow<V>,
119    {
120        let mut lo = 0;
121        let mut hi = self.len();
122
123        while lo < hi {
124            let mid = (lo + hi) >> 1;
125            match collator.cmp_slices(&self[mid], key) {
126                Ordering::Greater => hi = mid,
127                _ => lo = mid + 1,
128            }
129        }
130
131        hi
132    }
133}
134
135/// A node in a B+Tree
136#[derive(Clone)]
137pub enum Node<N> {
138    Index(N, Vec<Uuid>),
139    Leaf(N),
140}
141
142impl<N> Node<N> {
143    /// Return `true` if this is a leaf node.
144    pub fn is_leaf(&self) -> bool {
145        match self {
146            Self::Leaf(_) => true,
147            _ => false,
148        }
149    }
150}
151
152impl<N: GetSize> GetSize for Node<N> {
153    fn get_size(&self) -> usize {
154        match self {
155            Self::Index(keys, children) => keys.get_size() + (children.len() * UUID_SIZE),
156            Self::Leaf(leaf) => leaf.get_size(),
157        }
158    }
159}
160
161#[cfg(feature = "stream")]
162struct NodeVisitor<C, N> {
163    context: C,
164    phantom: std::marker::PhantomData<N>,
165}
166
167#[cfg(feature = "stream")]
168impl<C, N> NodeVisitor<C, N> {
169    fn new(context: C) -> Self {
170        Self {
171            context,
172            phantom: std::marker::PhantomData,
173        }
174    }
175}
176
177#[cfg(feature = "stream")]
178#[async_trait]
179impl<N> de::Visitor for NodeVisitor<N::Context, N>
180where
181    N: de::FromStream,
182{
183    type Value = Node<N>;
184
185    fn expecting() -> &'static str {
186        "a B+Tree node"
187    }
188
189    async fn visit_seq<A: de::SeqAccess>(self, mut seq: A) -> Result<Self::Value, A::Error> {
190        let leaf = seq.expect_next::<bool>(()).await?;
191
192        if leaf {
193            match seq.expect_next(self.context).await {
194                Ok(leaf) => Ok(Node::Leaf(leaf)),
195                Err(cause) => Err(cause),
196            }
197        } else {
198            let bounds = seq.expect_next(self.context).await?;
199            let children = seq.expect_next(()).await?;
200            Ok(Node::Index(bounds, children))
201        }
202    }
203}
204
205#[cfg(feature = "stream")]
206#[async_trait]
207impl<N> de::FromStream for Node<N>
208where
209    N: de::FromStream,
210{
211    type Context = N::Context;
212
213    async fn from_stream<D: de::Decoder>(
214        cxt: Self::Context,
215        decoder: &mut D,
216    ) -> Result<Self, D::Error> {
217        decoder.decode_seq(NodeVisitor::new(cxt)).await
218    }
219}
220
221#[cfg(feature = "stream")]
222impl<'en, N: 'en> en::IntoStream<'en> for Node<N>
223where
224    N: en::IntoStream<'en>,
225{
226    fn into_stream<E: en::Encoder<'en>>(self, encoder: E) -> Result<E::Ok, E::Error> {
227        match self {
228            Node::Leaf(keys) => (true, keys).into_stream(encoder),
229            Node::Index(bounds, children) => (false, bounds, children).into_stream(encoder),
230        }
231    }
232}
233
234#[cfg(feature = "stream")]
235impl<'en, N: 'en> en::ToStream<'en> for Node<N>
236where
237    N: en::ToStream<'en>,
238{
239    fn to_stream<E: en::Encoder<'en>>(&'en self, encoder: E) -> Result<E::Ok, E::Error> {
240        use en::IntoStream;
241
242        match self {
243            Node::Leaf(keys) => (true, keys).into_stream(encoder),
244            Node::Index(bounds, children) => (false, bounds, children).into_stream(encoder),
245        }
246    }
247}
248
249#[cfg(debug_assertions)]
250impl<N: fmt::Debug> fmt::Debug for Node<N> {
251    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
252        match self {
253            Self::Leaf(keys) => write!(f, "leaf node with keys {:?}", keys),
254            Self::Index(bounds, children) => write!(
255                f,
256                "index node with bounds {:?} and children {:?}",
257                bounds, children
258            ),
259        }
260    }
261}
262
263#[cfg(not(debug_assertions))]
264impl<V: fmt::Debug> fmt::Debug for Node<V> {
265    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
266        match self {
267            Self::Leaf(_keys) => write!(f, "a leaf node"),
268            Self::Index(_bounds, children) => {
269                write!(f, "an index node with {} children", children.len())
270            }
271        }
272    }
273}