Skip to main content

prefix_trie/trieview/
iter.rs

1//! Generic iterator over all `(prefix, value)` pairs in a [`TrieView`] sub-trie.
2//!
3//! [`ViewIter`] works for all view types: [`TrieRef`][super::TrieRef],
4//! [`IntersectionView`][super::IntersectionView], [`UnionView`][super::union::UnionView],
5//! [`DifferenceView`][super::DifferenceView], etc. (through a single generic implementation).
6
7use crate::{
8    node::{child_bit, data_bit, lex_after_child, lex_after_data, lex_order},
9    prefix::mask_from_prefix_len,
10    Prefix,
11};
12
13use super::{reconstruct_prefix, TrieView, K};
14
15/// Iterator over all `(prefix, value)` pairs in a [`TrieView`] sub-trie.
16///
17/// Yields entries in lexicographic (DFS pre-order) order. The single generic implementation
18/// works for all view types: [`TrieRef`][super::TrieRef], `IntersectionView`, etc.
19pub struct ViewIter<'a, V: TrieView<'a>> {
20    stack: Vec<IterElem<'a, V>>,
21}
22
23/// An entry on the iterator's internal stack.
24enum IterElem<'a, V: TrieView<'a>> {
25    /// A node whose data and children have not yet been expanded.
26    Node(V),
27    /// A ready-to-yield item.
28    Item(V::P, V::T),
29}
30
31impl<'a, V: TrieView<'a>> ViewIter<'a, V> {
32    pub(super) fn new(root: V) -> Self {
33        let mut stack = Vec::new();
34        expand_node(&mut stack, root);
35        Self { stack }
36    }
37
38    pub(super) fn new_from(view: V, prefix: &V::P, inclusive: bool) -> Self {
39        let target_key = prefix.mask();
40        let target_len = prefix.prefix_len() as u32;
41        let mut stack = Vec::new();
42        build_iter_from_stack(&mut stack, view, target_key, target_len, inclusive);
43        Self { stack }
44    }
45}
46
47/// Iterator over all prefixes in a [`TrieView`] sub-trie.
48pub struct ViewKeys<'a, V: TrieView<'a>>(ViewIter<'a, V>);
49
50impl<'a, V: TrieView<'a>> ViewKeys<'a, V> {
51    pub(super) fn new(root: V) -> Self {
52        Self(ViewIter::new(root))
53    }
54}
55
56impl<'a, V: TrieView<'a>> Iterator for ViewKeys<'a, V> {
57    type Item = V::P;
58
59    fn next(&mut self) -> Option<Self::Item> {
60        self.0.next().map(|(prefix, _)| prefix)
61    }
62}
63
64/// Iterator over all values in a [`TrieView`] sub-trie.
65pub struct ViewValues<'a, V: TrieView<'a>>(ViewIter<'a, V>);
66
67impl<'a, V: TrieView<'a>> ViewValues<'a, V> {
68    pub(super) fn new(root: V) -> Self {
69        Self(ViewIter::new(root))
70    }
71}
72
73impl<'a, V: TrieView<'a>> Iterator for ViewValues<'a, V> {
74    type Item = V::T;
75
76    fn next(&mut self) -> Option<Self::Item> {
77        self.0.next().map(|(_, value)| value)
78    }
79}
80
81/// Expand `view` into its data items and child nodes, pushing them onto `stack`
82/// in **reverse** lexicographic order so that popping yields the correct lex order.
83#[inline]
84fn expand_node<'a, V: TrieView<'a>>(stack: &mut Vec<IterElem<'a, V>>, view: V) {
85    expand_node_masked(stack, view, !0, !0)
86}
87
88/// Like [`expand_node`], but additionally masks data and child bits with the given masks.
89#[inline]
90fn expand_node_masked<'a, V: TrieView<'a>>(
91    stack: &mut Vec<IterElem<'a, V>>,
92    mut view: V,
93    data_mask: u32,
94    child_mask: u32,
95) {
96    let effective_data = view.data_bitmap() & data_mask;
97    let effective_children = view.child_bitmap() & child_mask;
98
99    for elem in lex_order().rev() {
100        match elem {
101            Ok(data_bit) => {
102                if (effective_data >> data_bit) & 1 == 0 {
103                    continue;
104                }
105                let prefix = reconstruct_prefix::<V::P>(view.depth(), view.key(), data_bit);
106                // SAFETY: each data_bit is visited at most once per expand_node call;
107                // the effective bitmap is a subset of data_bitmap(), and we iterate
108                // each set bit exactly once.
109                let value = unsafe { view.get_data(data_bit) };
110                stack.push(IterElem::Item(prefix, value));
111            }
112            Err(child_bit) => {
113                if (effective_children >> child_bit) & 1 == 0 {
114                    continue;
115                }
116                // SAFETY: each child_bit is visited at most once per expand_node call.
117                stack.push(IterElem::Node(unsafe { view.get_child(child_bit) }));
118            }
119        }
120    }
121}
122
123/// Build an iterator stack starting from `current` that yields entries at or after
124/// `(target_key, target_len)` in lexicographic order.
125fn build_iter_from_stack<'a, V: TrieView<'a>>(
126    stack: &mut Vec<IterElem<'a, V>>,
127    mut current: V,
128    target_key: <V::P as Prefix>::R,
129    target_len: u32,
130    inclusive: bool,
131) {
132    // Check containment: does the target share the view's prefix?
133    let view_mask = mask_from_prefix_len(current.prefix_len() as u8);
134    let view_prefix = current.key() & view_mask;
135    let target_at_view_len = target_key & view_mask;
136
137    if view_prefix != target_at_view_len {
138        // Target is outside this view's sub-trie.
139        // All entries share view_prefix; compare to determine before/after.
140        if view_prefix > target_at_view_len {
141            // All entries come after target → full iter
142            expand_node(stack, current);
143        }
144        // else: all entries come before target → empty iter
145        return;
146    }
147
148    // Target is within this view's sub-trie (or is the view's prefix itself).
149
150    if target_len <= current.prefix_len() {
151        // Target encompasses the view's position.
152        if target_len == current.prefix_len() && !inclusive {
153            // Skip the exact root value, include everything else.
154            let db = data_bit(current.key(), current.prefix_len());
155            expand_node_masked(stack, current, !(1u32 << db), !0);
156        } else {
157            expand_node(stack, current);
158        }
159        return;
160    }
161
162    // Target is deeper than the view's position. Navigate toward it.
163    loop {
164        if target_len < current.depth() + K {
165            // Target falls within this node as a data slot.
166            let db = data_bit(target_key, target_len);
167            let (data_mask, child_mask) = lex_after_data(db);
168            let data_mask = if inclusive {
169                data_mask
170            } else {
171                data_mask & !(1 << db)
172            };
173            expand_node_masked(stack, current, data_mask, child_mask);
174            break;
175        }
176
177        // Target is deeper; follow the child pointer.
178        let cb = child_bit(current.depth(), target_key);
179        let (data_mask, child_mask) = lex_after_child(cb);
180
181        let has_child = (current.child_bitmap() >> cb) & 1 == 1;
182        let child = if has_child {
183            // SAFETY: cb is not in child_mask (lex_after_child excludes it),
184            // so it won't be accessed again in expand_node_masked below.
185            Some(unsafe { current.get_child(cb) })
186        } else {
187            None
188        };
189
190        expand_node_masked(stack, current, data_mask, child_mask);
191
192        match child {
193            Some(c) => current = c,
194            None => break,
195        }
196    }
197}
198
199impl<'a, V: TrieView<'a>> Iterator for ViewIter<'a, V> {
200    type Item = (V::P, V::T);
201
202    fn next(&mut self) -> Option<Self::Item> {
203        loop {
204            match self.stack.pop()? {
205                IterElem::Item(prefix, value) => return Some((prefix, value)),
206                IterElem::Node(view) => expand_node(&mut self.stack, view),
207            }
208        }
209    }
210}