prefix_trie/rkyv/map.rs
1//! Module containing the archived prefix map and access methods.
2
3use std::marker::PhantomData;
4
5#[repr(transparent)]
6#[derive(Portable, CheckBytes)]
7#[bytecheck(crate = rkyv::bytecheck)]
8pub(super) struct MyPhantomData<T>(pub(super) PhantomData<T>);
9
10// Safety: PhantomData is zero-sized, so it cannot have an undefined value by definition.
11unsafe impl<T> NoUndef for MyPhantomData<T> {}
12
13use num_traits::{CheckedAdd, One, Zero};
14use rkyv::{
15 bytecheck::CheckBytes,
16 traits::NoUndef,
17 vec::{ArchivedVec, VecResolver},
18 Archive, Portable, Serialize,
19};
20
21use crate::{
22 aggregate::{fold_coverage, member_coverage},
23 allocator::compute_slot,
24 node::{
25 child_bit, child_cover_mask, child_cover_mask_for_bit, data_bit, data_cover_mask,
26 data_lpm_mask, extend_repr, lex_after_child, lex_after_data, Key, LexElem,
27 DATA_BIT_TO_PREFIX, LEX_ORDER,
28 },
29 table::{reconstruct_prefix, K, NUM_CHILDREN, NUM_DATA},
30 Prefix,
31};
32// needed for doc references.
33#[allow(unused_imports)]
34use crate::{PrefixMap, PrefixSet};
35
36/// Archived (immutable) version of a [`PrefixMap`].
37///
38/// Any (verified) archived prefix map is canonical and has the following properties:
39/// - The tree is stored as BFS (ordered per level).
40/// - Data is stored contiguously without empty (uninitialized) memory in between.
41/// - The root node is always present.
42/// - No node (except the root) may be emtpy.
43///
44/// Due to these properties, assuming that T is also canonical (i.e., has only one possible
45/// representation), you can compare two `ArchivedPrefixMap`s for equality by comparing their byte
46/// string.
47#[repr(C)]
48#[derive(Portable, CheckBytes)]
49#[bytecheck(verify, crate = rkyv::bytecheck)]
50pub struct ArchivedPrefixMap<P, T: Archive> {
51 pub(super) nodes: ArchivedVec<ArchivedNodeRepr>,
52 pub(super) data: ArchivedVec<T::Archived>,
53 pub(super) marker: MyPhantomData<P>,
54}
55
56impl<P, T: Archive> ArchivedPrefixMap<P, T> {
57 /// Returns the number of entries stored in the map.
58 ///
59 /// This is the number of stored prefixes, not the number of addresses they cover (see
60 /// [`address_count`](Self::address_count)).
61 pub fn len(&self) -> usize {
62 self.data.len()
63 }
64
65 /// Returns `true` if the map contains no entries.
66 pub fn is_empty(&self) -> bool {
67 self.data.is_empty()
68 }
69}
70
71impl<P: Prefix, T: Archive> ArchivedPrefixMap<P, T> {
72 /// Count the number of unique addresses covered by all prefixes in the map. If the entire trie
73 /// is fully covered, the function returns `None` (as it contains `P::R::MAX + 1` addresses).
74 /// Overlapping prefixes are not double-counted.
75 ///
76 /// To avoid double-counting, the function traverses the (partial) trie once, skipping nodes
77 /// that are already covered.
78 ///
79 /// This mirrors [`PrefixMap::address_count`], but operates on the archived map.
80 ///
81 /// ```
82 /// # use prefix_trie::PrefixMap;
83 /// # use prefix_trie::rkyv::ArchivedPrefixMap;
84 /// # use rkyv::rancor::Error;
85 /// # #[cfg(all(feature = "rkyv", feature = "ipnet"))]
86 /// # fn main() -> Result<(), Box<dyn std::error::Error>> {
87 /// # type P = ipnet::Ipv4Net;
88 /// # macro_rules! p { ($s:literal) => { $s.parse::<P>()? } }
89 /// let mut pm = PrefixMap::<P, i32>::new();
90 /// pm.insert(p!("192.0.2.0/24"), 1);
91 /// pm.insert(p!("192.0.2.128/25"), 2);
92 /// pm.insert(p!("198.51.100.0/24"), 3);
93 ///
94 /// let bytes = rkyv::to_bytes::<Error>(&pm)?;
95 /// let map: &ArchivedPrefixMap<P, i32> = rkyv::access::<_, Error>(&bytes)?;
96 ///
97 /// assert_eq!(map.address_count(), Some(512));
98 /// # Ok(())
99 /// # }
100 /// # #[cfg(not(all(feature = "rkyv", feature = "ipnet")))]
101 /// # fn main() {}
102 /// ```
103 pub fn address_count(&self) -> Option<P::R> {
104 // check if the trie is fully covered by a single root node
105 if self.nodes[0].has_data_bit(0) {
106 return None;
107 }
108 // otherwise, traverse the tree
109 self.address_count_at(0, 0)
110 }
111
112 /// Get the value stored at exactly `prefix`.
113 ///
114 /// This mirrors [`PrefixMap::get`], but operates on the archived map and yields a reference to
115 /// the archived value.
116 ///
117 /// ```
118 /// # use prefix_trie::PrefixMap;
119 /// # use prefix_trie::rkyv::ArchivedPrefixMap;
120 /// # use rkyv::rancor::Error;
121 /// # #[cfg(all(feature = "rkyv", feature = "ipnet"))]
122 /// # fn main() -> Result<(), Box<dyn std::error::Error>> {
123 /// # type P = ipnet::Ipv4Net;
124 /// # macro_rules! p { ($s:literal) => { $s.parse::<P>()? } }
125 /// let mut pm = PrefixMap::<P, i32>::new();
126 /// pm.insert(p!("10.0.1.0/24"), 1);
127 ///
128 /// let bytes = rkyv::to_bytes::<Error>(&pm)?;
129 /// let map: &ArchivedPrefixMap<P, i32> = rkyv::access::<_, Error>(&bytes)?;
130 ///
131 /// assert_eq!(map.get(&p!("10.0.1.0/24")).map(|v| v.to_native()), Some(1));
132 /// assert_eq!(map.get(&p!("10.0.2.0/24")), None);
133 /// assert_eq!(map.get(&p!("10.0.0.0/23")), None);
134 /// assert_eq!(map.get(&p!("10.0.1.128/25")), None);
135 /// # Ok(())
136 /// # }
137 /// # #[cfg(not(all(feature = "rkyv", feature = "ipnet")))]
138 /// # fn main() {}
139 /// ```
140 pub fn get<'a>(&'a self, prefix: &P) -> Option<&'a T::Archived> {
141 let (key, prefix_len) = key_prefix_len(prefix);
142 let (loc, _) = self.find_loc(key, prefix_len)?;
143 let bit = data_bit(key, prefix_len);
144 let data_loc = self.nodes[loc.idx()].data_loc(bit)?;
145 Some(&self.data[data_loc.idx()])
146 }
147
148 /// Check whether `prefix` is present in the map.
149 ///
150 /// This mirrors [`PrefixMap::contains_key`], but operates on the archived map.
151 ///
152 /// ```
153 /// # use prefix_trie::PrefixMap;
154 /// # use prefix_trie::rkyv::ArchivedPrefixMap;
155 /// # use rkyv::rancor::Error;
156 /// # #[cfg(all(feature = "rkyv", feature = "ipnet"))]
157 /// # fn main() -> Result<(), Box<dyn std::error::Error>> {
158 /// # type P = ipnet::Ipv4Net;
159 /// # macro_rules! p { ($s:literal) => { $s.parse::<P>()? } }
160 /// let mut pm = PrefixMap::<P, i32>::new();
161 /// pm.insert(p!("10.0.1.0/24"), 1);
162 ///
163 /// let bytes = rkyv::to_bytes::<Error>(&pm)?;
164 /// let map: &ArchivedPrefixMap<P, i32> = rkyv::access::<_, Error>(&bytes)?;
165 ///
166 /// assert!(map.contains_key(&p!("10.0.1.0/24")));
167 /// assert!(!map.contains_key(&p!("10.0.2.0/24")));
168 /// assert!(!map.contains_key(&p!("10.0.0.0/23")));
169 /// assert!(!map.contains_key(&p!("10.0.1.128/25")));
170 /// # Ok(())
171 /// # }
172 /// # #[cfg(not(all(feature = "rkyv", feature = "ipnet")))]
173 /// # fn main() {}
174 /// ```
175 pub fn contains_key(&self, prefix: &P) -> bool {
176 let (key, prefix_len) = key_prefix_len(prefix);
177 let Some((loc, _)) = self.find_loc(key, prefix_len) else {
178 return false;
179 };
180 let bit = data_bit(key, prefix_len);
181 self.nodes[loc.idx()].data_loc(bit).is_some()
182 }
183
184 /// Get the value stored at exactly `prefix`, together with the canonical matched prefix.
185 ///
186 /// **Warning**: The table does not store the prefix, but it is reconstructed. This means that
187 /// any bits in the host part will be truncated.
188 ///
189 /// This mirrors [`PrefixMap::get_key_value`], but operates on the archived map and yields a
190 /// reference to the archived value.
191 ///
192 /// ```
193 /// # use prefix_trie::PrefixMap;
194 /// # use prefix_trie::rkyv::ArchivedPrefixMap;
195 /// # use rkyv::rancor::Error;
196 /// # #[cfg(all(feature = "rkyv", feature = "ipnet"))]
197 /// # fn main() -> Result<(), Box<dyn std::error::Error>> {
198 /// # type P = ipnet::Ipv4Net;
199 /// # macro_rules! p { ($s:literal) => { $s.parse::<P>()? } }
200 /// let prefix = p!("10.0.1.0/24");
201 /// let mut pm = PrefixMap::<P, i32>::new();
202 /// pm.insert(prefix, 1);
203 ///
204 /// let bytes = rkyv::to_bytes::<Error>(&pm)?;
205 /// let map: &ArchivedPrefixMap<P, i32> = rkyv::access::<_, Error>(&bytes)?;
206 ///
207 /// let (key, value) = map.get_key_value(&prefix).unwrap();
208 /// assert_eq!((key, value.to_native()), (prefix, 1));
209 /// # Ok(())
210 /// # }
211 /// # #[cfg(not(all(feature = "rkyv", feature = "ipnet")))]
212 /// # fn main() {}
213 /// ```
214 pub fn get_key_value<'a>(&'a self, prefix: &P) -> Option<(P, &'a T::Archived)> {
215 let (key, prefix_len) = key_prefix_len(prefix);
216 let (loc, depth) = self.find_loc(key, prefix_len)?;
217 let bit = data_bit(key, prefix_len);
218 let data_loc = self.nodes[loc.idx()].data_loc(bit)?;
219 let prefix = reconstruct_prefix(key, depth, data_loc.bit as usize);
220 Some((prefix, &self.data[data_loc.idx()]))
221 }
222
223 /// Get the longest prefix in the map that contains `prefix`, together with its value.
224 ///
225 /// This mirrors [`PrefixMap::get_lpm`], but operates on the archived map and yields a reference
226 /// to the archived value.
227 ///
228 /// ```
229 /// # use prefix_trie::PrefixMap;
230 /// # use prefix_trie::rkyv::ArchivedPrefixMap;
231 /// # use rkyv::rancor::Error;
232 /// # #[cfg(all(feature = "rkyv", feature = "ipnet"))]
233 /// # fn main() -> Result<(), Box<dyn std::error::Error>> {
234 /// # type P = ipnet::Ipv4Net;
235 /// # macro_rules! p { ($s:literal) => { $s.parse::<P>()? } }
236 /// let mut pm = PrefixMap::<P, i32>::new();
237 /// pm.insert(p!("10.0.1.0/24"), 1);
238 /// pm.insert(p!("10.0.0.0/23"), 2);
239 ///
240 /// let bytes = rkyv::to_bytes::<Error>(&pm)?;
241 /// let map: &ArchivedPrefixMap<P, i32> = rkyv::access::<_, Error>(&bytes)?;
242 ///
243 /// let lpm = |s| map.get_lpm(&s).map(|(p, v)| (p, v.to_native()));
244 /// assert_eq!(lpm(p!("10.0.1.1/32")), Some((p!("10.0.1.0/24"), 1)));
245 /// assert_eq!(lpm(p!("10.0.1.0/24")), Some((p!("10.0.1.0/24"), 1)));
246 /// assert_eq!(lpm(p!("10.0.0.0/24")), Some((p!("10.0.0.0/23"), 2)));
247 /// assert_eq!(lpm(p!("10.0.2.0/24")), None);
248 /// # Ok(())
249 /// # }
250 /// # #[cfg(not(all(feature = "rkyv", feature = "ipnet")))]
251 /// # fn main() {}
252 /// ```
253 pub fn get_lpm<'a>(&'a self, prefix: &P) -> Option<(P, &'a T::Archived)> {
254 let (key, prefix_len) = key_prefix_len(prefix);
255 let (data_loc, depth) = self.find_lpm(key, prefix_len)?;
256 let prefix = reconstruct_prefix(key, depth, data_loc.bit as usize);
257 Some((prefix, &self.data[data_loc.idx()]))
258 }
259
260 /// Get the longest prefix in the map that contains `prefix`.
261 ///
262 /// This mirrors [`PrefixMap::get_lpm_prefix`], but operates on the archived map.
263 ///
264 /// ```
265 /// # use prefix_trie::PrefixMap;
266 /// # use prefix_trie::rkyv::ArchivedPrefixMap;
267 /// # use rkyv::rancor::Error;
268 /// # #[cfg(all(feature = "rkyv", feature = "ipnet"))]
269 /// # fn main() -> Result<(), Box<dyn std::error::Error>> {
270 /// # type P = ipnet::Ipv4Net;
271 /// # macro_rules! p { ($s:literal) => { $s.parse::<P>()? } }
272 /// let mut pm = PrefixMap::<P, i32>::new();
273 /// pm.insert(p!("10.0.1.0/24"), 1);
274 /// pm.insert(p!("10.0.0.0/23"), 2);
275 ///
276 /// let bytes = rkyv::to_bytes::<Error>(&pm)?;
277 /// let map: &ArchivedPrefixMap<P, i32> = rkyv::access::<_, Error>(&bytes)?;
278 ///
279 /// assert_eq!(map.get_lpm_prefix(&p!("10.0.1.1/32")), Some(p!("10.0.1.0/24")));
280 /// assert_eq!(map.get_lpm_prefix(&p!("10.0.0.0/24")), Some(p!("10.0.0.0/23")));
281 /// assert_eq!(map.get_lpm_prefix(&p!("10.0.2.0/24")), None);
282 /// # Ok(())
283 /// # }
284 /// # #[cfg(not(all(feature = "rkyv", feature = "ipnet")))]
285 /// # fn main() {}
286 /// ```
287 pub fn get_lpm_prefix(&self, prefix: &P) -> Option<P> {
288 let (key, prefix_len) = key_prefix_len(prefix);
289 let (data_loc, depth) = self.find_lpm(key, prefix_len)?;
290 let prefix = reconstruct_prefix(key, depth, data_loc.bit as usize);
291 Some(prefix)
292 }
293
294 /// Get the shortest prefix in the map that contains `prefix`, together with its value.
295 ///
296 /// This mirrors [`PrefixMap::get_spm`], but operates on the archived map and yields a reference
297 /// to the archived value.
298 ///
299 /// ```
300 /// # use prefix_trie::PrefixMap;
301 /// # use prefix_trie::rkyv::ArchivedPrefixMap;
302 /// # use rkyv::rancor::Error;
303 /// # #[cfg(all(feature = "rkyv", feature = "ipnet"))]
304 /// # fn main() -> Result<(), Box<dyn std::error::Error>> {
305 /// # type P = ipnet::Ipv4Net;
306 /// # macro_rules! p { ($s:literal) => { $s.parse::<P>()? } }
307 /// let mut pm = PrefixMap::<P, i32>::new();
308 /// pm.insert(p!("10.0.1.0/24"), 1);
309 /// pm.insert(p!("10.0.0.0/23"), 2);
310 ///
311 /// let bytes = rkyv::to_bytes::<Error>(&pm)?;
312 /// let map: &ArchivedPrefixMap<P, i32> = rkyv::access::<_, Error>(&bytes)?;
313 ///
314 /// let spm = |s| map.get_spm(&s).map(|(p, v)| (p, v.to_native()));
315 /// assert_eq!(spm(p!("10.0.1.1/32")), Some((p!("10.0.0.0/23"), 2)));
316 /// assert_eq!(spm(p!("10.0.1.0/24")), Some((p!("10.0.0.0/23"), 2)));
317 /// assert_eq!(spm(p!("10.0.0.0/23")), Some((p!("10.0.0.0/23"), 2)));
318 /// assert_eq!(spm(p!("10.0.2.0/24")), None);
319 /// # Ok(())
320 /// # }
321 /// # #[cfg(not(all(feature = "rkyv", feature = "ipnet")))]
322 /// # fn main() {}
323 /// ```
324 pub fn get_spm<'a>(&'a self, prefix: &P) -> Option<(P, &'a T::Archived)> {
325 let (key, prefix_len) = key_prefix_len(prefix);
326 let (data_loc, depth) = self.find_spm(key, prefix_len)?;
327 let prefix = reconstruct_prefix(key, depth, data_loc.bit as usize);
328 Some((prefix, &self.data[data_loc.idx()]))
329 }
330
331 /// Get the shortest prefix in the map that contains `prefix`.
332 ///
333 /// This mirrors [`PrefixMap::get_spm_prefix`], but operates on the archived map.
334 ///
335 /// ```
336 /// # use prefix_trie::PrefixMap;
337 /// # use prefix_trie::rkyv::ArchivedPrefixMap;
338 /// # use rkyv::rancor::Error;
339 /// # #[cfg(all(feature = "rkyv", feature = "ipnet"))]
340 /// # fn main() -> Result<(), Box<dyn std::error::Error>> {
341 /// # type P = ipnet::Ipv4Net;
342 /// # macro_rules! p { ($s:literal) => { $s.parse::<P>()? } }
343 /// let mut pm = PrefixMap::<P, i32>::new();
344 /// pm.insert(p!("10.0.1.0/24"), 1);
345 /// pm.insert(p!("10.0.0.0/23"), 2);
346 ///
347 /// let bytes = rkyv::to_bytes::<Error>(&pm)?;
348 /// let map: &ArchivedPrefixMap<P, i32> = rkyv::access::<_, Error>(&bytes)?;
349 ///
350 /// assert_eq!(map.get_spm_prefix(&p!("10.0.1.1/32")), Some(p!("10.0.0.0/23")));
351 /// assert_eq!(map.get_spm_prefix(&p!("10.0.0.0/23")), Some(p!("10.0.0.0/23")));
352 /// assert_eq!(map.get_spm_prefix(&p!("10.0.2.0/24")), None);
353 /// # Ok(())
354 /// # }
355 /// # #[cfg(not(all(feature = "rkyv", feature = "ipnet")))]
356 /// # fn main() {}
357 /// ```
358 pub fn get_spm_prefix(&self, prefix: &P) -> Option<P> {
359 let (key, prefix_len) = key_prefix_len(prefix);
360 let (data_loc, depth) = self.find_spm(key, prefix_len)?;
361 let prefix = reconstruct_prefix(key, depth, data_loc.bit as usize);
362 Some(prefix)
363 }
364
365 /// Check whether `prefix` is covered by the map, i.e., whether the map contains an entry at
366 /// `prefix` itself or any less-specific prefix that contains it.
367 ///
368 /// This function does not perform aggregation. That means that, even if both the left and
369 /// right children of `p` are present in the map, `is_covered(p)` may still return `false`. See
370 /// [`is_covered_in_aggregate`](Self::is_covered_in_aggregate) for that case.
371 ///
372 /// This mirrors [`PrefixMap::is_covered`], but operates on the archived map.
373 ///
374 /// ```
375 /// # use prefix_trie::PrefixMap;
376 /// # use prefix_trie::rkyv::ArchivedPrefixMap;
377 /// # use rkyv::rancor::Error;
378 /// # #[cfg(all(feature = "rkyv", feature = "ipnet"))]
379 /// # fn main() -> Result<(), Box<dyn std::error::Error>> {
380 /// # type P = ipnet::Ipv4Net;
381 /// # macro_rules! p { ($s:literal) => { $s.parse::<P>()? } }
382 /// let mut pm = PrefixMap::<P, i32>::new();
383 /// pm.insert(p!("10.0.0.0/8"), 1);
384 ///
385 /// let bytes = rkyv::to_bytes::<Error>(&pm)?;
386 /// let map: &ArchivedPrefixMap<P, i32> = rkyv::access::<_, Error>(&bytes)?;
387 ///
388 /// assert!(map.is_covered(&p!("10.0.0.0/8")));
389 /// assert!(map.is_covered(&p!("10.1.2.0/24")));
390 /// assert!(!map.is_covered(&p!("11.0.0.0/8")));
391 /// # Ok(())
392 /// # }
393 /// # #[cfg(not(all(feature = "rkyv", feature = "ipnet")))]
394 /// # fn main() {}
395 /// ```
396 #[inline(always)]
397 pub fn is_covered(&self, prefix: &P) -> bool {
398 self.get_spm_prefix(prefix).is_some()
399 }
400
401 /// Check whether every address in `prefix` is covered by the map, i.e., whether `prefix`'s
402 /// entire range is tiled by entries in the map, even if no single entry covers `prefix` on its
403 /// own. See [`is_covered`](Self::is_covered) for the (cheaper, stricter) single-entry check.
404 ///
405 /// This mirrors [`PrefixMap::is_covered_in_aggregate`], but operates on the archived map.
406 ///
407 /// ```
408 /// # use prefix_trie::PrefixMap;
409 /// # use prefix_trie::rkyv::ArchivedPrefixMap;
410 /// # use rkyv::rancor::Error;
411 /// # #[cfg(all(feature = "rkyv", feature = "ipnet"))]
412 /// # fn main() -> Result<(), Box<dyn std::error::Error>> {
413 /// # type P = ipnet::Ipv4Net;
414 /// # macro_rules! p { ($s:literal) => { $s.parse::<P>()? } }
415 /// let mut pm = PrefixMap::<P, i32>::new();
416 /// pm.insert(p!("10.0.0.0/9"), 1);
417 /// pm.insert(p!("10.128.0.0/9"), 2);
418 ///
419 /// let bytes = rkyv::to_bytes::<Error>(&pm)?;
420 /// let map: &ArchivedPrefixMap<P, i32> = rkyv::access::<_, Error>(&bytes)?;
421 ///
422 /// assert!(!map.is_covered(&p!("10.0.0.0/8")));
423 /// assert!(map.is_covered_in_aggregate(&p!("10.0.0.0/8")));
424 /// # Ok(())
425 /// # }
426 /// # #[cfg(not(all(feature = "rkyv", feature = "ipnet")))]
427 /// # fn main() {}
428 /// ```
429 pub fn is_covered_in_aggregate(&self, prefix: &P) -> bool {
430 let (key, prefix_len) = key_prefix_len(prefix);
431 self.covers_in_aggregate(key, prefix_len)
432 }
433
434 /// An iterator visiting all key-value pairs in lexicographic order. The iterator element type
435 /// is `(P, &T::Archived)`, with reconstructed prefixes `P`.
436 ///
437 /// This mirrors [`PrefixMap::iter`], but operates on the archived map and yields references to
438 /// archived values.
439 ///
440 /// ```
441 /// # use prefix_trie::PrefixMap;
442 /// # use prefix_trie::rkyv::ArchivedPrefixMap;
443 /// # use rkyv::rancor::Error;
444 /// # #[cfg(all(feature = "rkyv", feature = "ipnet"))]
445 /// # fn main() -> Result<(), Box<dyn std::error::Error>> {
446 /// # type P = ipnet::Ipv4Net;
447 /// # macro_rules! p { ($s:literal) => { $s.parse::<P>()? } }
448 /// let mut pm = PrefixMap::<P, i32>::new();
449 /// pm.insert(p!("10.0.0.0/22"), 1);
450 /// pm.insert(p!("10.0.0.0/23"), 2);
451 /// pm.insert(p!("10.0.2.0/23"), 3);
452 /// pm.insert(p!("10.0.0.0/24"), 4);
453 /// pm.insert(p!("10.0.2.0/24"), 5);
454 ///
455 /// let bytes = rkyv::to_bytes::<Error>(&pm)?;
456 /// let map: &ArchivedPrefixMap<P, i32> = rkyv::access::<_, Error>(&bytes)?;
457 ///
458 /// assert_eq!(
459 /// map.iter().map(|(p, v)| (p, v.to_native())).collect::<Vec<_>>(),
460 /// vec![
461 /// (p!("10.0.0.0/22"), 1),
462 /// (p!("10.0.0.0/23"), 2),
463 /// (p!("10.0.0.0/24"), 4),
464 /// (p!("10.0.2.0/23"), 3),
465 /// (p!("10.0.2.0/24"), 5),
466 /// ],
467 /// );
468 /// # Ok(())
469 /// # }
470 /// # #[cfg(not(all(feature = "rkyv", feature = "ipnet")))]
471 /// # fn main() {}
472 /// ```
473 pub fn iter(&self) -> Iter<'_, P, T> {
474 Iter::new(self)
475 }
476
477 /// An iterator visiting all keys in lexicographic order. The iterator element type is
478 /// reconstructed prefixes `P`.
479 ///
480 /// This mirrors [`PrefixMap::keys`], but operates on the archived map.
481 ///
482 /// ```
483 /// # use prefix_trie::PrefixMap;
484 /// # use prefix_trie::rkyv::ArchivedPrefixMap;
485 /// # use rkyv::rancor::Error;
486 /// # #[cfg(all(feature = "rkyv", feature = "ipnet"))]
487 /// # fn main() -> Result<(), Box<dyn std::error::Error>> {
488 /// # type P = ipnet::Ipv4Net;
489 /// # macro_rules! p { ($s:literal) => { $s.parse::<P>()? } }
490 /// let mut pm = PrefixMap::<P, i32>::new();
491 /// pm.insert(p!("10.0.0.0/22"), 1);
492 /// pm.insert(p!("10.0.0.0/23"), 2);
493 /// pm.insert(p!("10.0.2.0/23"), 3);
494 /// pm.insert(p!("10.0.0.0/24"), 4);
495 /// pm.insert(p!("10.0.2.0/24"), 5);
496 ///
497 /// let bytes = rkyv::to_bytes::<Error>(&pm)?;
498 /// let map: &ArchivedPrefixMap<P, i32> = rkyv::access::<_, Error>(&bytes)?;
499 ///
500 /// assert_eq!(
501 /// map.keys().collect::<Vec<_>>(),
502 /// vec![
503 /// p!("10.0.0.0/22"),
504 /// p!("10.0.0.0/23"),
505 /// p!("10.0.0.0/24"),
506 /// p!("10.0.2.0/23"),
507 /// p!("10.0.2.0/24"),
508 /// ],
509 /// );
510 /// # Ok(())
511 /// # }
512 /// # #[cfg(not(all(feature = "rkyv", feature = "ipnet")))]
513 /// # fn main() {}
514 /// ```
515 pub fn keys(&self) -> Keys<'_, P, T> {
516 Keys(Iter::new(self))
517 }
518
519 /// An iterator visiting all values in lexicographic order. The iterator element type is
520 /// `&T::Archived`.
521 ///
522 /// This mirrors [`PrefixMap::values`], but operates on the archived map and yields references to
523 /// archived values.
524 ///
525 /// ```
526 /// # use prefix_trie::PrefixMap;
527 /// # use prefix_trie::rkyv::ArchivedPrefixMap;
528 /// # use rkyv::rancor::Error;
529 /// # #[cfg(all(feature = "rkyv", feature = "ipnet"))]
530 /// # fn main() -> Result<(), Box<dyn std::error::Error>> {
531 /// # type P = ipnet::Ipv4Net;
532 /// # macro_rules! p { ($s:literal) => { $s.parse::<P>()? } }
533 /// let mut pm = PrefixMap::<P, i32>::new();
534 /// pm.insert(p!("10.0.0.0/22"), 1);
535 /// pm.insert(p!("10.0.0.0/23"), 2);
536 /// pm.insert(p!("10.0.2.0/23"), 3);
537 /// pm.insert(p!("10.0.0.0/24"), 4);
538 /// pm.insert(p!("10.0.2.0/24"), 5);
539 ///
540 /// let bytes = rkyv::to_bytes::<Error>(&pm)?;
541 /// let map: &ArchivedPrefixMap<P, i32> = rkyv::access::<_, Error>(&bytes)?;
542 ///
543 /// assert_eq!(
544 /// map.values().map(|v| v.to_native()).collect::<Vec<_>>(),
545 /// vec![1, 2, 4, 3, 5],
546 /// );
547 /// # Ok(())
548 /// # }
549 /// # #[cfg(not(all(feature = "rkyv", feature = "ipnet")))]
550 /// # fn main() {}
551 /// ```
552 pub fn values(&self) -> Values<'_, P, T> {
553 Values(Iter::new(self))
554 }
555
556 /// Iterate over `prefix` and all more-specific entries contained within it, including `prefix`
557 /// itself if it is present. The iterator yields `(P, &'a T)`, with reconstructed prefixes `P`,
558 /// in lexicographic order.
559 ///
560 /// **Note**: Consider using [`crate::AsView::view_at`] as an alternative.
561 ///
562 /// This mirrors [`PrefixMap::children`], but operates on the archived map and yields references
563 /// to archived values.
564 ///
565 /// ```
566 /// # use prefix_trie::PrefixMap;
567 /// # use prefix_trie::rkyv::ArchivedPrefixMap;
568 /// # use rkyv::rancor::Error;
569 /// # #[cfg(all(feature = "rkyv", feature = "ipnet"))]
570 /// # fn main() -> Result<(), Box<dyn std::error::Error>> {
571 /// # type P = ipnet::Ipv4Net;
572 /// # macro_rules! p { ($s:literal) => { $s.parse::<P>()? } }
573 /// let mut pm = PrefixMap::<P, i32>::new();
574 /// pm.insert(p!("10.0.0.0/22"), 1);
575 /// pm.insert(p!("10.0.0.0/23"), 2);
576 /// pm.insert(p!("10.0.2.0/23"), 3);
577 /// pm.insert(p!("10.0.0.0/24"), 4);
578 /// pm.insert(p!("10.0.2.0/24"), 5);
579 ///
580 /// let bytes = rkyv::to_bytes::<Error>(&pm)?;
581 /// let map: &ArchivedPrefixMap<P, i32> = rkyv::access::<_, Error>(&bytes)?;
582 ///
583 /// assert_eq!(
584 /// map.children(&p!("10.0.0.0/23"))
585 /// .map(|(p, v)| (p, v.to_native()))
586 /// .collect::<Vec<_>>(),
587 /// vec![(p!("10.0.0.0/23"), 2), (p!("10.0.0.0/24"), 4)],
588 /// );
589 /// # Ok(())
590 /// # }
591 /// # #[cfg(not(all(feature = "rkyv", feature = "ipnet")))]
592 /// # fn main() {}
593 /// ```
594 pub fn children<'a>(&'a self, prefix: &P) -> Iter<'a, P, T> {
595 let (key, prefix_len) = key_prefix_len(prefix);
596 let Some(lex) = self.build_children_lex_iter(key, prefix_len) else {
597 return Default::default();
598 };
599 Iter::at_node(self, lex)
600 }
601
602 /// Iterate over all entries starting at `prefix`, in lexicographic order.
603 ///
604 /// This enables stateless, cursor-based pagination: pass the last-seen prefix to resume.
605 ///
606 /// - If `inclusive` is `true`, the iterator includes the entry at `prefix` (if present).
607 /// - If `inclusive` is `false`, the iterator starts after `prefix`. Entries more specific than
608 /// `prefix` (its children) are still yielded.
609 ///
610 /// If `prefix` is not present in the map, the iterator starts at the first entry that would come
611 /// after `prefix` in lexicographic order, regardless of `inclusive`.
612 ///
613 /// This mirrors [`PrefixMap::iter_from`], but operates on the archived map and yields references
614 /// to archived values.
615 ///
616 /// ```
617 /// # use prefix_trie::PrefixMap;
618 /// # use prefix_trie::rkyv::ArchivedPrefixMap;
619 /// # use rkyv::rancor::Error;
620 /// # #[cfg(all(feature = "rkyv", feature = "ipnet"))]
621 /// # fn main() -> Result<(), Box<dyn std::error::Error>> {
622 /// # type P = ipnet::Ipv4Net;
623 /// # macro_rules! p { ($s:literal) => { $s.parse::<P>()? } }
624 /// let mut pm = PrefixMap::<P, i32>::new();
625 /// pm.insert(p!("10.0.0.0/8"), 1);
626 /// pm.insert(p!("10.1.0.0/16"), 2);
627 /// pm.insert(p!("10.2.0.0/16"), 3);
628 /// pm.insert(p!("10.2.0.0/24"), 4);
629 /// pm.insert(p!("10.3.0.0/16"), 5);
630 /// pm.insert(p!("10.4.0.0/16"), 6);
631 ///
632 /// let bytes = rkyv::to_bytes::<Error>(&pm)?;
633 /// let map: &ArchivedPrefixMap<P, i32> = rkyv::access::<_, Error>(&bytes)?;
634 ///
635 /// assert_eq!(
636 /// map.iter_from(&p!("10.2.0.0/16"), true)
637 /// .take(3)
638 /// .map(|(p, v)| (p, v.to_native()))
639 /// .collect::<Vec<_>>(),
640 /// vec![
641 /// (p!("10.2.0.0/16"), 3),
642 /// (p!("10.2.0.0/24"), 4),
643 /// (p!("10.3.0.0/16"), 5),
644 /// ],
645 /// );
646 ///
647 /// assert_eq!(
648 /// map.iter_from(&p!("10.2.0.0/16"), false)
649 /// .take(3)
650 /// .map(|(p, v)| (p, v.to_native()))
651 /// .collect::<Vec<_>>(),
652 /// vec![
653 /// (p!("10.2.0.0/24"), 4),
654 /// (p!("10.3.0.0/16"), 5),
655 /// (p!("10.4.0.0/16"), 6),
656 /// ],
657 /// );
658 /// # Ok(())
659 /// # }
660 /// # #[cfg(not(all(feature = "rkyv", feature = "ipnet")))]
661 /// # fn main() {}
662 /// ```
663 pub fn iter_from<'a>(&'a self, prefix: &P, inclusive: bool) -> Iter<'a, P, T> {
664 let (key, prefix_len) = key_prefix_len(prefix);
665 let stack = self.build_iter_stack_at(key, prefix_len, inclusive);
666 Iter::from_stack(self, stack)
667 }
668
669 /// Iterate over all entries in the map that cover `prefix`, including `prefix` itself if it is
670 /// present. The returned iterator yields `(P, &'a T::Archived)`, with reconstructed prefixes `P`.
671 ///
672 /// The iterator will always yield elements ordered by their prefix length, i.e., their depth in
673 /// the tree.
674 ///
675 /// This mirrors [`PrefixMap::cover`], but operates on the archived map and yields references to
676 /// archived values.
677 ///
678 /// ```
679 /// # use prefix_trie::PrefixMap;
680 /// # use prefix_trie::rkyv::ArchivedPrefixMap;
681 /// # use rkyv::rancor::Error;
682 /// # #[cfg(all(feature = "rkyv", feature = "ipnet"))]
683 /// # fn main() -> Result<(), Box<dyn std::error::Error>> {
684 /// # type P = ipnet::Ipv4Net;
685 /// # macro_rules! p { ($s:literal) => { $s.parse::<P>()? } }
686 /// let mut pm = PrefixMap::<P, i32>::new();
687 /// pm.insert(p!("10.0.0.0/8"), 0);
688 /// pm.insert(p!("10.1.0.0/16"), 1);
689 /// pm.insert(p!("10.1.1.0/24"), 2);
690 /// pm.insert(p!("10.1.2.0/24"), 3); // disjoint prefixes are not covered
691 /// pm.insert(p!("10.1.1.0/25"), 4); // more specific prefixes are not covered
692 /// pm.insert(p!("11.0.0.0/8"), 5); // branch points without a value are skipped
693 ///
694 /// let bytes = rkyv::to_bytes::<Error>(&pm)?;
695 /// let map: &ArchivedPrefixMap<P, i32> = rkyv::access::<_, Error>(&bytes)?;
696 ///
697 /// assert_eq!(
698 /// map.cover(&p!("10.1.1.0/24"))
699 /// .map(|(p, v)| (p, v.to_native()))
700 /// .collect::<Vec<_>>(),
701 /// vec![(p!("10.0.0.0/8"), 0), (p!("10.1.0.0/16"), 1), (p!("10.1.1.0/24"), 2)],
702 /// );
703 /// # Ok(())
704 /// # }
705 /// # #[cfg(not(all(feature = "rkyv", feature = "ipnet")))]
706 /// # fn main() {}
707 /// ```
708 pub fn cover<'a>(&'a self, prefix: &P) -> Cover<'a, P, T> {
709 Cover::new(self, prefix)
710 }
711
712 /// Iterate over all prefixes in the map that cover `prefix`, including `prefix` itself if it is
713 /// present. The returned iterator yields reconstructed prefixes `P`.
714 ///
715 /// The iterator will always yield elements ordered by their prefix length, i.e., their depth in
716 /// the tree.
717 ///
718 /// This mirrors [`PrefixMap::cover_keys`], but operates on the archived map.
719 ///
720 /// ```
721 /// # use prefix_trie::PrefixMap;
722 /// # use prefix_trie::rkyv::ArchivedPrefixMap;
723 /// # use rkyv::rancor::Error;
724 /// # #[cfg(all(feature = "rkyv", feature = "ipnet"))]
725 /// # fn main() -> Result<(), Box<dyn std::error::Error>> {
726 /// # type P = ipnet::Ipv4Net;
727 /// # macro_rules! p { ($s:literal) => { $s.parse::<P>()? } }
728 /// let mut pm = PrefixMap::<P, i32>::new();
729 /// pm.insert(p!("10.0.0.0/8"), 0);
730 /// pm.insert(p!("10.1.0.0/16"), 1);
731 /// pm.insert(p!("10.1.1.0/24"), 2);
732 /// pm.insert(p!("10.1.2.0/24"), 3); // disjoint prefixes are not covered
733 /// pm.insert(p!("10.1.1.0/25"), 4); // more specific prefixes are not covered
734 /// pm.insert(p!("11.0.0.0/8"), 5); // branch points without a value are skipped
735 ///
736 /// let bytes = rkyv::to_bytes::<Error>(&pm)?;
737 /// let map: &ArchivedPrefixMap<P, i32> = rkyv::access::<_, Error>(&bytes)?;
738 ///
739 /// assert_eq!(
740 /// map.cover_keys(&p!("10.1.1.0/24")).collect::<Vec<_>>(),
741 /// vec![p!("10.0.0.0/8"), p!("10.1.0.0/16"), p!("10.1.1.0/24")],
742 /// );
743 /// # Ok(())
744 /// # }
745 /// # #[cfg(not(all(feature = "rkyv", feature = "ipnet")))]
746 /// # fn main() {}
747 /// ```
748 pub fn cover_keys<'a>(&'a self, prefix: &P) -> CoverKeys<'a, P, T> {
749 CoverKeys(Cover::new(self, prefix))
750 }
751
752 /// Iterate over the values of all prefixes in the map that cover `prefix`, including `prefix`
753 /// itself if it is present. The returned iterator yields `&'a T::Archived`.
754 ///
755 /// The iterator will always yield elements ordered by their prefix length, i.e., their depth in
756 /// the tree.
757 ///
758 /// This mirrors [`PrefixMap::cover_values`], but operates on the archived map and yields
759 /// references to archived values.
760 ///
761 /// ```
762 /// # use prefix_trie::PrefixMap;
763 /// # use prefix_trie::rkyv::ArchivedPrefixMap;
764 /// # use rkyv::rancor::Error;
765 /// # #[cfg(all(feature = "rkyv", feature = "ipnet"))]
766 /// # fn main() -> Result<(), Box<dyn std::error::Error>> {
767 /// # type P = ipnet::Ipv4Net;
768 /// # macro_rules! p { ($s:literal) => { $s.parse::<P>()? } }
769 /// let mut pm = PrefixMap::<P, i32>::new();
770 /// pm.insert(p!("10.0.0.0/8"), 0);
771 /// pm.insert(p!("10.1.0.0/16"), 1);
772 /// pm.insert(p!("10.1.1.0/24"), 2);
773 /// pm.insert(p!("10.1.2.0/24"), 3); // disjoint prefixes are not covered
774 /// pm.insert(p!("10.1.1.0/25"), 4); // more specific prefixes are not covered
775 /// pm.insert(p!("11.0.0.0/8"), 5); // branch points without a value are skipped
776 ///
777 /// let bytes = rkyv::to_bytes::<Error>(&pm)?;
778 /// let map: &ArchivedPrefixMap<P, i32> = rkyv::access::<_, Error>(&bytes)?;
779 ///
780 /// assert_eq!(
781 /// map.cover_values(&p!("10.1.1.0/24"))
782 /// .map(|v| v.to_native())
783 /// .collect::<Vec<_>>(),
784 /// vec![0, 1, 2],
785 /// );
786 /// # Ok(())
787 /// # }
788 /// # #[cfg(not(all(feature = "rkyv", feature = "ipnet")))]
789 /// # fn main() {}
790 /// ```
791 pub fn cover_values<'a>(&'a self, prefix: &P) -> CoverValues<'a, P, T> {
792 CoverValues(Cover::new(self, prefix))
793 }
794}
795
796/// An iterator over all entries of an [`ArchivedPrefixMap`] in lexicographic order.
797pub struct Iter<'a, P: Prefix, T: Archive> {
798 map: Option<&'a ArchivedPrefixMap<P, T>>,
799 stack: Vec<MaskedLexIter<'a, P::R>>,
800}
801
802impl<'a, P: Prefix, T: Archive> Default for Iter<'a, P, T> {
803 fn default() -> Self {
804 Self {
805 map: None,
806 stack: Vec::new(),
807 }
808 }
809}
810
811impl<'a, P: Prefix, T: Archive> Iter<'a, P, T> {
812 pub(super) fn new(map: &'a ArchivedPrefixMap<P, T>) -> Self {
813 Self::at_node(map, MaskedLexIter::root(map))
814 }
815
816 pub(super) fn at_node(map: &'a ArchivedPrefixMap<P, T>, lex: MaskedLexIter<'a, P::R>) -> Self {
817 let stack = vec![lex];
818 Self {
819 map: Some(map),
820 stack,
821 }
822 }
823
824 pub(super) fn from_stack(
825 map: &'a ArchivedPrefixMap<P, T>,
826 stack: Vec<MaskedLexIter<'a, P::R>>,
827 ) -> Self {
828 Self {
829 map: Some(map),
830 stack,
831 }
832 }
833}
834
835impl<'a, P: Prefix, T: Archive> Iterator for Iter<'a, P, T> {
836 type Item = (P, &'a T::Archived);
837
838 fn next(&mut self) -> Option<Self::Item> {
839 let map = self.map?;
840 while let Some(lex_iter) = self.stack.last_mut() {
841 let Some(next) = lex_iter.next() else {
842 self.stack.pop();
843 continue;
844 };
845
846 match next {
847 LexIterElem::Data(loc, depth) => {
848 let p = reconstruct_prefix(lex_iter.key, depth, loc.bit as usize);
849 return Some((p, &map.data[loc.idx()]));
850 }
851 LexIterElem::Child(next_loc, depth, next_key) => self
852 .stack
853 .push(MaskedLexIter::new(next_loc, depth, next_key, map)),
854 }
855 }
856 None
857 }
858}
859
860/// An iterator over all prefixes of an [`ArchivedPrefixMap`] in lexicographic order.
861pub struct Keys<'a, P: Prefix, T: Archive>(pub(super) Iter<'a, P, T>);
862
863impl<'a, P: Prefix, T: Archive> Default for Keys<'a, P, T> {
864 fn default() -> Self {
865 Self(Default::default())
866 }
867}
868
869impl<'a, P: Prefix, T: Archive> Iterator for Keys<'a, P, T> {
870 type Item = P;
871
872 fn next(&mut self) -> Option<Self::Item> {
873 self.0.next().map(|(p, _)| p)
874 }
875}
876
877/// An iterator over all values of an [`ArchivedPrefixMap`] in lexicographic order of their
878/// prefixes.
879pub struct Values<'a, P: Prefix, T: Archive>(Iter<'a, P, T>);
880
881impl<'a, P: Prefix, T: Archive> Default for Values<'a, P, T> {
882 fn default() -> Self {
883 Self(Default::default())
884 }
885}
886
887impl<'a, P: Prefix, T: Archive> Iterator for Values<'a, P, T> {
888 type Item = &'a T::Archived;
889
890 fn next(&mut self) -> Option<Self::Item> {
891 self.0.next().map(|(_, t)| t)
892 }
893}
894
895/// An iterator that yields all elements in an `ArchivedPrefixMap` that cover (are a superset of) a
896/// given prefix (including the prefix itself if present).
897///
898/// See [`PrefixMap::cover`] for an example.
899pub struct Cover<'a, P: Prefix, T: Archive> {
900 map: &'a ArchivedPrefixMap<P, T>,
901 loc: Loc,
902 depth: u32,
903 lpm_elements: Vec<Loc>,
904 key: P::R,
905 prefix_len: u32,
906}
907
908impl<'a, P: Prefix, T: Archive> Cover<'a, P, T> {
909 pub(super) fn new(map: &'a ArchivedPrefixMap<P, T>, prefix: &P) -> Self {
910 let (key, prefix_len) = key_prefix_len(prefix);
911 let mut s = Self {
912 map,
913 loc: Loc::root(),
914 lpm_elements: Vec::new(),
915 depth: 0,
916 key,
917 prefix_len,
918 };
919 s.populate_lpm_elements();
920 s
921 }
922
923 fn step(&mut self) -> Option<()> {
924 // check if we can still take one step
925 if self.prefix_len < self.depth + K {
926 return None;
927 }
928
929 let child_bit = child_bit(self.depth, self.key);
930 self.loc = self.map.nodes[self.loc.idx()].child_loc(child_bit)?;
931 self.depth += K;
932 self.populate_lpm_elements();
933 Some(())
934 }
935
936 fn populate_lpm_elements(&mut self) {
937 self.lpm_elements = self.map.nodes[self.loc.idx()]
938 .data_lpm_locs(self.depth, self.key, self.prefix_len)
939 .rev()
940 .collect();
941 }
942}
943
944impl<'a, P: Prefix, T: Archive> Iterator for Cover<'a, P, T> {
945 type Item = (P, &'a T::Archived);
946
947 fn next(&mut self) -> Option<Self::Item> {
948 loop {
949 // if we already have some elements in the LPM list, pop those.
950 if let Some(data_loc) = self.lpm_elements.pop() {
951 let prefix = reconstruct_prefix(self.key, self.depth, data_loc.bit as usize);
952 return Some((prefix, &self.map.data[data_loc.idx()]));
953 };
954
955 self.step()?
956 }
957 }
958}
959
960/// An iterator that yields all prefixes in an `ArchivedPrefixMap` that cover (are a superset of) a
961/// given prefix (including the prefix itself if present).
962///
963/// See [`PrefixMap::cover_keys`] for an example.
964pub struct CoverKeys<'a, P: Prefix, T: Archive>(Cover<'a, P, T>);
965
966impl<'a, P: Prefix, T: Archive> Iterator for CoverKeys<'a, P, T> {
967 type Item = P;
968
969 fn next(&mut self) -> Option<Self::Item> {
970 self.0.next().map(|(p, _)| p)
971 }
972}
973
974/// An iterator that yields all values of prefixes in an `ArchivedPrefixMap` that cover (are a
975/// superset of) a given prefix (including the prefix itself if present).
976///
977/// See [`PrefixMap::cover_values`] for an example.
978pub struct CoverValues<'a, P: Prefix, T: Archive>(Cover<'a, P, T>);
979
980impl<'a, P: Prefix, T: Archive> Iterator for CoverValues<'a, P, T> {
981 type Item = &'a T::Archived;
982
983 fn next(&mut self) -> Option<Self::Item> {
984 self.0.next().map(|(_, t)| t)
985 }
986}
987
988impl<'a, P: Prefix, T: Archive> IntoIterator for &'a ArchivedPrefixMap<P, T> {
989 type Item = (P, &'a T::Archived);
990 type IntoIter = Iter<'a, P, T>;
991
992 fn into_iter(self) -> Self::IntoIter {
993 self.iter()
994 }
995}
996
997impl<P, T> Eq for ArchivedPrefixMap<P, T>
998where
999 T: Archive,
1000 T::Archived: Eq,
1001{
1002}
1003
1004impl<P, T> PartialEq for ArchivedPrefixMap<P, T>
1005where
1006 T: Archive,
1007 T::Archived: PartialEq,
1008{
1009 fn eq(&self, other: &Self) -> bool {
1010 // We can directly compare nodes and data due to the canonical representation.
1011 self.nodes == other.nodes && self.data == other.data
1012 }
1013}
1014
1015// Private functions
1016impl<P: Prefix, T: Archive> ArchivedPrefixMap<P, T> {
1017 /// recursive function to compute the address count.
1018 fn address_count_at(&self, loc: u32, depth: u32) -> Option<P::R> {
1019 let node = &self.nodes[loc as usize];
1020 let data_bitmap = node.data_bitmap();
1021 let (covered_data, covered_children) = member_coverage(data_bitmap);
1022 let mut count = P::R::zero();
1023
1024 for bit in 0..NUM_DATA as u32 {
1025 if data_bitmap & !covered_data & (1 << bit) == 0 {
1026 continue;
1027 }
1028 let prefix_len = depth + DATA_BIT_TO_PREFIX[bit as usize].1 as u32;
1029 let host_bits = P::num_bits() - prefix_len;
1030 let addresses = P::R::one() << host_bits as usize;
1031 count = count.checked_add(&addresses)?;
1032 }
1033
1034 for child in node.child_locs() {
1035 if covered_children & (1 << child.bit) == 0 {
1036 let child_count = self.address_count_at(child.idx, depth + K)?;
1037 count = count.checked_add(&child_count)?;
1038 }
1039 }
1040
1041 Some(count)
1042 }
1043
1044 /// Traverse child pointers to the `MultiBitNode` containing `prefix_len`.
1045 /// Returns `(node_loc, depth)` on success, or `None` if any required child is absent.
1046 /// This is the shared traversal primitive used by all `find_*` methods.
1047 #[inline(always)]
1048 fn find_loc<R: Key>(&self, key: R, prefix_len: u32) -> Option<(Loc, u32)> {
1049 let mut loc = Loc::root();
1050 let mut depth = 0u32;
1051 while prefix_len >= depth + K {
1052 let cb = child_bit(depth, key);
1053 loc = self.nodes[loc.idx()].child_loc(cb)?;
1054 depth += K;
1055 }
1056 Some((loc, depth))
1057 }
1058
1059 /// Find the longest-prefix match and return the position of the data of the LPM match, plus the
1060 /// depth of the node containing this data.
1061 #[inline(always)]
1062 fn find_lpm<R: Key>(&self, key: R, prefix_len: u32) -> Option<(Loc, u32)> {
1063 let mut loc = Loc::root();
1064 let mut depth = 0;
1065 let mut lpm: Option<(Loc, u32)> = None;
1066
1067 loop {
1068 let node = &self.nodes[loc.idx()];
1069 if let Some(data_loc) = node.data_lpm_loc(depth, key, prefix_len) {
1070 lpm = Some((data_loc, depth));
1071 }
1072 if prefix_len < depth + K {
1073 return lpm;
1074 }
1075 let child_bit = child_bit(depth, key);
1076 // SAFETY: `loc` starts as `Loc::root()` and is only updated to the result
1077 // of a prior `child()` call, which always returns a valid `Loc`.
1078 let Some(next) = self.nodes[loc.idx()].child_loc(child_bit) else {
1079 return lpm;
1080 };
1081 loc = next;
1082 depth += K;
1083 }
1084 }
1085
1086 /// Find the shortest-prefix match and return the position of the data of the LPM match, plus the
1087 /// depth of the node containing this data.
1088 #[inline(always)]
1089 fn find_spm<R: Key>(&self, key: R, prefix_len: u32) -> Option<(Loc, u32)> {
1090 let mut loc = Loc::root();
1091 let mut depth = 0;
1092
1093 loop {
1094 let node = &self.nodes[loc.idx()];
1095 if let Some(data_loc) = node.data_spm_loc(depth, key, prefix_len) {
1096 return Some((data_loc, depth));
1097 }
1098 if prefix_len < depth + K {
1099 return None;
1100 }
1101 let child_bit = child_bit(depth, key);
1102 // SAFETY: `loc` starts as `Loc::root()` and is only updated to the result
1103 // of a prior `child()` call, which always returns a valid `Loc`.
1104 loc = self.nodes[loc.idx()].child_loc(child_bit)?;
1105 depth += K;
1106 }
1107 }
1108
1109 /// Check whether `bit` of the node at `loc` has its entire range covered by the union of
1110 /// members, without performing aggregation. Mirrors [`Table::bit_covered`](crate::table): a
1111 /// fold's result for a given bit only depends on that bit's heap descendants, so this only
1112 /// recurses into the children `bit`'s coverage actually depends on
1113 /// (`child_cover_mask_for_bit`), skipping any already redundant under an ancestor member
1114 /// (`children_under_member`).
1115 fn bit_covered(&self, loc: Loc, bit: u32) -> bool {
1116 let node = &self.nodes[loc.idx()];
1117 let data_bitmap = node.data_bitmap();
1118 if data_bitmap & (1 << bit) != 0 {
1119 return true; // `bit` itself is a member
1120 }
1121
1122 let mask = child_cover_mask_for_bit(bit);
1123 let (_, children_under_member) = member_coverage(data_bitmap);
1124 let mut child_coverage = children_under_member & mask;
1125 for child in node.child_locs() {
1126 let child_bit = child.bit;
1127 if mask & (1 << child_bit) == 0 || children_under_member & (1 << child_bit) != 0 {
1128 continue;
1129 }
1130 if self.bit_covered(child, 0) {
1131 child_coverage |= 1 << child_bit;
1132 }
1133 }
1134
1135 fold_coverage(data_bitmap, child_coverage) & (1 << bit) != 0
1136 }
1137
1138 /// Check whether every address in the prefix given by `key`/`prefix_len` is covered by the
1139 /// union of members, without performing aggregation. A single descent: an ancestor or exact
1140 /// member short-circuits to `true`; otherwise [`Self::bit_covered`] tests just the owning
1141 /// node's bit for the target prefix.
1142 fn covers_in_aggregate<R: Key>(&self, key: R, prefix_len: u32) -> bool {
1143 let mut loc = Loc::root();
1144 let mut depth = 0;
1145 loop {
1146 let node = &self.nodes[loc.idx()];
1147 if node.data_spm_loc(depth, key, prefix_len).is_some() {
1148 return true; // an ancestor or the prefix itself is a member
1149 }
1150 if prefix_len < depth + K {
1151 let bit = data_bit(key, prefix_len);
1152 return self.bit_covered(loc, bit);
1153 }
1154 let cb = child_bit(depth, key);
1155 let Some(next) = self.nodes[loc.idx()].child_loc(cb) else {
1156 return false; // owning node absent and no ancestor member => uncovered
1157 };
1158 loc = next;
1159 depth += K;
1160 }
1161 }
1162
1163 /// Build a lex iter to iterate all children of the prefix.
1164 fn build_children_lex_iter(
1165 &self,
1166 key: P::R,
1167 prefix_len: u32,
1168 ) -> Option<MaskedLexIter<'_, P::R>> {
1169 let (loc, depth) = self.find_loc(key, prefix_len)?;
1170 let mut lex = MaskedLexIter::new(loc, depth, key, self);
1171 // Only take those that are children of the prefix
1172 lex.apply_data_mask(data_cover_mask(depth, key, prefix_len));
1173 lex.apply_child_mask(child_cover_mask(depth, key, prefix_len));
1174 Some(lex)
1175 }
1176
1177 /// Build an iterator stack positioned at a given prefix in lex order.
1178 ///
1179 /// Navigates from the root toward `(key, prefix_len)`, pushing lex iterators onto the stack
1180 /// with entries before the target masked out. If `inclusive` is false, the exact target
1181 /// data slot is also excluded.
1182 fn build_iter_stack_at(
1183 &self,
1184 key: P::R,
1185 prefix_len: u32,
1186 inclusive: bool,
1187 ) -> Vec<MaskedLexIter<'_, P::R>> {
1188 let mut stack = Vec::new();
1189 let mut loc = Loc::root();
1190 let mut depth = 0u32;
1191
1192 loop {
1193 let mut lex = MaskedLexIter::new(loc, depth, key, self);
1194
1195 if prefix_len < depth + K {
1196 // Target falls within this node as a data slot.
1197 let data_bit = data_bit(key, prefix_len);
1198 let (data_mask, child_mask) = lex_after_data(data_bit);
1199 let data_mask = if inclusive {
1200 data_mask
1201 } else {
1202 data_mask & !(1 << data_bit)
1203 };
1204 lex.apply_data_mask(data_mask);
1205 lex.apply_child_mask(child_mask);
1206 stack.push(lex);
1207 break;
1208 }
1209
1210 // Target is deeper; follow the child pointer.
1211 let child_bit = child_bit(depth, key);
1212 let (data_mask, child_mask) = lex_after_child(child_bit);
1213 lex.apply_data_mask(data_mask);
1214 lex.apply_child_mask(child_mask);
1215 stack.push(lex);
1216
1217 // SAFETY: `loc` is valid (see above); `child()` returns a valid `Loc` if present.
1218 match self.nodes[loc.idx()].child_loc(child_bit) {
1219 Some(next) => {
1220 loc = next;
1221 depth += K;
1222 }
1223 None => break, // child doesn't exist; entries after it are already in the mask
1224 }
1225 }
1226
1227 stack
1228 }
1229}
1230
1231fn key_prefix_len<P: Prefix>(prefix: &P) -> (P::R, u32) {
1232 let key = prefix.repr();
1233 let prefix_len = prefix.prefix_len() as u32;
1234 (key, prefix_len)
1235}
1236
1237/// Rkyv representation of a node with compacted indices
1238#[derive(Archive, Serialize, Default)]
1239#[rkyv(derive(Debug, Default, PartialEq, Eq, Hash))]
1240pub(super) struct NodeRepr {
1241 pub(super) data_bitmap: u32,
1242 pub(super) child_bitmap: u32,
1243 pub(super) data_idx: u32,
1244 pub(super) children_idx: u32,
1245}
1246
1247impl ArchivedNodeRepr {
1248 #[inline(always)]
1249 pub(super) fn data_idx(&self) -> u32 {
1250 self.data_idx.to_native()
1251 }
1252
1253 #[inline(always)]
1254 pub(super) fn data_bitmap(&self) -> u32 {
1255 self.data_bitmap.to_native()
1256 }
1257
1258 #[inline(always)]
1259 pub(super) fn has_data_bit(&self, bit: u32) -> bool {
1260 self.data_bitmap() & (1 << bit) != 0
1261 }
1262
1263 /// Get the location of the given data bit (only if it is set)
1264 pub(super) fn data_loc(&self, bit: u32) -> Option<Loc> {
1265 if self.has_data_bit(bit) {
1266 Some(Loc::new(self.data_bitmap(), self.data_idx(), bit))
1267 } else {
1268 None
1269 }
1270 }
1271
1272 /// Get the data loc of the longest prefix match in this node (if it exists).
1273 /// Returns Loc with bit (bitmap position) and computed slot.
1274 #[inline(always)]
1275 fn data_lpm_loc<R: Key>(&self, depth: u32, key: R, prefix_len: u32) -> Option<Loc> {
1276 let nodes_present = self.data_bitmap & data_lpm_mask(depth, key, prefix_len);
1277 if nodes_present == 0 {
1278 return None;
1279 }
1280 let msb_bit = u32::BITS - 1 - nodes_present.leading_zeros();
1281 Some(Loc::new(self.data_bitmap(), self.data_idx(), msb_bit))
1282 }
1283
1284 /// Get the data loc of the shortest prefix match in this node (if it exists).
1285 /// Returns Loc with bit (bitmap position) and computed slot.
1286 #[inline(always)]
1287 fn data_spm_loc<R: Key>(&self, depth: u32, key: R, prefix_len: u32) -> Option<Loc> {
1288 let nodes_present = self.data_bitmap & data_lpm_mask(depth, key, prefix_len);
1289 if nodes_present == 0 {
1290 return None;
1291 }
1292 let lsb_bit = nodes_present.trailing_zeros();
1293 Some(Loc::new(self.data_bitmap(), self.data_idx(), lsb_bit))
1294 }
1295
1296 /// Get an iterator over all indices of data that cover (or equal) the prefix, i.e.,
1297 /// `(key, prefix_len)`.
1298 #[inline(always)]
1299 pub(super) fn data_lpm_locs<R: Key>(
1300 &self,
1301 depth: u32,
1302 key: R,
1303 prefix_len: u32,
1304 ) -> impl DoubleEndedIterator<Item = Loc> + 'static {
1305 let bitmap = self.data_bitmap();
1306 let filter = bitmap & data_lpm_mask(depth, key, prefix_len);
1307 bitmap_offset_locs(bitmap, filter, self.data_idx())
1308 }
1309
1310 #[inline(always)]
1311 pub(super) fn children_idx(&self) -> u32 {
1312 self.children_idx.to_native()
1313 }
1314
1315 #[inline(always)]
1316 pub(super) fn child_bitmap(&self) -> u32 {
1317 self.child_bitmap.to_native()
1318 }
1319
1320 #[inline(always)]
1321 pub(super) fn has_child_bit(&self, bit: u32) -> bool {
1322 self.child_bitmap() & (1 << bit) != 0
1323 }
1324
1325 /// Get the location of the given data bit (only if it is set)
1326 pub(super) fn child_loc(&self, bit: u32) -> Option<Loc> {
1327 if self.has_child_bit(bit) {
1328 Some(Loc::new(self.child_bitmap(), self.children_idx(), bit))
1329 } else {
1330 None
1331 }
1332 }
1333
1334 /// Get an iterator over all children.
1335 #[inline(always)]
1336 pub(super) fn child_locs(&self) -> impl DoubleEndedIterator<Item = Loc> + 'static {
1337 let bitmap = self.child_bitmap();
1338 bitmap_offset_locs(bitmap, bitmap, self.children_idx())
1339 }
1340}
1341
1342/// `bitmap` is used to compute the popcount (offset), while `filter` is used for filtering.
1343#[inline(always)]
1344fn bitmap_offset_locs(
1345 bitmap: u32,
1346 filter: u32,
1347 offset: u32,
1348) -> impl DoubleEndedIterator<Item = Loc> + 'static {
1349 (0..(NUM_CHILDREN as u32))
1350 .filter(move |&bit| filter & (1 << bit) != 0)
1351 .map(move |bit| Loc::new(bitmap, offset, bit))
1352}
1353
1354#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
1355pub(super) struct Loc {
1356 idx: u32,
1357 bit: u32,
1358}
1359
1360impl Loc {
1361 #[inline(always)]
1362 pub(super) fn root() -> Self {
1363 Self { idx: 0, bit: 0 }
1364 }
1365
1366 #[inline(always)]
1367 pub(super) fn new(bitmap: u32, offset: u32, bit: u32) -> Self {
1368 Loc {
1369 idx: offset + compute_slot(bitmap, bit),
1370 bit,
1371 }
1372 }
1373
1374 #[inline(always)]
1375 pub(super) fn idx(&self) -> usize {
1376 self.idx as usize
1377 }
1378}
1379
1380pub(super) struct MaskedLexIter<'a, R> {
1381 iter: std::slice::Iter<'static, LexElem>,
1382 depth: u32,
1383 key: R,
1384 // Original (unmasked) node: kept for correct POPCNT slot computation.
1385 node: &'a ArchivedNodeRepr,
1386 // Separate filter fields: apply_*_mask modifies these, not the node bitmaps.
1387 data_filter: u32,
1388 child_filter: u32,
1389}
1390
1391#[derive(Clone, Copy)]
1392pub(super) enum LexIterElem<R> {
1393 Data(Loc, u32),
1394 Child(Loc, u32, R),
1395}
1396
1397impl<'a, R> MaskedLexIter<'a, R> {
1398 pub(crate) fn root<P, T>(map: &'a ArchivedPrefixMap<P, T>) -> Self
1399 where
1400 P: Prefix<R = R>,
1401 R: Zero,
1402 T: Archive,
1403 {
1404 Self::new(Loc::root(), 0, R::zero(), map)
1405 }
1406
1407 pub(crate) fn new<P, T>(loc: Loc, depth: u32, key: R, map: &'a ArchivedPrefixMap<P, T>) -> Self
1408 where
1409 P: Prefix<R = R>,
1410 T: Archive,
1411 {
1412 Self {
1413 iter: LEX_ORDER.iter(),
1414 depth,
1415 key,
1416 node: &map.nodes[loc.idx()],
1417 data_filter: u32::MAX,
1418 child_filter: u32::MAX,
1419 }
1420 }
1421
1422 pub(crate) fn apply_data_mask(&mut self, mask: u32) {
1423 // Only reduce the set of offsets to yield; keep node.data_bitmap intact for POPCNT.
1424 self.data_filter &= mask;
1425 }
1426
1427 pub(crate) fn apply_child_mask(&mut self, mask: u32) {
1428 self.child_filter &= mask;
1429 }
1430}
1431
1432impl<'a, R: Key> Iterator for MaskedLexIter<'a, R> {
1433 type Item = LexIterElem<R>;
1434
1435 fn next(&mut self) -> Option<Self::Item> {
1436 loop {
1437 let next = *self.iter.next()?;
1438 match next.decode() {
1439 Ok(data_bit) => {
1440 // Check original bitmap (for existence) AND filter (for masking).
1441 if self.data_filter & (1 << data_bit) != 0 {
1442 if let Some(loc) = self.node.data_loc(data_bit) {
1443 return Some(LexIterElem::Data(loc, self.depth));
1444 }
1445 }
1446 }
1447 Err(child_bit) => {
1448 if self.node.has_child_bit(child_bit)
1449 && (self.child_filter & (1 << child_bit)) != 0
1450 {
1451 return Some(LexIterElem::Child(
1452 Loc::new(
1453 self.node.child_bitmap(),
1454 self.node.children_idx(),
1455 child_bit,
1456 ),
1457 self.depth + K,
1458 extend_repr(self.key, self.depth, child_bit),
1459 ));
1460 }
1461 }
1462 }
1463 }
1464 }
1465}
1466
1467/// The `rkyv` resolver for [`ArchivedPrefixMap`] and [`super::ArchivedPrefixSet`].
1468pub struct PrefixMapResolver {
1469 pub(super) nodes: VecResolver,
1470 pub(super) nodes_len: usize,
1471 pub(super) data: VecResolver,
1472 pub(super) data_len: usize,
1473}