Skip to main content

prefix_trie/trieview/
mod.rs

1//! Composable trie-view trait for [`crate::PrefixMap`].
2//!
3//! # Architecture
4//!
5//! [`TrieView`] is a **trait** implemented by any cursor (mutable or immutable)
6//! into a prefix trie:
7//! - [`TrieRef`]: an immutable cursor yielding `&T`
8//! - [`TrieRefMut`]: a mutable cursor yielding `&mut T`
9//! - Composed views: [`IntersectionView`], [`UnionView`], [`CoveringUnionView`],
10//!   [`DifferenceView`], [`CoveringDifferenceView`]
11//!
12//! This design makes set operations **composable**:
13//!
14//! ```
15//! # use prefix_trie::{PrefixMap, PrefixSet, AsView, TrieView};
16//! # use prefix_trie::trieview::union::UnionItem;
17//! # type P = (u32, u8);
18//! let mut target: PrefixMap::<P, _> = [((0, 8), 1), ((0, 16), 2), ((0, 24), 3)].into_iter().collect();
19//! let source:     PrefixMap::<P, _> = [((0, 8), 9), ((0, 16), 1)].into_iter().collect();
20//! let ignore:     PrefixSet::<P>    = [ (0, 10)].into_iter().collect();
21//!
22//! (&mut target)
23//!     .view()
24//!     .union(&source)
25//!     .covering_difference(&ignore)
26//!     .values()
27//!     .for_each(|x| if let UnionItem::Both(l, r) = x {
28//!         *l += *r
29//!     });
30//!
31//! assert_eq!(
32//!     target.into_iter().collect::<Vec<_>>(),
33//!     vec![((0, 8), 10), ((0, 16), 2), ((0, 24), 3)], // only (0, 8) got updated
34//! );
35//! ```
36//!
37//! # Safety contract for `get_data`, `get_child`, and `reposition`
38//!
39//! The three unsafe primitives carry the following contracts:
40//!
41//! - **`get_data`**: each `data_bit` must be passed **at most once** per view instance.
42//! - **`get_child`**: each `child_bit` must be passed **at most once** per view instance.
43//! - For mutable views, values reached through different data bits, values reachable through
44//!   different child bits, and values stored in a node versus values reachable through its child
45//!   views must be disjoint from each other.
46//! - **`reposition`**: the returned cursor shares the same underlying node as `self`.
47//!   For mutable views the caller must ensure the two cursors' effective bitmaps are
48//!   disjoint, or that the original is not used for data access after the call.
49//!
50//! All default methods uphold these invariants internally.
51//!
52//! # Clone and mutable views
53//!
54//! The `TrieView` trait does **not** require `Self: Clone`. Mutable views
55//! ([`TrieRefMut`]) intentionally do not implement `Clone` to prevent aliasing
56//! `&mut` references. Methods that need to retain an earlier cursor while descending,
57//! such as [`find_lpm`][TrieView::find_lpm], require `Self: Clone`. Methods that
58//! return an element directly, such as [`find_lpm_value`][TrieView::find_lpm_value],
59//! can work with mutable views because they do not need to return a saved cursor.
60//!
61//! Composed views implement `Clone` only when their sides do. This naturally means clone-backed
62//! methods such as [`find_lpm`][TrieView::find_lpm] are unavailable on composed mutable views,
63//! while consuming methods such as [`find_lpm_value`][TrieView::find_lpm_value] remain usable.
64
65// Structural immutability invariant (for maintainers)
66//
67// The node structure of the underlying trie (node allocations, bitmaps, child pointers) must
68// not change for the entire lifetime of any `TrieView` or `TrieRefMut` borrow.
69//
70// Concretely:
71// - No insertions or deletions that would trigger a tier upgrade/downgrade in the node or cell
72//   allocators are permitted while a view is alive.
73// - No structural operations (e.g. `insert`, `remove`, `remove_children`, `retain`) may be
74//   called on the underlying `PrefixMap` while a view borrows it.
75//
76// For immutable views (TrieRef) this is automatically enforced by Rust's borrow checker:
77// the view holds `&'a Table<T>`, which prevents any `&mut` access to the map.
78//
79// For mutable views (TrieRefMut) the invariant is maintained by holding `&'a Table<T>` for
80// structural reads while using a raw pointer (`RawPtr<T>`) only for data-value mutations.
81// The raw pointer path accesses only the value slots (the flat `cells` array), never any
82// allocation metadata or bitmaps. As long as no two live `&mut T` references alias the same
83// slot — guaranteed by the acyclic tree structure — these raw-pointer value mutations are sound
84// without requiring `&mut Table<T>`.
85
86pub mod covering_difference;
87pub mod covering_union;
88pub mod difference;
89mod equality;
90mod filter;
91pub mod intersection;
92pub(crate) mod iter;
93mod map;
94pub mod trie_ref;
95pub mod trie_ref_mut;
96pub mod union;
97
98pub use covering_difference::CoveringDifferenceView;
99pub use covering_union::{CoveringUnionItem, CoveringUnionView};
100pub use difference::DifferenceView;
101pub use filter::FilterView;
102pub use intersection::IntersectionView;
103pub use iter::{ViewIter, ViewKeys, ViewValues};
104pub use map::{ClonedView, CopiedView, MapView};
105pub use trie_ref::TrieRef;
106pub use trie_ref_mut::TrieRefMut;
107pub use union::{UnionItem, UnionView};
108
109use num_traits::{One, PrimInt, Zero};
110
111use crate::{
112    prefix::mask_from_prefix_len,
113    Prefix,
114    {
115        node::{child_bit, data_bit, data_lpm_mask, DATA_BIT_TO_PREFIX},
116        table::K,
117    },
118};
119
120/// An immutable or mutable view into a (possibly composed) prefix trie.
121///
122/// # Required methods
123///
124/// Eight methods that concrete and composed views must implement:
125/// - **Position**: [`Self::depth`], [`Self::key`], [`Self::prefix_len`]
126/// - **Bitmaps**: [`Self::data_bitmap`], [`Self::child_bitmap`]
127/// - **Primitives** (unsafe): [`Self::get_data`], [`Self::get_child`], [`Self::reposition`]
128///
129/// # Default methods
130///
131/// All other methods (`left`/`right`/`find`/`find_lpm`/`iter`/etc.) are
132/// provided as defaults built from the eight required methods.
133#[cfg_attr(docsrs, doc(notable_trait))]
134pub trait TrieView<'a>: Sized {
135    /// The prefix type.
136    type P: Prefix;
137    /// The value type yielded by this view (e.g. `&'a T`, `&'a mut T`, `(&'a L, &'a R)`).
138    type T: 'a;
139
140    /// Depth of the underlying `MultiBitNode`: always a multiple of `K`.
141    fn depth(&self) -> u32;
142
143    /// Accumulated key bits; only the top [`prefix_len`][Self::prefix_len] bits are significant.
144    fn key(&self) -> <Self::P as Prefix>::R;
145
146    /// Binary-tree depth of this view's root position (`depth <= prefix_len < depth + K`).
147    fn prefix_len(&self) -> u32;
148
149    /// Effective data bitmap (node bitmap ANDed with cover mask and any set-op filter).
150    ///
151    /// A set bit at position `b` means there is a value accessible via
152    /// [`get_data(b)`][Self::get_data].
153    fn data_bitmap(&self) -> u32;
154
155    /// Effective child bitmap (node bitmap ANDed with cover mask and any set-op filter).
156    ///
157    /// A set bit at position `b` means there is a non-empty sub-trie reachable via
158    /// [`get_child(b)`][Self::get_child].
159    fn child_bitmap(&self) -> u32;
160
161    /// Return the value at `data_bit`.
162    ///
163    /// # Safety
164    /// `data_bit` must be set in [`data_bitmap`][Self::data_bitmap], and must be passed to this
165    /// method **at most once** per view instance.
166    /// For mutable views (`T = &'a mut T`), calling with the same bit twice produces two
167    /// aliasing `&'a mut T` references -> undefined behavior. Some implementations (e.g. those
168    /// caching values behind `MaybeUninit`) rely on `data_bit` being set in `data_bitmap` for
169    /// soundness, not merely for a well-defined result.
170    unsafe fn get_data(&mut self, data_bit: u32) -> Self::T;
171
172    /// Return a child view at `child_bit`.
173    ///
174    /// The returned view has `depth = self.depth() + K`, `prefix_len = self.depth() + K`,
175    /// and `key = extend_repr(self.key(), self.depth(), child_bit)`.
176    ///
177    /// # Safety
178    /// Each `child_bit` must be passed to this method **at most once** per view instance.
179    /// For mutable views, calling with the same bit twice creates two views with overlapping
180    /// mutable access to the same child node -> undefined behavior. Different bits always
181    /// refer to disjoint child nodes and are safe to combine.
182    ///
183    /// # Panics
184    /// May panic if `child_bit` is not set in [`child_bitmap`][Self::child_bitmap].
185    unsafe fn get_child(&mut self, child_bit: u32) -> Self;
186
187    /// Move the cursor to a different location within the same multibit-node.
188    ///
189    /// The underlying node location (and all data pointers) remain unchanged; only the
190    /// position cursor is updated.
191    ///
192    /// # Safety
193    /// For mutable views, the returned cursor shares the same `raw_ptr` and `node_loc`
194    /// as `self`. The caller must ensure that the returned cursor and `self` are never
195    /// simultaneously used to access overlapping data -> either by ensuring their effective
196    /// bitmaps are disjoint or by not accessing `self`'s data after the call (as in
197    /// `navigate_to` and `step`).
198    unsafe fn reposition(&mut self, key: <Self::P as Prefix>::R, prefix_len: u32);
199
200    // -----------------------------------------------------------------------------
201    // Default implementations
202    // -----------------------------------------------------------------------------
203
204    /// Whether the sub-trie rooted at this view position is non-empty.
205    ///
206    /// A shallow bitmap check: `true` means data or children exist worth exploring.
207    /// `false` means the sub-trie is definitely empty.
208    ///
209    /// **Note**: Composed views may over-approximate their bitmaps. For example,
210    /// [`DifferenceView`] and [`CoveringDifferenceView`] always expose all of the left side's
211    /// children, since some of their subtrees may be absent from the right side. For such views,
212    /// `true` may be returned even though iterating the view yields no entries. `false` is
213    /// always exact. To check emptiness exactly, iterate:
214    /// `view.iter().next().is_none()`. Note that [`iter`][Self::iter] takes the view by value;
215    /// clone it first if you still need it afterwards.
216    ///
217    /// ```
218    /// # use prefix_trie::{PrefixMap, AsView, TrieView};
219    /// # #[cfg(feature = "ipnet")]
220    /// macro_rules! net { ($x:literal) => { $x.parse::<ipnet::Ipv4Net>().unwrap() }; }
221    ///
222    /// # #[cfg(feature = "ipnet")]
223    /// # {
224    /// let mut map = PrefixMap::new();
225    /// map.insert(net!("10.0.0.0/8"), 1);
226    /// assert!(map.view().is_non_empty());
227    ///
228    /// let empty: PrefixMap<ipnet::Ipv4Net, i32> = PrefixMap::new();
229    /// assert!(!empty.view().is_non_empty());
230    ///
231    /// // Over-approximation: `right` removes `left`'s only entry entirely, but `DifferenceView`
232    /// // still exposes left's child pointer toward it, so `is_non_empty` says `true` even though
233    /// // iterating the difference yields nothing.
234    /// let mut left = PrefixMap::new();
235    /// left.insert(net!("10.1.0.0/16"), 1);
236    /// let mut right = PrefixMap::new();
237    /// right.insert(net!("10.1.0.0/16"), 1);
238    ///
239    /// let diff = left.view().difference(&right);
240    /// assert!(diff.is_non_empty());
241    /// assert!(diff.iter().next().is_none());
242    /// # }
243    /// ```
244    #[inline]
245    fn is_non_empty(&self) -> bool {
246        self.data_bitmap() != 0 || self.child_bitmap() != 0
247    }
248
249    /// Reconstruct the prefix at this view's root position.
250    ///
251    /// ```
252    /// # use prefix_trie::{PrefixMap, AsView, TrieView};
253    /// # #[cfg(feature = "ipnet")]
254    /// macro_rules! net { ($x:literal) => { $x.parse::<ipnet::Ipv4Net>().unwrap() }; }
255    ///
256    /// # #[cfg(feature = "ipnet")]
257    /// # {
258    /// let mut map = PrefixMap::new();
259    /// map.insert(net!("192.168.0.0/20"), 1);
260    /// map.insert(net!("192.168.0.0/22"), 2);
261    ///
262    /// let view = map.view().find(&net!("192.168.0.0/21")).unwrap();
263    /// assert_eq!(view.prefix(), net!("192.168.0.0/21"));
264    /// # }
265    /// ```
266    #[inline]
267    fn prefix(&self) -> Self::P {
268        let masked = self.key() & mask_from_prefix_len(self.prefix_len() as u8);
269        Self::P::from_repr_len(masked, self.prefix_len() as u8)
270    }
271
272    /// Return the value stored exactly at this view's root position, if any.
273    ///
274    /// This method consumes the view, which makes it suitable for mutable views.
275    ///
276    /// ```
277    /// # use prefix_trie::{PrefixMap, AsView, TrieView};
278    /// # #[cfg(feature = "ipnet")]
279    /// macro_rules! net { ($x:literal) => { $x.parse::<ipnet::Ipv4Net>().unwrap() }; }
280    ///
281    /// # #[cfg(feature = "ipnet")]
282    /// # {
283    /// let mut map = PrefixMap::new();
284    /// map.insert(net!("192.168.0.0/20"), 1);
285    /// map.insert(net!("192.168.0.0/22"), 2);
286    ///
287    /// assert_eq!(map.view().find_exact(&net!("192.168.0.0/22")).unwrap().value(), Some(&2));
288    /// assert_eq!(map.view().find(&net!("192.168.0.0/21")).unwrap().value(), None);
289    /// # }
290    /// ```
291    #[inline]
292    fn value(mut self) -> Option<Self::T> {
293        let data_bit = data_bit(self.key(), self.prefix_len());
294        if (self.data_bitmap() >> data_bit) & 1 == 1 {
295            // SAFETY: `value` consumes the view and calls `get_data` for one bit.
296            Some(unsafe { self.get_data(data_bit) })
297        } else {
298            None
299        }
300    }
301
302    /// Return the prefix and value stored exactly at this view's root position, if any.
303    ///
304    /// This method consumes the view, which makes it suitable for mutable views.
305    ///
306    /// ```
307    /// # use prefix_trie::{PrefixMap, AsView, TrieView};
308    /// # #[cfg(feature = "ipnet")]
309    /// macro_rules! net { ($x:literal) => { $x.parse::<ipnet::Ipv4Net>().unwrap() }; }
310    ///
311    /// # #[cfg(feature = "ipnet")]
312    /// # {
313    /// let mut map = PrefixMap::new();
314    /// map.insert(net!("192.168.0.0/22"), 2);
315    ///
316    /// let view = map.view().find_exact(&net!("192.168.0.0/22")).unwrap();
317    /// assert_eq!(view.prefix_value(), Some((net!("192.168.0.0/22"), &2)));
318    /// # }
319    /// ```
320    #[inline]
321    fn prefix_value(mut self) -> Option<(Self::P, Self::T)> {
322        let data_bit = data_bit(self.key(), self.prefix_len());
323        if (self.data_bitmap() >> data_bit) & 1 == 1 {
324            let prefix = self.prefix();
325            // SAFETY: `prefix_value` consumes the view and calls `get_data` for one bit.
326            Some((prefix, unsafe { self.get_data(data_bit) }))
327        } else {
328            None
329        }
330    }
331
332    /// Return a view into the left (0-bit) child sub-trie, or `None` if empty.
333    ///
334    /// ```
335    /// # use prefix_trie::{PrefixMap, AsView, TrieView};
336    /// # #[cfg(feature = "ipnet")]
337    /// macro_rules! net { ($x:literal) => { $x.parse::<ipnet::Ipv4Net>().unwrap() }; }
338    ///
339    /// # #[cfg(feature = "ipnet")]
340    /// # {
341    /// let mut map = PrefixMap::new();
342    /// map.insert(net!("10.0.0.0/8"), 1);
343    ///
344    /// let left = map.view().left().unwrap();
345    /// assert_eq!(left.prefix(), net!("0.0.0.0/1"));
346    /// assert_eq!(left.keys().collect::<Vec<_>>(), vec![net!("10.0.0.0/8")]);
347    /// # }
348    /// ```
349    #[inline]
350    fn left(self) -> Option<Self> {
351        step(self, false)
352    }
353
354    /// Return a view into the right (1-bit) child sub-trie, or `None` if empty.
355    ///
356    /// ```
357    /// # use prefix_trie::{PrefixMap, AsView, TrieView};
358    /// # #[cfg(feature = "ipnet")]
359    /// macro_rules! net { ($x:literal) => { $x.parse::<ipnet::Ipv4Net>().unwrap() }; }
360    ///
361    /// # #[cfg(feature = "ipnet")]
362    /// # {
363    /// let mut map = PrefixMap::new();
364    /// map.insert(net!("128.0.0.0/1"), 1);
365    ///
366    /// let right = map.view().right().unwrap();
367    /// assert_eq!(right.prefix(), net!("128.0.0.0/1"));
368    /// assert_eq!(right.value(), Some(&1));
369    /// # }
370    /// ```
371    #[inline]
372    fn right(self) -> Option<Self> {
373        step(self, true)
374    }
375
376    /// Navigate to `prefix` and return the view if the sub-trie is non-empty.
377    ///
378    /// The emptiness check may over-approximate on composed views (see
379    /// [`is_non_empty`][Self::is_non_empty]): the returned view may yield no entries when
380    /// iterated. `None`, however, always means that the view contains nothing at or below
381    /// `prefix`. To check exactly whether the sub-trie contains an entry, iterate the returned
382    /// view: `view.iter().next().is_none()`. Note that [`iter`][Self::iter] takes the view by
383    /// value; clone it first if you still need it afterwards.
384    ///
385    /// ```
386    /// # use prefix_trie::{PrefixMap, AsView, TrieView};
387    /// # #[cfg(feature = "ipnet")]
388    /// macro_rules! net { ($x:literal) => { $x.parse::<ipnet::Ipv4Net>().unwrap() }; }
389    ///
390    /// # #[cfg(feature = "ipnet")]
391    /// # {
392    /// let mut map = PrefixMap::new();
393    /// map.insert(net!("192.168.0.0/20"), 1);
394    /// map.insert(net!("192.168.0.0/22"), 2);
395    /// map.insert(net!("192.168.0.0/24"), 3);
396    ///
397    /// let sub = map.view().find(&net!("192.168.0.0/21")).unwrap();
398    /// assert_eq!(
399    ///     sub.keys().collect::<Vec<_>>(),
400    ///     vec![net!("192.168.0.0/22"), net!("192.168.0.0/24")]
401    /// );
402    /// # }
403    /// ```
404    #[inline]
405    fn find(self, prefix: &Self::P) -> Option<Self> {
406        let view = navigate_to(self, prefix.mask(), prefix.prefix_len() as u32)?;
407        if view.is_non_empty() {
408            Some(view)
409        } else {
410            None
411        }
412    }
413
414    /// Navigate to `prefix` and return the view only if a value is stored exactly there.
415    ///
416    /// ```
417    /// # use prefix_trie::{PrefixMap, AsView, TrieView};
418    /// # #[cfg(feature = "ipnet")]
419    /// macro_rules! net { ($x:literal) => { $x.parse::<ipnet::Ipv4Net>().unwrap() }; }
420    ///
421    /// # #[cfg(feature = "ipnet")]
422    /// # {
423    /// let mut map = PrefixMap::new();
424    /// map.insert(net!("192.168.0.0/20"), 1);
425    /// map.insert(net!("192.168.0.0/22"), 2);
426    ///
427    /// assert!(map.view().find_exact(&net!("192.168.0.0/21")).is_none());
428    /// assert_eq!(
429    ///     map.view().find_exact(&net!("192.168.0.0/22")).unwrap().value(),
430    ///     Some(&2)
431    /// );
432    /// # }
433    /// ```
434    #[inline]
435    fn find_exact(self, prefix: &Self::P) -> Option<Self> {
436        let view = navigate_to(self, prefix.mask(), prefix.prefix_len() as u32)?;
437        let data_bit = data_bit(view.key(), view.prefix_len());
438        if (view.data_bitmap() >> data_bit) & 1 == 1 {
439            Some(view)
440        } else {
441            None
442        }
443    }
444
445    /// Navigate to `prefix` and return its prefix/value pair if a value is stored exactly there.
446    ///
447    /// This method consumes the view and does not require `Self: Clone`, so it also works with
448    /// mutable views.
449    ///
450    /// ```
451    /// # use prefix_trie::{PrefixMap, AsView, TrieView};
452    /// # #[cfg(feature = "ipnet")]
453    /// macro_rules! net { ($x:literal) => { $x.parse::<ipnet::Ipv4Net>().unwrap() }; }
454    ///
455    /// # #[cfg(feature = "ipnet")]
456    /// # {
457    /// let mut map = PrefixMap::new();
458    /// map.insert(net!("192.168.0.0/22"), 2);
459    ///
460    /// assert_eq!(
461    ///     map.view().find_exact_value(&net!("192.168.0.0/22")),
462    ///     Some((net!("192.168.0.0/22"), &2))
463    /// );
464    /// assert_eq!(map.view().find_exact_value(&net!("192.168.0.0/21")), None);
465    /// # }
466    /// ```
467    #[inline]
468    fn find_exact_value(self, prefix: &Self::P) -> Option<(Self::P, Self::T)> {
469        let view = navigate_to(self, prefix.mask(), prefix.prefix_len() as u32)?;
470        view.prefix_value()
471    }
472
473    /// Find the view pointing at the longest prefix match for `prefix`.
474    ///
475    /// This method requires `Self: Clone` because the search must remember the best matching view
476    /// while it continues descending toward more-specific prefixes.
477    ///
478    /// ```
479    /// # use prefix_trie::{PrefixMap, AsView, TrieView};
480    /// # #[cfg(feature = "ipnet")]
481    /// macro_rules! net { ($x:literal) => { $x.parse::<ipnet::Ipv4Net>().unwrap() }; }
482    ///
483    /// # #[cfg(feature = "ipnet")]
484    /// # {
485    /// let mut map = PrefixMap::new();
486    /// map.insert(net!("192.168.0.0/20"), 1);
487    /// map.insert(net!("192.168.0.0/22"), 2);
488    ///
489    /// let view = map.view().find_lpm(&net!("192.168.0.0/21")).unwrap();
490    /// assert_eq!(view.prefix(), net!("192.168.0.0/20"));
491    /// assert_eq!(view.value(), Some(&1));
492    /// # }
493    /// ```
494    fn find_lpm(mut self, prefix: &Self::P) -> Option<Self>
495    where
496        Self: Clone,
497    {
498        let target_key = prefix.mask();
499        let target_len = prefix.prefix_len() as u32;
500        if !contains_key::<Self::P>(self.key(), self.prefix_len(), target_key, target_len) {
501            return None;
502        }
503        let mut best = None;
504
505        loop {
506            if let Some(data_bit) = lpm_data_bit(&self, target_key, target_len) {
507                let prefix = reconstruct_prefix::<Self::P>(self.depth(), self.key(), data_bit);
508                let mut view = self.clone();
509                // SAFETY: the cloned cursor is moved within its current multibit node.
510                unsafe { view.reposition(prefix.mask(), prefix.prefix_len() as u32) };
511                best = Some(view);
512            }
513
514            if target_len < self.depth() + K {
515                return best;
516            }
517
518            let child_bit = child_bit(self.depth(), target_key);
519            if (self.child_bitmap() >> child_bit) & 1 == 0 {
520                return best;
521            }
522
523            // SAFETY: follows a single path; each child bit is used at most once per view.
524            self = unsafe { self.get_child(child_bit) };
525        }
526    }
527
528    /// Find the longest prefix match for `prefix` and return its prefix/value pair.
529    ///
530    /// This method does not require `Self: Clone`; it can therefore be used with views that yield
531    /// mutable references. It consumes the view and only returns the matched element, not a cursor.
532    ///
533    /// ```
534    /// # use prefix_trie::{PrefixMap, AsView, TrieView};
535    /// # #[cfg(feature = "ipnet")]
536    /// macro_rules! net { ($x:literal) => { $x.parse::<ipnet::Ipv4Net>().unwrap() }; }
537    ///
538    /// # #[cfg(feature = "ipnet")]
539    /// # {
540    /// let mut map = PrefixMap::new();
541    /// map.insert(net!("192.168.0.0/20"), 1);
542    /// map.insert(net!("192.168.0.0/22"), 2);
543    ///
544    /// let (prefix, value) = (&mut map)
545    ///     .view()
546    ///     .find_lpm_value(&net!("192.168.0.0/21"))
547    ///     .unwrap();
548    ///
549    /// assert_eq!(prefix, net!("192.168.0.0/20"));
550    /// *value += 10;
551    /// assert_eq!(map.get(&net!("192.168.0.0/20")), Some(&11));
552    /// # }
553    /// ```
554    fn find_lpm_value(mut self, prefix: &Self::P) -> Option<(Self::P, Self::T)> {
555        let target_key = prefix.mask();
556        let target_len = prefix.prefix_len() as u32;
557        if !contains_key::<Self::P>(self.key(), self.prefix_len(), target_key, target_len) {
558            return None;
559        }
560        let mut best = None;
561
562        loop {
563            if let Some(data_bit) = lpm_data_bit(&self, target_key, target_len) {
564                let prefix = reconstruct_prefix::<Self::P>(self.depth(), self.key(), data_bit);
565                drop(best.take());
566                // SAFETY: each node on the target path is visited at most once, and we keep only
567                // the most-specific matched value.
568                best = Some((prefix, unsafe { self.get_data(data_bit) }));
569            }
570
571            if target_len < self.depth() + K {
572                return best;
573            }
574
575            let child_bit = child_bit(self.depth(), target_key);
576            if (self.child_bitmap() >> child_bit) & 1 == 0 {
577                return best;
578            }
579
580            // SAFETY: follows a single path; each child bit is used at most once per view.
581            self = unsafe { self.get_child(child_bit) };
582        }
583    }
584
585    /// Return an iterator over all `(prefix, value)` pairs in this sub-trie.
586    ///
587    /// ```
588    /// # use prefix_trie::{PrefixMap, AsView, TrieView};
589    /// # #[cfg(feature = "ipnet")]
590    /// macro_rules! net { ($x:literal) => { $x.parse::<ipnet::Ipv4Net>().unwrap() }; }
591    ///
592    /// # #[cfg(feature = "ipnet")]
593    /// # {
594    /// let mut map = PrefixMap::new();
595    /// map.insert(net!("192.168.0.0/20"), 1);
596    /// map.insert(net!("192.168.0.0/22"), 2);
597    /// map.insert(net!("192.168.0.0/24"), 3);
598    ///
599    /// let sub = map.view().find(&net!("192.168.0.0/22")).unwrap();
600    /// assert_eq!(
601    ///     sub.iter().collect::<Vec<_>>(),
602    ///     vec![(net!("192.168.0.0/22"), &2), (net!("192.168.0.0/24"), &3)]
603    /// );
604    /// # }
605    /// ```
606    #[inline]
607    fn iter(self) -> ViewIter<'a, Self> {
608        ViewIter::new(self)
609    }
610
611    /// Iterate over all entries in this sub-trie starting at `prefix`, in lexicographic order.
612    ///
613    /// This enables stateless, cursor-based pagination: pass the last-seen prefix to resume.
614    ///
615    /// - If `inclusive` is `true`, the iterator includes the entry at `prefix` (if present).
616    /// - If `inclusive` is `false`, the iterator starts after `prefix`. Entries more specific than
617    ///   `prefix` (its children) are still yielded.
618    ///
619    /// If `prefix` is not present, the iterator starts at the first entry that would come after
620    /// `prefix` in lexicographic order, regardless of `inclusive`.
621    ///
622    /// ```
623    /// # use prefix_trie::{PrefixMap, AsView, TrieView};
624    /// # #[cfg(feature = "ipnet")]
625    /// macro_rules! net { ($x:literal) => { $x.parse::<ipnet::Ipv4Net>().unwrap() }; }
626    ///
627    /// # #[cfg(feature = "ipnet")]
628    /// # {
629    /// let mut map = PrefixMap::new();
630    /// map.insert(net!("10.0.0.0/8"), 1);
631    /// map.insert(net!("10.1.0.0/16"), 2);
632    /// map.insert(net!("10.2.0.0/16"), 3);
633    /// map.insert(net!("10.3.0.0/16"), 4);
634    ///
635    /// let page: Vec<_> = map.view().iter_from(&net!("10.1.0.0/16"), false).take(2).collect();
636    /// assert_eq!(page, vec![(net!("10.2.0.0/16"), &3), (net!("10.3.0.0/16"), &4)]);
637    /// # }
638    /// ```
639    #[inline]
640    fn iter_from(self, prefix: &Self::P, inclusive: bool) -> ViewIter<'a, Self> {
641        ViewIter::new_from(self, prefix, inclusive)
642    }
643
644    /// Return an iterator over all prefixes in this sub-trie.
645    ///
646    /// ```
647    /// # use prefix_trie::{PrefixMap, AsView, TrieView};
648    /// # #[cfg(feature = "ipnet")]
649    /// macro_rules! net { ($x:literal) => { $x.parse::<ipnet::Ipv4Net>().unwrap() }; }
650    ///
651    /// # #[cfg(feature = "ipnet")]
652    /// # {
653    /// let mut map = PrefixMap::new();
654    /// map.insert(net!("192.168.0.0/20"), 1);
655    /// map.insert(net!("192.168.0.0/22"), 2);
656    /// map.insert(net!("192.168.0.0/24"), 3);
657    ///
658    /// let sub = map.view().find(&net!("192.168.0.0/22")).unwrap();
659    /// assert_eq!(
660    ///     sub.keys().collect::<Vec<_>>(),
661    ///     vec![net!("192.168.0.0/22"), net!("192.168.0.0/24")]
662    /// );
663    /// # }
664    /// ```
665    #[inline]
666    fn keys(self) -> ViewKeys<'a, Self> {
667        ViewKeys::new(self)
668    }
669
670    /// Return an iterator over all values in this sub-trie.
671    ///
672    /// ```
673    /// # use prefix_trie::{PrefixMap, AsView, TrieView};
674    /// # #[cfg(feature = "ipnet")]
675    /// macro_rules! net { ($x:literal) => { $x.parse::<ipnet::Ipv4Net>().unwrap() }; }
676    ///
677    /// # #[cfg(feature = "ipnet")]
678    /// # {
679    /// let mut map = PrefixMap::new();
680    /// map.insert(net!("192.168.0.0/20"), 1);
681    /// map.insert(net!("192.168.0.0/22"), 2);
682    /// map.insert(net!("192.168.0.0/24"), 3);
683    ///
684    /// let sub = map.view().find(&net!("192.168.0.0/22")).unwrap();
685    /// assert_eq!(sub.values().copied().collect::<Vec<_>>(), vec![2, 3]);
686    /// # }
687    /// ```
688    #[inline]
689    fn values(self) -> ViewValues<'a, Self> {
690        ViewValues::new(self)
691    }
692
693    /// Takes a closure and creates a view which calls that closure for each value it yields.
694    ///
695    /// **Warning**: The closure `f` may not applied to all elements of the view if it is further
696    /// combined with others.
697    ///
698    /// ```
699    /// # use prefix_trie::{PrefixMap, AsView, TrieView};
700    /// # #[cfg(feature = "ipnet")]
701    /// macro_rules! net { ($x:literal) => { $x.parse::<ipnet::Ipv4Net>().unwrap() }; }
702    ///
703    /// # #[cfg(feature = "ipnet")]
704    /// # {
705    /// let mut data = PrefixMap::new();
706    /// data.insert(net!("192.168.0.0/20"), 1);
707    /// data.insert(net!("192.168.0.0/22"), 2);
708    /// data.insert(net!("192.168.0.0/24"), 3);
709    ///
710    /// let mapped = data.view().map(|x| *x * 2);
711    /// assert_eq!(mapped.values().collect::<Vec<_>>(), vec![2, 4, 6]);
712    /// # }
713    /// ```
714    fn map<F, U>(self, f: F) -> MapView<'a, Self, F, U>
715    where
716        F: Fn(Self::T) -> U,
717        U: 'a,
718    {
719        MapView {
720            view: self,
721            f,
722            _marker: Default::default(),
723        }
724    }
725
726    /// Takes a closure and creates a view which only yields values for which the closure
727    /// returns `true`.
728    ///
729    /// **Warning**: As with [`map`][Self::map], the predicate may not be evaluated on all
730    /// elements if this view is further combined with others: a branch that an outer
731    /// combinator never descends into is never visited, so the predicate never runs on it.
732    ///
733    /// ```
734    /// # use prefix_trie::{PrefixMap, AsView, TrieView};
735    /// # #[cfg(feature = "ipnet")]
736    /// macro_rules! net { ($x:literal) => { $x.parse::<ipnet::Ipv4Net>().unwrap() }; }
737    ///
738    /// # #[cfg(feature = "ipnet")]
739    /// # {
740    /// let mut data = PrefixMap::new();
741    /// data.insert(net!("192.0.0.0/8"), 1);
742    /// data.insert(net!("192.168.0.0/16"), 2);
743    /// data.insert(net!("192.168.0.0/24"), 3);
744    ///
745    /// let filtered = data.view().filter(|_, x| *x % 2 == 0).copied();
746    /// assert_eq!(filtered.values().collect::<Vec<_>>(), vec![2]);
747    /// # }
748    /// ```
749    fn filter<F>(self, f: F) -> FilterView<'a, Self, F>
750    where
751        F: Fn(Self::P, &Self::T) -> bool,
752    {
753        FilterView::new(self, f)
754    }
755
756    /// Creates a view which clones each value it yields.
757    ///
758    /// ```
759    /// # use prefix_trie::{PrefixMap, AsView, TrieView};
760    /// # #[cfg(feature = "ipnet")]
761    /// macro_rules! net { ($x:literal) => { $x.parse::<ipnet::Ipv4Net>().unwrap() }; }
762    ///
763    /// # #[cfg(feature = "ipnet")]
764    /// # {
765    /// let mut data = PrefixMap::new();
766    /// data.insert(net!("192.168.0.0/20"), vec![1]);
767    /// data.insert(net!("192.168.0.0/22"), vec![2]);
768    /// data.insert(net!("192.168.0.0/24"), vec![3]);
769    ///
770    /// assert_eq!(
771    ///     data.view().cloned().values().collect::<Vec<_>>(),
772    ///     vec![vec![1], vec![2], vec![3]]
773    /// );
774    /// # }
775    /// ```
776    fn cloned<'b, T>(self) -> ClonedView<'a, Self, T>
777    where
778        Self: TrieView<'a, T = &'b T>,
779        T: 'b + Clone,
780    {
781        ClonedView {
782            view: self,
783            _marker: Default::default(),
784        }
785    }
786
787    /// Creates a view which copies each value it yields.
788    ///
789    /// ```
790    /// # use prefix_trie::{PrefixMap, AsView, TrieView};
791    /// # #[cfg(feature = "ipnet")]
792    /// macro_rules! net { ($x:literal) => { $x.parse::<ipnet::Ipv4Net>().unwrap() }; }
793    ///
794    /// # #[cfg(feature = "ipnet")]
795    /// # {
796    /// let mut data = PrefixMap::new();
797    /// data.insert(net!("192.168.0.0/20"), 1);
798    /// data.insert(net!("192.168.0.0/22"), 2);
799    /// data.insert(net!("192.168.0.0/24"), 3);
800    ///
801    /// assert_eq!(data.view().copied().values().collect::<Vec<_>>(), vec![1, 2, 3]);
802    /// # }
803    /// ```
804    fn copied<'b, T>(self) -> CopiedView<'a, Self, T>
805    where
806        Self: TrieView<'a, T = &'b T>,
807        T: 'b + Copy,
808    {
809        CopiedView {
810            view: self,
811            _marker: Default::default(),
812        }
813    }
814
815    /// Return the intersection of `self` and `other` as a view, or `None` if disjoint.
816    ///
817    /// The returned [`IntersectionView`] iterates over every prefix present in **both**
818    /// sub-tries, yielding `(prefix, (left_value, right_value))` in lexicographic order.
819    ///
820    /// ```
821    /// # use prefix_trie::{PrefixMap, AsView, TrieView};
822    /// # #[cfg(feature = "ipnet")]
823    /// macro_rules! net { ($x:literal) => { $x.parse::<ipnet::Ipv4Net>().unwrap() }; }
824    ///
825    /// # #[cfg(feature = "ipnet")]
826    /// # {
827    /// let mut left = PrefixMap::new();
828    /// left.insert(net!("10.0.0.0/8"), 1);
829    /// left.insert(net!("10.1.0.0/16"), 2);
830    ///
831    /// let mut right = PrefixMap::new();
832    /// right.insert(net!("10.1.0.0/16"), 20);
833    /// right.insert(net!("10.1.1.0/24"), 30);
834    ///
835    /// let got: Vec<_> = left
836    ///     .view()
837    ///     .intersection(&right)
838    ///     .unwrap()
839    ///     .iter()
840    ///     .map(|(prefix, (left, right))| (prefix, *left, *right))
841    ///     .collect();
842    ///
843    /// assert_eq!(got, vec![(net!("10.1.0.0/16"), 2, 20)]);
844    /// # }
845    /// ```
846    #[inline]
847    fn intersection<R>(self, other: R) -> Option<IntersectionView<'a, Self, R::View>>
848    where
849        R: AsView<'a, P = Self::P>,
850    {
851        IntersectionView::new(self, other.view())
852    }
853
854    /// Return the union of `self` and `other` as a view.
855    ///
856    /// The returned [`UnionView`] iterates over every prefix present in **either** sub-trie,
857    /// yielding `(prefix, UnionItem)` in lexicographic order.
858    ///
859    /// ```
860    /// # use prefix_trie::{PrefixMap, AsView, TrieView};
861    /// # use prefix_trie::trieview::union::UnionItem;
862    /// # #[cfg(feature = "ipnet")]
863    /// macro_rules! net { ($x:literal) => { $x.parse::<ipnet::Ipv4Net>().unwrap() }; }
864    ///
865    /// # #[cfg(feature = "ipnet")]
866    /// # {
867    /// let mut left = PrefixMap::new();
868    /// left.insert(net!("10.0.0.0/8"), 1);
869    /// left.insert(net!("10.1.0.0/16"), 2);
870    ///
871    /// let mut right = PrefixMap::new();
872    /// right.insert(net!("10.1.0.0/16"), 20);
873    /// right.insert(net!("10.1.1.0/24"), 30);
874    ///
875    /// let got: Vec<_> = left
876    ///     .view()
877    ///     .union(&right)
878    ///     .iter()
879    ///     .map(|(prefix, item)| match item {
880    ///         UnionItem::Left(left) => (prefix, Some(*left), None),
881    ///         UnionItem::Right(right) => (prefix, None, Some(*right)),
882    ///         UnionItem::Both(left, right) => (prefix, Some(*left), Some(*right)),
883    ///     })
884    ///     .collect();
885    ///
886    /// assert_eq!(
887    ///     got,
888    ///     vec![
889    ///         (net!("10.0.0.0/8"), Some(1), None),
890    ///         (net!("10.1.0.0/16"), Some(2), Some(20)),
891    ///         (net!("10.1.1.0/24"), None, Some(30)),
892    ///     ]
893    /// );
894    /// # }
895    /// ```
896    #[inline]
897    fn union<R>(self, other: R) -> UnionView<'a, Self, R::View>
898    where
899        R: AsView<'a, P = Self::P>,
900    {
901        UnionView::new(self, other.view())
902    }
903
904    /// Return the covering union of `self` and `other` as a view.
905    ///
906    /// The returned [`CoveringUnionView`] iterates over every prefix present in either sub-trie.
907    /// For prefixes present on only one side, the yielded item includes the longest prefix match
908    /// from the opposite side when one exists inside that opposite view.
909    ///
910    /// ```
911    /// # use prefix_trie::{PrefixMap, AsView, TrieView};
912    /// # use prefix_trie::trieview::CoveringUnionItem;
913    /// # #[cfg(feature = "ipnet")]
914    /// macro_rules! net { ($x:literal) => { $x.parse::<ipnet::Ipv4Net>().unwrap() }; }
915    ///
916    /// # #[cfg(feature = "ipnet")]
917    /// # {
918    /// let mut left = PrefixMap::new();
919    /// left.insert(net!("10.1.0.0/16"), 2);
920    ///
921    /// let mut right = PrefixMap::new();
922    /// right.insert(net!("10.0.0.0/8"), 10);
923    ///
924    /// let (_, item) = left
925    ///     .view()
926    ///     .covering_union(&right)
927    ///     .iter()
928    ///     .find(|(prefix, _)| prefix == &net!("10.1.0.0/16"))
929    ///     .unwrap();
930    ///
931    /// match item {
932    ///     CoveringUnionItem::Left {
933    ///         left,
934    ///         right_lpm: Some((right_prefix, right)),
935    ///     } => {
936    ///         assert_eq!(*left, 2);
937    ///         assert_eq!(right_prefix, net!("10.0.0.0/8"));
938    ///         assert_eq!(*right, 10);
939    ///     }
940    ///     _ => panic!("expected a left-only prefix covered by the right side"),
941    /// }
942    /// # }
943    /// ```
944    #[inline]
945    fn covering_union<R>(self, other: R) -> CoveringUnionView<'a, Self, R::View>
946    where
947        Self: Clone,
948        R: AsView<'a, P = Self::P>,
949        R::View: Clone,
950    {
951        CoveringUnionView::new(self, other.view())
952    }
953
954    /// Return the difference of `self` minus `other` as a view.
955    ///
956    /// The returned [`DifferenceView`] iterates over every prefix present in `self` but
957    /// **not** in `other`, yielding values from `self` in lexicographic order.
958    ///
959    /// ```
960    /// # use prefix_trie::{PrefixMap, AsView, TrieView};
961    /// # #[cfg(feature = "ipnet")]
962    /// macro_rules! net { ($x:literal) => { $x.parse::<ipnet::Ipv4Net>().unwrap() }; }
963    ///
964    /// # #[cfg(feature = "ipnet")]
965    /// # {
966    /// let mut left = PrefixMap::new();
967    /// left.insert(net!("10.0.0.0/8"), 1);
968    /// left.insert(net!("10.1.0.0/16"), 2);
969    /// left.insert(net!("10.1.1.0/24"), 3);
970    ///
971    /// let mut right = PrefixMap::new();
972    /// right.insert(net!("10.1.0.0/16"), 20);
973    ///
974    /// let got: Vec<_> = left
975    ///     .view()
976    ///     .difference(&right)
977    ///     .iter()
978    ///     .map(|(prefix, value)| (prefix, *value))
979    ///     .collect();
980    ///
981    /// assert_eq!(got, vec![(net!("10.0.0.0/8"), 1), (net!("10.1.1.0/24"), 3)]);
982    /// # }
983    /// ```
984    #[inline]
985    fn difference<R>(self, other: R) -> DifferenceView<'a, Self, R::View>
986    where
987        R: AsView<'a, P = Self::P>,
988    {
989        DifferenceView::new(self, other.view())
990    }
991
992    /// Check whether `self` and `other` contain exactly the same set of prefixes,
993    /// ignoring values.
994    ///
995    /// This uses a bitmap-based structural comparison (no prefix reconstruction)
996    /// and short-circuits as soon as a difference is found.
997    ///
998    /// ```
999    /// # use prefix_trie::{PrefixMap, PrefixSet, AsView, TrieView};
1000    /// # type P = (u32, u8);
1001    /// let a: PrefixMap<P, _> = [((0, 8), 1), ((0, 16), 2)].into_iter().collect();
1002    /// let b: PrefixMap<P, _> = [((0, 8), 9), ((0, 16), 9)].into_iter().collect();
1003    /// let c: PrefixMap<P, _> = [((0, 8), 1)].into_iter().collect();
1004    ///
1005    /// assert!(a.view().eq_keys(&b));   // same keys, different values
1006    /// assert!(!a.view().eq_keys(&c));  // different key sets
1007    /// ```
1008    fn eq_keys<R: AsView<'a, P = Self::P>>(self, other: R) -> bool {
1009        equality::eq_keys_recursive(self, other.view())
1010    }
1011
1012    /// Check whether `self` and `other` contain the same prefixes with equal values,
1013    /// using `cmp` to compare each value pair.
1014    ///
1015    /// Iterates both views in lexicographic order, verifying that prefixes match
1016    /// and `cmp` returns `true` for every value pair, and that both views have the
1017    /// same number of entries.
1018    ///
1019    /// ```
1020    /// # use prefix_trie::{PrefixMap, AsView, TrieView};
1021    /// # type P = (u32, u8);
1022    /// let a: PrefixMap<P, _> = [((0, 8), 1), ((0, 16), 2)].into_iter().collect();
1023    /// let b: PrefixMap<P, _> = [((0, 8), 1), ((0, 16), 2)].into_iter().collect();
1024    /// let c: PrefixMap<P, _> = [((0, 8), 1), ((0, 16), 9)].into_iter().collect();
1025    ///
1026    /// assert!(a.view().eq_by(&b, |a, b| a == b));
1027    /// assert!(!a.view().eq_by(&c, |a, b| a == b));
1028    /// ```
1029    fn eq_by<R, F>(self, other: R, mut cmp: F) -> bool
1030    where
1031        Self::P: PartialEq,
1032        R: AsView<'a, P = Self::P>,
1033        F: FnMut(Self::T, <<R as AsView<'a>>::View as TrieView<'a>>::T) -> bool,
1034    {
1035        let mut left = self.iter();
1036        let mut right = other.view().iter();
1037        loop {
1038            match (left.next(), right.next()) {
1039                (None, None) => return true,
1040                (Some((lp, lv)), Some((rp, rv))) if lp == rp => {
1041                    if !cmp(lv, rv) {
1042                        return false;
1043                    }
1044                }
1045                _ => return false,
1046            }
1047        }
1048    }
1049
1050    /// Return the covering difference of `self` minus `other` as a view.
1051    ///
1052    /// Iterates over every prefix `P_l` in `self` for which no covering prefix `P_r`
1053    /// exists in `other` (`P_r.len ≤ P_l.len` and `P_r` matches `P_l`'s leading bits).
1054    ///
1055    /// ```
1056    /// # use prefix_trie::{PrefixMap, AsView, TrieView};
1057    /// # #[cfg(feature = "ipnet")]
1058    /// macro_rules! net { ($x:literal) => { $x.parse::<ipnet::Ipv4Net>().unwrap() }; }
1059    ///
1060    /// # #[cfg(feature = "ipnet")]
1061    /// # {
1062    /// let mut left = PrefixMap::new();
1063    /// left.insert(net!("10.0.0.0/8"), 1);
1064    /// left.insert(net!("10.1.0.0/16"), 2);
1065    /// left.insert(net!("10.1.1.0/24"), 3);
1066    ///
1067    /// let mut right = PrefixMap::new();
1068    /// right.insert(net!("10.1.0.0/16"), 20);
1069    ///
1070    /// let got: Vec<_> = left
1071    ///     .view()
1072    ///     .covering_difference(&right)
1073    ///     .iter()
1074    ///     .map(|(prefix, value)| (prefix, *value))
1075    ///     .collect();
1076    ///
1077    /// assert_eq!(got, vec![(net!("10.0.0.0/8"), 1)]);
1078    /// # }
1079    /// ```
1080    #[inline]
1081    fn covering_difference<R>(self, other: R) -> CoveringDifferenceView<'a, Self, R::View>
1082    where
1083        R: AsView<'a, P = Self::P>,
1084    {
1085        CoveringDifferenceView::new(self, other.view())
1086    }
1087}
1088
1089// -----------------------------------------------------------------------------
1090// Private helper
1091// -----------------------------------------------------------------------------
1092
1093/// Step one binary level deeper, going left (0-bit) or right (1-bit).
1094fn step<'a, V, P, T>(mut view: V, go_right: bool) -> Option<V>
1095where
1096    V: TrieView<'a, P = P, T = T>,
1097    P: Prefix,
1098{
1099    let num_bits = P::R::zero().count_zeros();
1100    // Cannot descend past the key width.
1101    if view.prefix_len() >= num_bits {
1102        return None;
1103    }
1104    let new_prefix_len = view.prefix_len() + 1;
1105    let new_key = if go_right {
1106        let bit_pos = num_bits - view.prefix_len() - 1;
1107        view.key() | P::R::one().unsigned_shl(bit_pos)
1108    } else {
1109        view.key()
1110    };
1111
1112    if new_prefix_len < view.depth() + K {
1113        // Intra-node: narrow the position cursor within the same node.
1114        // SAFETY: view is not used for data access after this; only `view` is used.
1115        unsafe { view.reposition(new_key, new_prefix_len) };
1116        if view.is_non_empty() {
1117            Some(view)
1118        } else {
1119            None
1120        }
1121    } else {
1122        // Cross into a child node (new_prefix_len == depth + K).
1123        let child_bit = child_bit(view.depth(), new_key);
1124        if (view.child_bitmap() >> child_bit) & 1 == 0 {
1125            return None;
1126        }
1127        // SAFETY: step is called for one direction at a time; child_bit is used once.
1128        Some(unsafe { view.get_child(child_bit) })
1129    }
1130}
1131
1132/// Navigate toward `(target_key, target_len)` from this view's node.
1133///
1134/// Returns `None` if a required child node does not exist in [`child_bitmap`][Self::child_bitmap].
1135fn navigate_to<'a, V, P, T>(mut view: V, target_key: P::R, target_len: u32) -> Option<V>
1136where
1137    V: TrieView<'a, P = P, T = T>,
1138    P: Prefix,
1139{
1140    if !contains_key::<P>(view.key(), view.prefix_len(), target_key, target_len) {
1141        return None;
1142    }
1143
1144    while target_len >= view.depth() + K {
1145        let child_bit = child_bit(view.depth(), target_key);
1146        if (view.child_bitmap() >> child_bit) & 1 == 0 {
1147            return None;
1148        }
1149        // SAFETY: follows a single path; each child_bit used exactly once per
1150        // view instance before view is replaced by the returned child.
1151        view = unsafe { view.get_child(child_bit) };
1152    }
1153
1154    // SAFETY: view is replaced by the repositioned cursor; the old position is
1155    // not used for data access after this point. `target` is checked above to sit at or
1156    // below the view's current position.
1157    unsafe { view.reposition(target_key, target_len) }
1158    Some(view)
1159}
1160
1161fn contains_key<P: Prefix>(
1162    root_key: P::R,
1163    root_len: u32,
1164    target_key: P::R,
1165    target_len: u32,
1166) -> bool {
1167    if root_len > target_len {
1168        return false;
1169    }
1170    let mask = mask_from_prefix_len(root_len as u8);
1171    root_key & mask == target_key & mask
1172}
1173
1174fn lpm_data_bit<'a, V: TrieView<'a>>(
1175    view: &V,
1176    target_key: <V::P as Prefix>::R,
1177    target_len: u32,
1178) -> Option<u32> {
1179    let data_bits = view.data_bitmap() & data_lpm_mask(view.depth(), target_key, target_len);
1180    if data_bits == 0 {
1181        None
1182    } else {
1183        Some(u32::BITS - 1 - data_bits.leading_zeros())
1184    }
1185}
1186
1187/// Reconstruct the prefix at `data_bit` within the node starting at `depth`.
1188pub(crate) fn reconstruct_prefix<P: Prefix>(depth: u32, key: P::R, data_bit: u32) -> P {
1189    let (offset, level) = DATA_BIT_TO_PREFIX[data_bit as usize];
1190    let prefix_len = depth + level as u32;
1191    let root = key & mask_from_prefix_len(depth as u8);
1192    let offset_r = <P::R as num_traits::cast::NumCast>::from(offset).unwrap();
1193    let offset_bits = K - 1;
1194    let total_width = P::num_bits();
1195    let shifted = if total_width > depth + offset_bits {
1196        offset_r << (total_width - (depth + offset_bits)) as usize
1197    } else {
1198        offset_r >> (depth + offset_bits - total_width) as usize
1199    };
1200    P::from_repr_len(root | shifted, prefix_len as u8)
1201}
1202
1203/// Trait that is implemented on structures that can be turned into a view.
1204pub trait AsView<'a> {
1205    /// The prefix type.
1206    type P: Prefix;
1207    /// The concrete view type returned by [`view`][AsView::view].
1208    type View: TrieView<'a, P = Self::P>;
1209
1210    /// Get a view rooted at the origin (the entire trie).
1211    fn view(self) -> Self::View;
1212
1213    /// Get a view rooted at `prefix`, or `None` if the sub-trie is empty.
1214    ///
1215    /// The emptiness check may over-approximate on composed views (see
1216    /// [`TrieView::is_non_empty`]): the returned view may yield no entries when iterated.
1217    /// `None` always means that the view contains nothing at or below `prefix`. To check
1218    /// exactly whether the sub-trie contains an entry, iterate the returned view:
1219    /// `view.iter().next().is_none()`. Note that [`TrieView::iter`] takes the view by value;
1220    /// clone it first if you still need it afterwards.
1221    fn view_at(self, prefix: &Self::P) -> Option<Self::View>
1222    where
1223        Self: Sized,
1224    {
1225        self.view().find(prefix)
1226    }
1227}