Skip to main content

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}