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
18pub 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 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 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 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 (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#[derive(Clone)]
137pub enum Node<N> {
138 Index(N, Vec<Uuid>),
139 Leaf(N),
140}
141
142impl<N> Node<N> {
143 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}