ts_bart/node/stride_ops/
prefix.rs1use ts_bitset::Bitset256;
2
3use crate::{BaseIndex, StrideBase};
4
5pub trait PrefixOps: PrefixReadOps {
7 fn insert_prefix(&mut self, idx: BaseIndex, value: Self::T) -> Option<Self::T>;
9 fn remove_prefix(&mut self, idx: BaseIndex) -> Option<Self::T>;
11 fn get_prefix_exact_mut(&mut self, idx: BaseIndex) -> Option<&mut Self::T>;
14}
15
16static_assertions::assert_obj_safe!(PrefixOps<T = ()>);
17
18impl<T> PrefixOps for &mut T
19where
20 T: PrefixOps + ?Sized,
21{
22 fn insert_prefix(&mut self, idx: BaseIndex, value: Self::T) -> Option<Self::T> {
23 (*self).insert_prefix(idx, value)
24 }
25
26 fn remove_prefix(&mut self, idx: BaseIndex) -> Option<Self::T> {
27 (*self).remove_prefix(idx)
28 }
29
30 fn get_prefix_exact_mut(&mut self, idx: BaseIndex) -> Option<&mut Self::T> {
31 (*self).get_prefix_exact_mut(idx)
32 }
33}
34
35pub trait PrefixReadOps: StrideBase {
37 fn prefix_bitset(&self) -> &Bitset256;
39 fn lookup_index(&self, idx: BaseIndex) -> Option<(BaseIndex, &Self::T)>;
41 fn get_prefix_exact(&self, idx: BaseIndex) -> Option<&Self::T>;
44
45 fn prefix_count(&self) -> usize {
47 self.prefix_bitset().count_ones()
48 }
49}
50
51static_assertions::assert_obj_safe!(PrefixReadOps<T = ()>);
52
53impl<T> PrefixReadOps for &T
54where
55 T: PrefixReadOps + ?Sized,
56{
57 fn prefix_bitset(&self) -> &Bitset256 {
58 (*self).prefix_bitset()
59 }
60
61 fn lookup_index(&self, idx: BaseIndex) -> Option<(BaseIndex, &Self::T)> {
62 (*self).lookup_index(idx)
63 }
64
65 fn get_prefix_exact(&self, idx: BaseIndex) -> Option<&Self::T> {
66 (*self).get_prefix_exact(idx)
67 }
68}
69
70impl<T> PrefixReadOps for &mut T
71where
72 T: PrefixReadOps + ?Sized,
73{
74 fn prefix_bitset(&self) -> &Bitset256 {
75 (**self).prefix_bitset()
76 }
77
78 fn lookup_index(&self, idx: BaseIndex) -> Option<(BaseIndex, &Self::T)> {
79 (**self).lookup_index(idx)
80 }
81
82 fn get_prefix_exact(&self, idx: BaseIndex) -> Option<&Self::T> {
83 (**self).get_prefix_exact(idx)
84 }
85}
86
87pub trait PrefixOpsExt: PrefixOps {
89 #[inline]
108 fn supersets_prefix(&self, idx: BaseIndex) -> bool {
109 use core::borrow::Borrow;
110 self.prefix_bitset().intersects(crate::lpm(idx).borrow())
111 }
112
113 #[inline]
118 fn lookup(&self, idx: BaseIndex) -> Option<&Self::T> {
119 let (_idx, ret) = self.lookup_index(idx)?;
120 Some(ret)
121 }
122
123 #[inline]
136 fn with_prefix(mut self, idx: BaseIndex, value: Self::T) -> Self
137 where
138 Self: Sized,
139 {
140 self.insert_prefix(idx, value);
141 self
142 }
143
144 fn matching_prefixes(&self, octet: u8) -> NodePrefixIter<'_, Self::T>
163 where
164 Self: Sized,
165 {
166 NodePrefixIter::for_octet(self, octet)
167 }
168}
169
170impl<T> PrefixOpsExt for T where T: PrefixOps + ?Sized {}
171
172pub struct NodePrefixIter<'n, T> {
174 node: &'n dyn PrefixReadOps<T = T>,
175 yield_state: Bitset256,
176}
177
178impl<'n, T> NodePrefixIter<'n, T>
179where
180 T: 'static,
181{
182 pub fn for_octet(node: &'n dyn PrefixReadOps<T = T>, octet: u8) -> Self {
185 use core::borrow::Borrow;
186
187 let idx = BaseIndex::from_pfx_7(octet);
188
189 let mut yield_state = *node.prefix_bitset();
190 yield_state.intersect_inplace(crate::lpm(idx).borrow());
191
192 Self { node, yield_state }
193 }
194}
195
196impl<'n, T> Iterator for NodePrefixIter<'n, T>
197where
198 T: 'static,
199{
200 type Item = (BaseIndex, &'n T);
201
202 fn next(&mut self) -> Option<Self::Item> {
203 while let Some(bit) = self.yield_state.last_set() {
204 self.yield_state.clear(bit);
205
206 let index = BaseIndex::new(bit as _);
207 if let Some(val) = self.node.get_prefix_exact(index) {
208 return Some((index, val));
209 }
210 }
211
212 None
213 }
214}
215
216impl<T> core::iter::FusedIterator for NodePrefixIter<'_, T> where T: 'static {}