1use core::{
8 borrow::Borrow,
9 fmt::{Debug, Formatter},
10};
11
12use ts_array256::{Array256, ArrayStorage};
13use ts_bitset::Bitset256;
14
15use crate::BaseIndex;
16
17mod child;
18mod child_storage;
19mod descendants;
20mod stride_ops;
21
22pub use child::Child;
23pub use child_storage::{BoxStorage, InlineStorage, Storage};
24pub use stride_ops::{
25 NodePrefixIter, PrefixOps, PrefixOpsExt, PrefixReadOps, Stats, StrideBase, StrideOps,
26 StrideOpsExt,
27};
28
29pub type DefaultStorage = BoxStorage;
34
35pub type DefaultNode<T> = Node<T, DefaultStorage>;
38
39cfg_if::cfg_if! {
40 if #[cfg(feature = "smallvec")] {
41 type ArrayStore<T> = smallvec::SmallVec<[T; 1]>;
46 } else {
47 type ArrayStore<T> = alloc::vec::Vec<T>;
49 }
50}
51
52#[derive(PartialEq, Eq, Hash)]
62pub struct Node<T, C = DefaultStorage>
63where
64 C: Storage + ?Sized,
65{
66 pub prefixes: Array256<ArrayStore<T>>,
72
73 pub children: Array256<ArrayStore<Child<C::Container<Self>, T>>>,
76}
77
78impl<T, C> Clone for Node<T, C>
79where
80 C: Storage + ?Sized,
81 T: Clone,
82{
83 #[inline]
84 fn clone(&self) -> Self {
85 Self {
86 prefixes: self.prefixes.clone(),
87 children: self.children.clone_with(&|c| match c {
88 Child::Path(p) => Child::Path(C::clone(p)),
89 Child::Fringe(p) => Child::Fringe(p.clone()),
90 Child::Leaf { prefix, value } => Child::Leaf {
91 prefix: *prefix,
92 value: value.clone(),
93 },
94 }),
95 }
96 }
97}
98
99impl<T, C> Debug for Node<T, C>
100where
101 T: Debug,
102 C: Storage + ?Sized,
103{
104 fn fmt(&self, f: &mut Formatter<'_>) -> core::fmt::Result {
105 struct IdArrayFormatter<'a, S> {
106 ary: &'a Array256<S>,
107 }
108
109 impl<S> Debug for IdArrayFormatter<'_, S>
110 where
111 S: ArrayStorage + AsRef<[S::T]>,
112 S::T: Debug,
113 {
114 fn fmt(&self, f: &mut Formatter<'_>) -> core::fmt::Result {
115 f.debug_map()
116 .entries(self.ary.bitset().bits().map(|i| {
117 (
118 BaseIndex::new(i as _).fmt_prefix(),
119 self.ary.get(i as _).unwrap(),
120 )
121 }))
122 .finish()
123 }
124 }
125
126 f.debug_struct("Node")
127 .field(
128 "prefixes",
129 &IdArrayFormatter {
130 ary: &self.prefixes,
131 },
132 )
133 .field(
134 "children",
135 &self
136 .children
137 .custom_storage_fmt(&Child::as_node_ref::<C, _>),
138 )
139 .finish()
140 }
141}
142
143impl<T, C> Default for Node<T, C>
144where
145 C: Storage + ?Sized,
146{
147 #[inline]
148 fn default() -> Self {
149 Self::EMPTY
150 }
151}
152
153impl<T, C> Node<T, C>
154where
155 C: Storage + ?Sized,
156{
157 pub const EMPTY: Self = Self {
159 prefixes: Array256::EMPTY,
160 children: Array256::EMPTY,
161 };
162
163 #[inline]
165 pub const fn is_empty(&self) -> bool {
166 self.prefixes.is_empty() && self.children.is_empty()
167 }
168
169 pub fn stats(&self) -> Stats
171 where
172 Self: StrideOps,
173 {
174 self.descendant_nodes(true)
175 .fold(Stats::default(), |mut stats, (_path, node)| {
176 let (leaves, fringes) = node.direct_children().fold(
177 (0, 0),
178 |(leaves, fringes), (_, child)| match child {
179 Child::Fringe(..) => (leaves, fringes + 1),
180 Child::Leaf { .. } => (leaves + 1, fringes),
181 _ => (leaves, fringes),
182 },
183 );
184
185 stats.node_count += 1;
186
187 stats.prefix_count += node.prefix_count();
188 stats.child_count += node.child_count();
189
190 stats.leaf_count += leaves;
191 stats.fringe_count += fringes;
192
193 stats
194 })
195 }
196}
197
198impl<T, C> StrideBase for Node<T, C>
199where
200 T: 'static,
201 C: Storage + ?Sized,
202{
203 type T = T;
204}
205
206impl<T, C> PrefixReadOps for Node<T, C>
207where
208 T: 'static,
209 C: Storage + ?Sized,
210{
211 fn prefix_bitset(&self) -> &Bitset256 {
212 self.prefixes.bitset()
213 }
214
215 fn prefix_count(&self) -> usize {
216 self.prefixes.len()
217 }
218
219 fn lookup_index(&self, idx: BaseIndex) -> Option<(BaseIndex, &Self::T)> {
220 let top = self.prefixes.intersection_top(crate::lpm(idx).borrow())?;
221 Some((BaseIndex::try_new(top)?, self.prefixes.get(top)?))
222 }
223
224 fn get_prefix_exact(&self, idx: BaseIndex) -> Option<&Self::T> {
225 self.prefixes.get(idx.get())
226 }
227}
228
229impl<T, C> PrefixOps for Node<T, C>
230where
231 T: 'static,
232 C: Storage + ?Sized,
233{
234 fn insert_prefix(&mut self, idx: BaseIndex, value: Self::T) -> Option<Self::T> {
235 self.prefixes.insert(idx.into(), value)
236 }
237
238 fn remove_prefix(&mut self, idx: BaseIndex) -> Option<Self::T> {
239 self.prefixes.remove(idx.into())
240 }
241
242 fn get_prefix_exact_mut(&mut self, idx: BaseIndex) -> Option<&mut Self::T> {
243 self.prefixes.get_mut(idx.get())
244 }
245}
246
247impl<T, C> StrideOps for Node<T, C>
248where
249 T: 'static,
250 C: Storage + ?Sized,
251{
252 fn child_bitset(&self) -> &Bitset256 {
253 self.children.bitset()
254 }
255
256 fn child_count(&self) -> usize {
257 self.children.len()
258 }
259
260 fn stats(&self) -> Stats {
261 self.stats()
262 }
263
264 fn insert_child(
265 &mut self,
266 addr: u8,
267 child: Child<Self, Self::T>,
268 ) -> Option<Child<Self, Self::T>> {
269 self.children
270 .insert(addr, child.map_node(C::new))
271 .map(|ret| ret.map_node(C::into_inner))
272 }
273
274 fn direct_children(&self) -> impl Iterator<Item = (u8, Child<&Self, &T>)> {
275 self.children
276 .iter()
277 .map(|(addr, child)| (addr, child.as_node_ref::<C, _>()))
278 }
279
280 fn remove_child(&mut self, addr: u8) -> Option<Child<Self, Self::T>> {
281 self.children
282 .remove(addr)
283 .map(|ret| ret.map_node(C::into_inner))
284 }
285
286 fn get_child(&self, addr: u8) -> Option<Child<&Self, &Self::T>> {
287 self.children.get(addr).map(Child::as_node_ref::<C, _>)
288 }
289
290 fn get_child_mut(&mut self, addr: u8) -> Option<Child<&mut Self, &mut Self::T>> {
291 self.children.get_mut(addr).map(Child::as_node_mut::<C, _>)
292 }
293
294 fn direct_prefixes(&self) -> impl Iterator<Item = (BaseIndex, &T)> {
295 self.prefixes
296 .iter()
297 .map(|(idx, value)| (BaseIndex::new(idx), value))
298 }
299}
300
301#[cfg(test)]
302mod test {
303 use super::*;
304
305 #[test]
306 fn bart_examples_prefix_crud() {
307 let mut node = Node::<usize>::EMPTY;
308 let index = BaseIndex::new(32);
309
310 assert_eq!(None, node.insert_prefix(index, 100));
311 assert_eq!(1, node.prefix_count());
312
313 assert_eq!(Some(100), node.insert_prefix(index, 111));
314 assert_eq!(1, node.prefix_count());
315 assert_eq!(Some(111), node.lookup(index).copied());
316
317 assert_eq!(Some(111), node.remove_prefix(index));
318 assert_eq!(0, node.prefix_count());
319 assert_eq!(None, node.lookup(index));
320 assert_eq!(None, node.remove_prefix(index));
321 }
322
323 #[test]
324 fn bart_examples_contains() {
325 let mut node = Node::<()>::EMPTY;
326 node.insert_prefix(BaseIndex::new(32), ());
327
328 for idx in [32, 64, 65, 128, 129, 130, 131] {
329 assert!(node.supersets_prefix(BaseIndex::new(idx)));
330 }
331
332 for idx in [1, 16, 33, 63, 127, 132, 255] {
333 assert!(!node.supersets_prefix(BaseIndex::new(idx)));
334 }
335 }
336
337 #[test]
338 fn bart_examples_lookup() {
339 let mut node = Node::<usize>::EMPTY;
340
341 node.insert_prefix(BaseIndex::new(32), 1);
342 node.insert_prefix(BaseIndex::new(64), 2);
343
344 assert_eq!(Some(&2), node.lookup(BaseIndex::new(128)));
345 assert_eq!(
346 Some((BaseIndex::new(64), &2)),
347 node.lookup_index(BaseIndex::new(128))
348 );
349 assert_eq!(None, node.lookup(BaseIndex::new(127)));
350 }
351
352 #[test]
353 fn bart_examples_children_crud() {
354 let mut child = Node::<usize>::EMPTY;
355 child.insert_prefix(BaseIndex::new(1), 10);
356
357 let mut node = Node::<usize>::EMPTY;
358 assert!(node.insert_child(10, Child::Path(child)).is_none());
359 assert_eq!(1, node.child_count());
360
361 assert!(node.get_child(10).is_some_and(|c| match c {
362 Child::Path(inner) => inner.supersets_prefix(BaseIndex::new(1)),
363 _ => false,
364 }));
365
366 assert!(node.remove_child(10).is_some());
367 assert_eq!(0, node.child_count());
368 assert!(node.remove_child(10).is_none());
369 }
370}