Skip to main content

prefix_trie/map/
mod.rs

1//! Implementation of the Prefix Map.
2
3use std::num::NonZeroUsize;
4
5use crate::{
6    inner::{Direction, DirectionForInsert, Node, Table},
7    Prefix,
8};
9
10// Include the entry and iter module last, to ensure correct docs.
11mod entry;
12mod iter;
13
14pub use entry::*;
15pub use iter::*;
16
17/// Prefix map implemented as a prefix tree.
18///
19/// You can perform union, intersection, and (covering) difference operations by first creating a
20/// view over the map using [`crate::AsView`] or [`crate::AsViewMut`].
21#[derive(Clone)]
22pub struct PrefixMap<P, T> {
23    pub(crate) table: Table<P, T>,
24    free: Vec<NonZeroUsize>,
25    count: usize,
26}
27
28impl<P, T> Default for PrefixMap<P, T>
29where
30    P: Prefix,
31{
32    fn default() -> Self {
33        Self {
34            table: Default::default(),
35            free: Vec::new(),
36            count: 0,
37        }
38    }
39}
40
41impl<P, T> PrefixMap<P, T>
42where
43    P: Prefix,
44{
45    /// Create an empty prefix map.
46    pub fn new() -> Self {
47        Self::default()
48    }
49
50    /// Returns the number of elements stored in `self`.
51    #[inline(always)]
52    pub fn len(&self) -> usize {
53        self.count
54    }
55
56    /// Returns `true` if the map contains no elements.
57    #[inline(always)]
58    pub fn is_empty(&self) -> bool {
59        self.count == 0
60    }
61
62    /// Get the value of an element by matching exactly on the prefix.
63    ///
64    /// ```
65    /// # use prefix_trie::*;
66    /// # #[cfg(feature = "ipnet")]
67    /// # fn main() -> Result<(), Box<dyn std::error::Error>> {
68    /// let mut pm: PrefixMap<ipnet::Ipv4Net, _> = PrefixMap::new();
69    /// pm.insert("192.168.1.0/24".parse()?, 1);
70    /// assert_eq!(pm.get(&"192.168.1.0/24".parse()?), Some(&1));
71    /// assert_eq!(pm.get(&"192.168.2.0/24".parse()?), None);
72    /// assert_eq!(pm.get(&"192.168.0.0/23".parse()?), None);
73    /// assert_eq!(pm.get(&"192.168.1.128/25".parse()?), None);
74    /// # Ok(())
75    /// # }
76    /// # #[cfg(not(feature = "ipnet"))]
77    /// # fn main() {}
78    /// ```
79    pub fn get<'a>(&'a self, prefix: &P) -> Option<&'a T> {
80        let mut idx = 0;
81        loop {
82            match self.table.get_direction(idx, prefix) {
83                Direction::Reached => return self.table[idx].value.as_ref(),
84                Direction::Enter { next, .. } => idx = next.get(),
85                Direction::Missing => return None,
86            }
87        }
88    }
89
90    /// Get a mutable reference to a value of an element by matching exactly on the prefix.
91    ///
92    /// ```
93    /// # use prefix_trie::*;
94    /// # #[cfg(feature = "ipnet")]
95    /// # fn main() -> Result<(), Box<dyn std::error::Error>> {
96    /// let mut pm: PrefixMap<ipnet::Ipv4Net, _> = PrefixMap::new();
97    /// let prefix = "192.168.1.0/24".parse()?;
98    /// pm.insert(prefix, 1);
99    /// assert_eq!(pm.get(&prefix), Some(&1));
100    /// *pm.get_mut(&prefix).unwrap() += 1;
101    /// assert_eq!(pm.get(&prefix), Some(&2));
102    /// # Ok(())
103    /// # }
104    /// # #[cfg(not(feature = "ipnet"))]
105    /// # fn main() {}
106    /// ```
107    pub fn get_mut<'a>(&'a mut self, prefix: &P) -> Option<&'a mut T> {
108        let mut idx = 0;
109        loop {
110            match self.table.get_direction(idx, prefix) {
111                Direction::Reached => return self.table[idx].value.as_mut(),
112                Direction::Enter { next, .. } => idx = next.get(),
113                Direction::Missing => return None,
114            }
115        }
116    }
117
118    /// Get the value of an element by matching exactly on the prefix. Notice, that the returned
119    /// prefix may differ from the one provided in the host-part of the address.
120    ///
121    /// ```
122    /// # use prefix_trie::*;
123    /// # #[cfg(feature = "ipnet")]
124    /// # fn main() -> Result<(), Box<dyn std::error::Error>> {
125    /// let mut pm: PrefixMap<ipnet::Ipv4Net, _> = PrefixMap::new();
126    /// let prefix = "192.168.1.0/24".parse()?;
127    /// pm.insert(prefix, 1);
128    /// assert_eq!(pm.get_key_value(&prefix), Some((&prefix, &1)));
129    /// # Ok(())
130    /// # }
131    /// # #[cfg(not(feature = "ipnet"))]
132    /// # fn main() {}
133    /// ```
134    pub fn get_key_value<'a>(&'a self, prefix: &P) -> Option<(&'a P, &'a T)> {
135        let mut idx = 0;
136        loop {
137            match self.table.get_direction(idx, prefix) {
138                Direction::Reached => return self.table[idx].prefix_value(),
139                Direction::Enter { next, .. } => idx = next.get(),
140                Direction::Missing => return None,
141            }
142        }
143    }
144
145    /// Get a value of an element by using longest prefix matching
146    ///
147    /// ```
148    /// # use prefix_trie::*;
149    /// # #[cfg(feature = "ipnet")]
150    /// # fn main() -> Result<(), Box<dyn std::error::Error>> {
151    /// let mut pm: PrefixMap<ipnet::Ipv4Net, _> = PrefixMap::new();
152    /// pm.insert("192.168.1.0/24".parse()?, 1);
153    /// pm.insert("192.168.0.0/23".parse()?, 2);
154    /// assert_eq!(pm.get_lpm(&"192.168.1.1/32".parse()?), Some((&"192.168.1.0/24".parse()?, &1)));
155    /// assert_eq!(pm.get_lpm(&"192.168.1.0/24".parse()?), Some((&"192.168.1.0/24".parse()?, &1)));
156    /// assert_eq!(pm.get_lpm(&"192.168.0.0/24".parse()?), Some((&"192.168.0.0/23".parse()?, &2)));
157    /// assert_eq!(pm.get_lpm(&"192.168.2.0/24".parse()?), None);
158    /// # Ok(())
159    /// # }
160    /// # #[cfg(not(feature = "ipnet"))]
161    /// # fn main() {}
162    /// ```
163    pub fn get_lpm<'a>(&'a self, prefix: &P) -> Option<(&'a P, &'a T)> {
164        let mut idx = 0;
165        let mut best_match: Option<(&P, &T)> = None;
166        loop {
167            best_match = self.table[idx].prefix_value().or(best_match);
168            match self.table.get_direction(idx, prefix) {
169                Direction::Enter { next, .. } => idx = next.get(),
170                _ => return best_match,
171            }
172        }
173    }
174
175    /// Get a mutable reference to a value of an element by using longest prefix matching
176    ///
177    /// ```
178    /// # use prefix_trie::*;
179    /// # #[cfg(feature = "ipnet")]
180    /// # fn main() -> Result<(), Box<dyn std::error::Error>> {
181    /// let mut pm: PrefixMap<ipnet::Ipv4Net, _> = PrefixMap::new();
182    /// pm.insert("192.168.1.0/24".parse()?, 1);
183    /// pm.insert("192.168.0.0/23".parse()?, 2);
184    /// assert_eq!(pm.get_lpm(&"192.168.1.1/32".parse()?), Some((&"192.168.1.0/24".parse()?, &1)));
185    /// *pm.get_lpm_mut(&"192.168.1.64/26".parse()?).unwrap().1 += 1;
186    /// assert_eq!(pm.get_lpm(&"192.168.1.1/32".parse()?), Some((&"192.168.1.0/24".parse()?, &2)));
187    /// # Ok(())
188    /// # }
189    /// # #[cfg(not(feature = "ipnet"))]
190    /// # fn main() {}
191    /// ```
192    pub fn get_lpm_mut<'a>(&'a mut self, prefix: &P) -> Option<(&'a P, &'a mut T)> {
193        let mut idx = 0;
194        let mut best_match: Option<usize> = None;
195        loop {
196            best_match = if self.table[idx].value.is_some() {
197                Some(idx)
198            } else {
199                best_match
200            };
201            match self.table.get_direction(idx, prefix) {
202                Direction::Enter { next, .. } => idx = next.get(),
203                _ => break,
204            }
205        }
206        if let Some(idx) = best_match {
207            self.table[idx].prefix_value_mut()
208        } else {
209            None
210        }
211    }
212
213    /// Check if a key is present in the datastructure.
214    ///
215    /// ```
216    /// # use prefix_trie::*;
217    /// # #[cfg(feature = "ipnet")]
218    /// # fn main() -> Result<(), Box<dyn std::error::Error>> {
219    /// let mut pm: PrefixMap<ipnet::Ipv4Net, _> = PrefixMap::new();
220    /// pm.insert("192.168.1.0/24".parse()?, 1);
221    /// assert!(pm.contains_key(&"192.168.1.0/24".parse()?));
222    /// assert!(!pm.contains_key(&"192.168.2.0/24".parse()?));
223    /// assert!(!pm.contains_key(&"192.168.0.0/23".parse()?));
224    /// assert!(!pm.contains_key(&"192.168.1.128/25".parse()?));
225    /// # Ok(())
226    /// # }
227    /// # #[cfg(not(feature = "ipnet"))]
228    /// # fn main() {}
229    /// ```
230    pub fn contains_key(&self, prefix: &P) -> bool {
231        let mut idx = 0;
232        loop {
233            match self.table.get_direction(idx, prefix) {
234                Direction::Reached => return self.table[idx].value.is_some(),
235                Direction::Enter { next, .. } => idx = next.get(),
236                Direction::Missing => return false,
237            }
238        }
239    }
240
241    /// Get the longest prefix in the datastructure that matches the given `prefix`.
242    ///
243    /// ```
244    /// # use prefix_trie::*;
245    /// # #[cfg(feature = "ipnet")]
246    /// # fn main() -> Result<(), Box<dyn std::error::Error>> {
247    /// let mut pm: PrefixMap<ipnet::Ipv4Net, _> = PrefixMap::new();
248    /// pm.insert("192.168.1.0/24".parse()?, 1);
249    /// pm.insert("192.168.0.0/23".parse()?, 2);
250    /// assert_eq!(pm.get_lpm_prefix(&"192.168.1.1/32".parse()?), Some(&"192.168.1.0/24".parse()?));
251    /// assert_eq!(pm.get_lpm_prefix(&"192.168.1.0/24".parse()?), Some(&"192.168.1.0/24".parse()?));
252    /// assert_eq!(pm.get_lpm_prefix(&"192.168.0.0/24".parse()?), Some(&"192.168.0.0/23".parse()?));
253    /// assert_eq!(pm.get_lpm_prefix(&"192.168.2.0/24".parse()?), None);
254    /// # Ok(())
255    /// # }
256    /// # #[cfg(not(feature = "ipnet"))]
257    /// # fn main() {}
258    /// ```
259    pub fn get_lpm_prefix<'a>(&'a self, prefix: &P) -> Option<&'a P> {
260        let mut idx = 0;
261        let mut best_match: Option<&P> = None;
262        loop {
263            best_match = self.table[idx]
264                .prefix_value()
265                .map(|(p, _)| p)
266                .or(best_match);
267            match self.table.get_direction(idx, prefix) {
268                Direction::Enter { next, .. } => idx = next.get(),
269                _ => return best_match,
270            }
271        }
272    }
273
274    /// Get a value of an element by using shortest prefix matching.
275    ///
276    /// ```
277    /// # use prefix_trie::*;
278    /// # #[cfg(feature = "ipnet")]
279    /// # fn main() -> Result<(), Box<dyn std::error::Error>> {
280    /// let mut pm: PrefixMap<ipnet::Ipv4Net, _> = PrefixMap::new();
281    /// pm.insert("192.168.1.0/24".parse()?, 1);
282    /// pm.insert("192.168.0.0/23".parse()?, 2);
283    /// assert_eq!(pm.get_spm(&"192.168.1.1/32".parse()?), Some((&"192.168.0.0/23".parse()?, &2)));
284    /// assert_eq!(pm.get_spm(&"192.168.1.0/24".parse()?), Some((&"192.168.0.0/23".parse()?, &2)));
285    /// assert_eq!(pm.get_spm(&"192.168.0.0/23".parse()?), Some((&"192.168.0.0/23".parse()?, &2)));
286    /// assert_eq!(pm.get_spm(&"192.168.2.0/24".parse()?), None);
287    /// # Ok(())
288    /// # }
289    /// # #[cfg(not(feature = "ipnet"))]
290    /// # fn main() {}
291    pub fn get_spm<'a>(&'a self, prefix: &P) -> Option<(&'a P, &'a T)> {
292        // Handle the special case, where the root is populated
293        if let Some(x) = self.table[0usize].prefix_value() {
294            return Some(x);
295        }
296        let mut idx = 0;
297        loop {
298            match self.table.get_direction(idx, prefix) {
299                Direction::Reached => return self.table[idx].prefix_value(),
300                Direction::Enter { next, .. } => {
301                    // Go until the first node with a value
302                    match self.table[next].prefix_value() {
303                        Some(x) => return Some(x),
304                        None => idx = next.get(),
305                    }
306                }
307                Direction::Missing => return None,
308            }
309        }
310    }
311
312    /// Get the shortest prefix in the datastructure that contains the given `prefix`.
313    ///
314    /// ```
315    /// # use prefix_trie::*;
316    /// # #[cfg(feature = "ipnet")]
317    /// # fn main() -> Result<(), Box<dyn std::error::Error>> {
318    /// let mut pm: PrefixMap<ipnet::Ipv4Net, _> = PrefixMap::new();
319    /// pm.insert("192.168.1.1/24".parse()?, 1);
320    /// pm.insert("192.168.0.0/23".parse()?, 2);
321    /// assert_eq!(pm.get_spm_prefix(&"192.168.1.1/32".parse()?), Some(&"192.168.0.0/23".parse()?));
322    /// assert_eq!(pm.get_spm_prefix(&"192.168.1.0/24".parse()?), Some(&"192.168.0.0/23".parse()?));
323    /// assert_eq!(pm.get_spm_prefix(&"192.168.0.0/23".parse()?), Some(&"192.168.0.0/23".parse()?));
324    /// assert_eq!(pm.get_spm_prefix(&"192.168.2.0/24".parse()?), None);
325    /// # Ok(())
326    /// # }
327    /// # #[cfg(not(feature = "ipnet"))]
328    /// # fn main() {}
329    pub fn get_spm_prefix<'a>(&'a self, prefix: &P) -> Option<&'a P> {
330        self.get_spm(prefix).map(|(p, _)| p)
331    }
332
333    /// Insert a new item into the prefix-map. This function may return any value that existed
334    /// before.
335    ///
336    /// ```
337    /// # use prefix_trie::*;
338    /// # #[cfg(feature = "ipnet")]
339    /// # fn main() -> Result<(), Box<dyn std::error::Error>> {
340    /// let mut pm: PrefixMap<ipnet::Ipv4Net, _> = PrefixMap::new();
341    /// assert_eq!(pm.insert("192.168.0.0/23".parse()?, 1), None);
342    /// assert_eq!(pm.insert("192.168.1.0/24".parse()?, 2), None);
343    /// assert_eq!(pm.insert("192.168.1.0/24".parse()?, 3), Some(2));
344    /// # Ok(())
345    /// # }
346    /// # #[cfg(not(feature = "ipnet"))]
347    /// # fn main() {}
348    /// ```
349    ///
350    /// You can store additional information in the host-part of the prefix. This information is
351    /// preserved in the map, and can be accessed with [`Self::get_key_value`]. In case the node
352    /// already exists in the tree, its prefix will be replaced by the provided argument. The
353    /// following example illustrates this:
354    ///
355    /// ```
356    /// # use prefix_trie::*;
357    /// # #[cfg(feature = "ipnet")]
358    /// # fn main() -> Result<(), Box<dyn std::error::Error>> {
359    /// let mut pm: PrefixMap<ipnet::Ipv4Net, _> = PrefixMap::new();
360    ///
361    /// pm.insert("192.168.0.1/24".parse()?, 1);
362    /// assert_eq!(
363    ///     pm.get_key_value(&"192.168.0.0/24".parse()?), // notice that the host part is zero
364    ///     Some((&"192.168.0.1/24".parse()?, &1))
365    /// );
366    ///
367    /// pm.insert("192.168.0.100/24".parse()?, 5);
368    /// assert_eq!(
369    ///     pm.get_key_value(&"192.168.0.0/24".parse()?),
370    ///     Some((&"192.168.0.100/24".parse()?, &5)) // `insert` updates the host part as well.
371    /// );
372    /// # Ok(())
373    /// # }
374    /// # #[cfg(not(feature = "ipnet"))]
375    /// # fn main() {}
376    /// ```
377    pub fn insert(&mut self, prefix: P, value: T) -> Option<T> {
378        let mut idx = 0;
379        loop {
380            match self.table.get_direction_for_insert(idx, &prefix) {
381                DirectionForInsert::Enter { next, .. } => idx = next,
382                DirectionForInsert::Reached => {
383                    let mut inc = 0;
384                    let node = &mut self.table[idx];
385                    // replace the prefix
386                    node.prefix = prefix;
387                    let old_value = node.value.take();
388                    if old_value.is_none() {
389                        inc = 1;
390                    }
391                    node.value = Some(value);
392                    self.count += inc;
393                    return old_value;
394                }
395                DirectionForInsert::NewLeaf { right } => {
396                    let new = self.new_node(prefix, Some(value));
397                    self.table.set_child(idx, new, right);
398                    return None;
399                }
400                DirectionForInsert::NewChild { right, child_right } => {
401                    let new = self.new_node(prefix, Some(value));
402                    let child = self.table.set_child(idx, new, right).unwrap();
403                    self.table.set_child(new, child, child_right);
404                    return None;
405                }
406                DirectionForInsert::NewBranch {
407                    branch_prefix,
408                    right,
409                    prefix_right,
410                } => {
411                    let branch = self.new_node(branch_prefix, None);
412                    let new = self.new_node(prefix, Some(value));
413                    let child = self.table.set_child(idx, branch, right).unwrap();
414                    self.table.set_child(branch, new, prefix_right);
415                    self.table.set_child(branch, child, !prefix_right);
416                    return None;
417                }
418            }
419        }
420    }
421
422    /// Gets the given key’s corresponding entry in the map for in-place manipulation. In case you
423    /// eventually insert an element into the map, this operation will also replace the prefix in
424    /// the node with the existing one. That is if you store additional information in the host part
425    /// of the address (the one that is masked out). See the documentation of the individual
426    /// functions of [`Entry`], [`OccupiedEntry`], and [`VacantEntry`].
427    ///
428    /// ```
429    /// # use prefix_trie::*;
430    /// # #[cfg(feature = "ipnet")]
431    /// # fn main() -> Result<(), Box<dyn std::error::Error>> {
432    /// let mut pm: PrefixMap<ipnet::Ipv4Net, _> = PrefixMap::new();
433    /// pm.insert("192.168.0.0/23".parse()?, vec![1]);
434    /// pm.entry("192.168.0.0/23".parse()?).or_default().push(2);
435    /// pm.entry("192.168.0.0/24".parse()?).or_default().push(3);
436    /// assert_eq!(pm.get(&"192.168.0.0/23".parse()?), Some(&vec![1, 2]));
437    /// assert_eq!(pm.get(&"192.168.0.0/24".parse()?), Some(&vec![3]));
438    /// # Ok(())
439    /// # }
440    /// # #[cfg(not(feature = "ipnet"))]
441    /// # fn main() {}
442    /// ```
443    pub fn entry(&mut self, prefix: P) -> Entry<'_, P, T> {
444        let mut idx = 0;
445        loop {
446            match self.table.get_direction_for_insert(idx, &prefix) {
447                DirectionForInsert::Enter { next, .. } => idx = next,
448                DirectionForInsert::Reached if self.table[idx].value.is_some() => {
449                    return Entry::Occupied(OccupiedEntry {
450                        node: &mut self.table[idx],
451                        prefix,
452                    });
453                }
454                direction => {
455                    return Entry::Vacant(VacantEntry {
456                        map: self,
457                        prefix,
458                        idx,
459                        direction,
460                    });
461                }
462            }
463        }
464    }
465
466    /// Removes a key from the map, returning the value at the key if the key was previously in the
467    /// map. In contrast to [`Self::remove_keep_tree`], this operation will modify the tree
468    /// structure. As a result, this operation takes longer than `remove_keep_tree`, as does
469    /// inserting the same element again. However, future reads may be faster as less nodes need to
470    /// be traversed. Further, it reduces the memory footprint to its minimum.
471    ///
472    /// ```
473    /// # use prefix_trie::*;
474    /// # #[cfg(feature = "ipnet")]
475    /// # fn main() -> Result<(), Box<dyn std::error::Error>> {
476    /// let mut pm: PrefixMap<ipnet::Ipv4Net, _> = PrefixMap::new();
477    /// let prefix = "192.168.1.0/24".parse()?;
478    /// pm.insert(prefix, 1);
479    /// assert_eq!(pm.get(&prefix), Some(&1));
480    /// assert_eq!(pm.remove(&prefix), Some(1));
481    /// assert_eq!(pm.get(&prefix), None);
482    /// # Ok(())
483    /// # }
484    /// # #[cfg(not(feature = "ipnet"))]
485    /// # fn main() {}
486    /// ```
487    pub fn remove(&mut self, prefix: &P) -> Option<T> {
488        let mut idx = 0;
489        let mut grandparent = None;
490        let mut grandparent_right = false;
491        let mut parent = None;
492        let mut parent_right = false;
493        // first, search for the element
494        loop {
495            match self.table.get_direction(idx, prefix) {
496                Direction::Reached => break,
497                Direction::Enter { next, right } => {
498                    grandparent_right = parent_right;
499                    parent_right = right;
500                    grandparent = parent;
501                    parent = Some(idx);
502                    idx = next.get();
503                }
504                Direction::Missing => return None,
505            }
506        }
507        self._remove_node(idx, parent, parent_right, grandparent, grandparent_right)
508            .0
509    }
510
511    /// Removes a key from the map, returning the value at the key if the key was previously in the
512    /// map. In contrast to [`Self::remove`], his operation will keep the tree structure as is, but
513    /// only remove the element from it. This allows any future `insert` on the same prefix to be
514    /// faster. However future reads from the tree might be a bit slower because they need to
515    /// traverse more nodes.
516    ///
517    /// ```
518    /// # use prefix_trie::*;
519    /// # #[cfg(feature = "ipnet")]
520    /// # fn main() -> Result<(), Box<dyn std::error::Error>> {
521    /// let mut pm: PrefixMap<ipnet::Ipv4Net, _> = PrefixMap::new();
522    /// let prefix = "192.168.1.0/24".parse()?;
523    /// pm.insert(prefix, 1);
524    /// assert_eq!(pm.get(&prefix), Some(&1));
525    /// assert_eq!(pm.remove_keep_tree(&prefix), Some(1));
526    /// assert_eq!(pm.get(&prefix), None);
527    ///
528    /// // future inserts of the same key are now faster!
529    /// pm.insert(prefix, 1);
530    /// # Ok(())
531    /// # }
532    /// # #[cfg(not(feature = "ipnet"))]
533    /// # fn main() {}
534    /// ```
535    pub fn remove_keep_tree(&mut self, prefix: &P) -> Option<T> {
536        let mut idx = 0;
537        let value = loop {
538            match self.table.get_direction(idx, prefix) {
539                Direction::Reached => break self.table[idx].value.take(),
540                Direction::Enter { next, .. } => idx = next.get(),
541                Direction::Missing => break None,
542            }
543        };
544
545        // decrease the count if the value is something
546        if value.is_some() {
547            self.count -= 1;
548        }
549
550        value
551    }
552
553    /// Remove all entries that are contained within `prefix`. This will change the tree
554    /// structure. This operation is `O(n)`, as the entries must be freed up one-by-one.
555    ///
556    /// ```
557    /// # use prefix_trie::*;
558    /// # #[cfg(feature = "ipnet")]
559    /// # fn main() -> Result<(), Box<dyn std::error::Error>> {
560    /// let mut pm: PrefixMap<ipnet::Ipv4Net, _> = PrefixMap::new();
561    /// pm.insert("192.168.0.0/22".parse()?, 1);
562    /// pm.insert("192.168.0.0/23".parse()?, 2);
563    /// pm.insert("192.168.0.0/24".parse()?, 3);
564    /// pm.insert("192.168.2.0/23".parse()?, 4);
565    /// pm.insert("192.168.2.0/24".parse()?, 5);
566    /// pm.remove_children(&"192.168.0.0/23".parse()?);
567    /// assert_eq!(pm.get(&"192.168.0.0/23".parse()?), None);
568    /// assert_eq!(pm.get(&"192.168.0.0/24".parse()?), None);
569    /// assert_eq!(pm.get(&"192.168.2.0/23".parse()?), Some(&4));
570    /// assert_eq!(pm.get(&"192.168.2.0/24".parse()?), Some(&5));
571    /// # Ok(())
572    /// # }
573    /// # #[cfg(not(feature = "ipnet"))]
574    /// # fn main() {}
575    /// ```
576    pub fn remove_children(&mut self, prefix: &P) {
577        if prefix.prefix_len() == 0 {
578            return self.clear();
579        }
580        let mut parent_right = false;
581        let mut parent = 0;
582        let mut idx = 0;
583        loop {
584            match self.table.get_direction_for_insert(idx, prefix) {
585                DirectionForInsert::Reached => {
586                    return self._do_remove_children(parent, parent_right);
587                }
588                DirectionForInsert::Enter { next, right } => {
589                    parent_right = right;
590                    parent = idx;
591                    idx = next
592                }
593                DirectionForInsert::NewLeaf { .. } | DirectionForInsert::NewBranch { .. } => return,
594                DirectionForInsert::NewChild { right, .. } => {
595                    return self._do_remove_children(idx, right);
596                }
597            }
598        }
599    }
600
601    /// Clear the map but keep the allocated memory.
602    ///
603    /// ```
604    /// # use prefix_trie::*;
605    /// # #[cfg(feature = "ipnet")]
606    /// # fn main() -> Result<(), Box<dyn std::error::Error>> {
607    /// let mut pm: PrefixMap<ipnet::Ipv4Net, _> = PrefixMap::new();
608    /// pm.insert("192.168.0.0/24".parse()?, 1);
609    /// pm.insert("192.168.1.0/24".parse()?, 2);
610    /// pm.clear();
611    /// assert_eq!(pm.get(&"192.168.0.0/24".parse()?), None);
612    /// assert_eq!(pm.get(&"192.168.1.0/24".parse()?), None);
613    /// # Ok(())
614    /// # }
615    /// # #[cfg(not(feature = "ipnet"))]
616    /// # fn main() {}
617    /// ```
618    pub fn clear(&mut self) {
619        self.table.as_mut().clear();
620        self.free.clear();
621        self.table.as_mut().push(Node {
622            prefix: P::zero(),
623            value: None,
624            left: None,
625            right: None,
626        });
627        self.count = 0;
628    }
629
630    /// Keep only the elements in the map that satisfy the given condition `f`.
631    ///
632    /// ```
633    /// # use prefix_trie::*;
634    /// # #[cfg(feature = "ipnet")]
635    /// # fn main() -> Result<(), Box<dyn std::error::Error>> {
636    /// let mut pm: PrefixMap<ipnet::Ipv4Net, _> = PrefixMap::new();
637    /// pm.insert("192.168.0.0/24".parse()?, 1);
638    /// pm.insert("192.168.1.0/24".parse()?, 2);
639    /// pm.insert("192.168.2.0/24".parse()?, 3);
640    /// pm.insert("192.168.2.0/25".parse()?, 4);
641    /// pm.retain(|_, t| *t % 2 == 0);
642    /// assert_eq!(pm.get(&"192.168.0.0/24".parse()?), None);
643    /// assert_eq!(pm.get(&"192.168.1.0/24".parse()?), Some(&2));
644    /// assert_eq!(pm.get(&"192.168.2.0/24".parse()?), None);
645    /// assert_eq!(pm.get(&"192.168.2.0/25".parse()?), Some(&4));
646    /// # Ok(())
647    /// # }
648    /// # #[cfg(not(feature = "ipnet"))]
649    /// # fn main() {}
650    /// ```
651    pub fn retain<F>(&mut self, f: F)
652    where
653        F: FnMut(&P, &T) -> bool,
654    {
655        self._retain(0, None, false, None, false, f);
656    }
657
658    /// Iterate over all entries in the map that covers the given `prefix` (including `prefix`
659    /// itself if that is present in the map). The returned iterator yields `(&'a P, &'a T)`.
660    ///
661    /// The iterator will always yield elements ordered by their prefix length, i.e., their depth in
662    /// the tree.
663    ///
664    /// ```
665    /// # use prefix_trie::*;
666    /// # #[cfg(feature = "ipnet")]
667    /// # fn main() -> Result<(), Box<dyn std::error::Error>> {
668    /// let mut pm: PrefixMap<ipnet::Ipv4Net, _> = PrefixMap::new();
669    /// let p0 = "10.0.0.0/8".parse()?;
670    /// let p1 = "10.1.0.0/16".parse()?;
671    /// let p2 = "10.1.1.0/24".parse()?;
672    /// pm.insert(p0, 0);
673    /// pm.insert(p1, 1);
674    /// pm.insert(p2, 2);
675    /// pm.insert("10.1.2.0/24".parse()?, 3); // disjoint prefixes are not covered
676    /// pm.insert("10.1.1.0/25".parse()?, 4); // more specific prefixes are not covered
677    /// pm.insert("11.0.0.0/8".parse()?, 5);  // Branch points that don't contain values are skipped
678    /// assert_eq!(
679    ///     pm.cover(&p2).collect::<Vec<_>>(),
680    ///     vec![(&p0, &0), (&p1, &1), (&p2, &2)]
681    /// );
682    /// # Ok(())
683    /// # }
684    /// # #[cfg(not(feature = "ipnet"))]
685    /// # fn main() {}
686    /// ```
687    ///
688    /// This function also yields the root note *if* it is part of the map:
689    ///
690    /// ```
691    /// # use prefix_trie::*;
692    /// # #[cfg(feature = "ipnet")]
693    /// # fn main() -> Result<(), Box<dyn std::error::Error>> {
694    /// let mut pm: PrefixMap<ipnet::Ipv4Net, _> = PrefixMap::new();
695    /// let root = "0.0.0.0/0".parse()?;
696    /// pm.insert(root, 0);
697    /// assert_eq!(pm.cover(&"10.0.0.0/8".parse()?).collect::<Vec<_>>(), vec![(&root, &0)]);
698    /// # Ok(())
699    /// # }
700    /// # #[cfg(not(feature = "ipnet"))]
701    /// # fn main() {}
702    /// ```
703    pub fn cover<'a, 'p>(&'a self, prefix: &'p P) -> Cover<'a, 'p, P, T> {
704        Cover {
705            table: &self.table,
706            idx: None,
707            prefix,
708        }
709    }
710
711    /// Iterate over all keys (prefixes) in the map that covers the given `prefix` (including
712    /// `prefix` itself if that is present in the map). The returned iterator yields `&'a P`.
713    ///
714    /// The iterator will always yield elements ordered by their prefix length, i.e., their depth in
715    /// the tree.
716    ///
717    /// ```
718    /// # use prefix_trie::*;
719    /// # #[cfg(feature = "ipnet")]
720    /// # fn main() -> Result<(), Box<dyn std::error::Error>> {
721    /// let mut pm: PrefixMap<ipnet::Ipv4Net, _> = PrefixMap::new();
722    /// let p0 = "10.0.0.0/8".parse()?;
723    /// let p1 = "10.1.0.0/16".parse()?;
724    /// let p2 = "10.1.1.0/24".parse()?;
725    /// pm.insert(p0, 0);
726    /// pm.insert(p1, 1);
727    /// pm.insert(p2, 2);
728    /// pm.insert("10.1.2.0/24".parse()?, 3); // disjoint prefixes are not covered
729    /// pm.insert("10.1.1.0/25".parse()?, 4); // more specific prefixes are not covered
730    /// pm.insert("11.0.0.0/8".parse()?, 5);  // Branch points that don't contain values are skipped
731    /// assert_eq!(pm.cover_keys(&p2).collect::<Vec<_>>(), vec![&p0, &p1, &p2]);
732    /// # Ok(())
733    /// # }
734    /// # #[cfg(not(feature = "ipnet"))]
735    /// # fn main() {}
736    /// ```
737    pub fn cover_keys<'a, 'p>(&'a self, prefix: &'p P) -> CoverKeys<'a, 'p, P, T> {
738        CoverKeys(Cover {
739            table: &self.table,
740            idx: None,
741            prefix,
742        })
743    }
744
745    /// Iterate over all values in the map that covers the given `prefix` (including `prefix`
746    /// itself if that is present in the map). The returned iterator yields `&'a T`.
747    ///
748    /// The iterator will always yield elements ordered by their prefix length, i.e., their depth in
749    /// the tree.
750    ///
751    /// ```
752    /// # use prefix_trie::*;
753    /// # #[cfg(feature = "ipnet")]
754    /// # fn main() -> Result<(), Box<dyn std::error::Error>> {
755    /// let mut pm: PrefixMap<ipnet::Ipv4Net, _> = PrefixMap::new();
756    /// let p0 = "10.0.0.0/8".parse()?;
757    /// let p1 = "10.1.0.0/16".parse()?;
758    /// let p2 = "10.1.1.0/24".parse()?;
759    /// pm.insert(p0, 0);
760    /// pm.insert(p1, 1);
761    /// pm.insert(p2, 2);
762    /// pm.insert("10.1.2.0/24".parse()?, 3); // disjoint prefixes are not covered
763    /// pm.insert("10.1.1.0/25".parse()?, 4); // more specific prefixes are not covered
764    /// pm.insert("11.0.0.0/8".parse()?, 5);  // Branch points that don't contain values are skipped
765    /// assert_eq!(pm.cover_values(&p2).collect::<Vec<_>>(), vec![&0, &1, &2]);
766    /// # Ok(())
767    /// # }
768    /// # #[cfg(not(feature = "ipnet"))]
769    /// # fn main() {}
770    /// ```
771    pub fn cover_values<'a, 'p>(&'a self, prefix: &'p P) -> CoverValues<'a, 'p, P, T> {
772        CoverValues(Cover {
773            table: &self.table,
774            idx: None,
775            prefix,
776        })
777    }
778}
779
780impl<P, T> PrefixMap<P, T> {
781    /// An iterator visiting all key-value pairs in lexicographic order. The iterator element type
782    /// is `(&P, &T)`.
783    ///
784    /// ```
785    /// # use prefix_trie::*;
786    /// # #[cfg(feature = "ipnet")]
787    /// # fn main() -> Result<(), Box<dyn std::error::Error>> {
788    /// let mut pm: PrefixMap<ipnet::Ipv4Net, _> = PrefixMap::new();
789    /// pm.insert("192.168.0.0/22".parse()?, 1);
790    /// pm.insert("192.168.0.0/23".parse()?, 2);
791    /// pm.insert("192.168.2.0/23".parse()?, 3);
792    /// pm.insert("192.168.0.0/24".parse()?, 4);
793    /// pm.insert("192.168.2.0/24".parse()?, 5);
794    /// assert_eq!(
795    ///     pm.iter().collect::<Vec<_>>(),
796    ///     vec![
797    ///         (&"192.168.0.0/22".parse()?, &1),
798    ///         (&"192.168.0.0/23".parse()?, &2),
799    ///         (&"192.168.0.0/24".parse()?, &4),
800    ///         (&"192.168.2.0/23".parse()?, &3),
801    ///         (&"192.168.2.0/24".parse()?, &5),
802    ///     ]
803    /// );
804    /// # Ok(())
805    /// # }
806    /// # #[cfg(not(feature = "ipnet"))]
807    /// # fn main() {}
808    /// ```
809    #[inline(always)]
810    pub fn iter(&self) -> Iter<'_, P, T> {
811        self.into_iter()
812    }
813
814    /// Get a mutable iterator over all key-value pairs. The order of this iterator is lexicographic.
815    pub fn iter_mut(&mut self) -> IterMut<'_, P, T> {
816        // Safety: We get the pointer to the table by and construct the `IterMut`. Its lifetime is
817        // now tied to the mutable borrow of `self`, so we are allowed to access elements of that
818        // table mutably.
819        unsafe { IterMut::new(&self.table, vec![0]) }
820    }
821
822    /// An iterator visiting all keys in lexicographic order. The iterator element type is `&P`.
823    ///
824    /// ```
825    /// # use prefix_trie::*;
826    /// # #[cfg(feature = "ipnet")]
827    /// # fn main() -> Result<(), Box<dyn std::error::Error>> {
828    /// let mut pm: PrefixMap<ipnet::Ipv4Net, _> = PrefixMap::new();
829    /// pm.insert("192.168.0.0/22".parse()?, 1);
830    /// pm.insert("192.168.0.0/23".parse()?, 2);
831    /// pm.insert("192.168.2.0/23".parse()?, 3);
832    /// pm.insert("192.168.0.0/24".parse()?, 4);
833    /// pm.insert("192.168.2.0/24".parse()?, 5);
834    /// assert_eq!(
835    ///     pm.keys().collect::<Vec<_>>(),
836    ///     vec![
837    ///         &"192.168.0.0/22".parse()?,
838    ///         &"192.168.0.0/23".parse()?,
839    ///         &"192.168.0.0/24".parse()?,
840    ///         &"192.168.2.0/23".parse()?,
841    ///         &"192.168.2.0/24".parse()?,
842    ///     ]
843    /// );
844    /// # Ok(())
845    /// # }
846    /// # #[cfg(not(feature = "ipnet"))]
847    /// # fn main() {}
848    /// ```
849    #[inline(always)]
850    pub fn keys(&self) -> Keys<'_, P, T> {
851        Keys { inner: self.iter() }
852    }
853
854    /// Creates a consuming iterator visiting all keys in lexicographic order. The iterator element
855    /// type is `P`.
856    #[inline(always)]
857    pub fn into_keys(self) -> IntoKeys<P, T> {
858        IntoKeys {
859            inner: IntoIter {
860                table: self.table.into_inner(),
861                nodes: vec![0],
862            },
863        }
864    }
865
866    /// An iterator visiting all values in lexicographic order. The iterator element type is `&P`.
867    ///
868    /// ```
869    /// # use prefix_trie::*;
870    /// # #[cfg(feature = "ipnet")]
871    /// # fn main() -> Result<(), Box<dyn std::error::Error>> {
872    /// let mut pm: PrefixMap<ipnet::Ipv4Net, _> = PrefixMap::new();
873    /// pm.insert("192.168.0.0/22".parse()?, 1);
874    /// pm.insert("192.168.0.0/23".parse()?, 2);
875    /// pm.insert("192.168.2.0/23".parse()?, 3);
876    /// pm.insert("192.168.0.0/24".parse()?, 4);
877    /// pm.insert("192.168.2.0/24".parse()?, 5);
878    /// assert_eq!(pm.values().collect::<Vec<_>>(), vec![&1, &2, &4, &3, &5]);
879    /// # Ok(())
880    /// # }
881    /// # #[cfg(not(feature = "ipnet"))]
882    /// # fn main() {}
883    /// ```
884    #[inline(always)]
885    pub fn values(&self) -> Values<'_, P, T> {
886        Values { inner: self.iter() }
887    }
888
889    /// Creates a consuming iterator visiting all values in lexicographic order. The iterator
890    /// element type is `P`.
891    #[inline(always)]
892    pub fn into_values(self) -> IntoValues<P, T> {
893        IntoValues {
894            inner: IntoIter {
895                table: self.table.into_inner(),
896                nodes: vec![0],
897            },
898        }
899    }
900
901    /// Get a mutable iterator over all values. The order of this iterator is lexicographic.
902    pub fn values_mut(&mut self) -> ValuesMut<'_, P, T> {
903        ValuesMut {
904            inner: self.iter_mut(),
905        }
906    }
907}
908
909impl<P, T> PrefixMap<P, T>
910where
911    P: Prefix,
912{
913    /// Get an iterator over the node itself and all children. All elements returned have a prefix
914    /// that is contained within `prefix` itself (or are the same). The iterator yields references
915    /// to both keys and values, i.e., type `(&'a P, &'a T)`. The iterator yields elements in
916    /// lexicographic order.
917    ///
918    /// **Note**: Consider using [`crate::AsView::view_at`] as an alternative.
919    ///
920    /// ```
921    /// # use prefix_trie::*;
922    /// # #[cfg(feature = "ipnet")]
923    /// # fn main() -> Result<(), Box<dyn std::error::Error>> {
924    /// let mut pm: PrefixMap<ipnet::Ipv4Net, _> = PrefixMap::new();
925    /// pm.insert("192.168.0.0/22".parse()?, 1);
926    /// pm.insert("192.168.0.0/23".parse()?, 2);
927    /// pm.insert("192.168.2.0/23".parse()?, 3);
928    /// pm.insert("192.168.0.0/24".parse()?, 4);
929    /// pm.insert("192.168.2.0/24".parse()?, 5);
930    /// assert_eq!(
931    ///     pm.children(&"192.168.0.0/23".parse()?).collect::<Vec<_>>(),
932    ///     vec![
933    ///         (&"192.168.0.0/23".parse()?, &2),
934    ///         (&"192.168.0.0/24".parse()?, &4),
935    ///     ]
936    /// );
937    /// # Ok(())
938    /// # }
939    /// # #[cfg(not(feature = "ipnet"))]
940    /// # fn main() {}
941    /// ```
942    pub fn children<'a>(&'a self, prefix: &P) -> Iter<'a, P, T> {
943        let nodes = iter::lpm_children_iter_start(&self.table, prefix);
944        Iter {
945            table: Some(&self.table),
946            nodes,
947        }
948    }
949
950    /// Get an iterator of mutable references of the node itself and all its children. All elements
951    /// returned have a prefix that is contained within `prefix` itself (or are the same). The
952    /// iterator yields references to the keys, and mutable references to the values, i.e., type
953    /// `(&'a P, &'a mut T)`. The iterator yields elements in lexicographic order.
954    ///
955    /// **Note**: Consider using [`crate::AsViewMut::view_mut_at`] as an alternative.
956    ///
957    /// ```
958    /// # use prefix_trie::*;
959    /// # #[cfg(feature = "ipnet")]
960    /// # fn main() -> Result<(), Box<dyn std::error::Error>> {
961    /// let mut pm: PrefixMap<ipnet::Ipv4Net, _> = PrefixMap::new();
962    /// pm.insert("192.168.0.0/22".parse()?, 1);
963    /// pm.insert("192.168.0.0/23".parse()?, 2);
964    /// pm.insert("192.168.0.0/24".parse()?, 3);
965    /// pm.insert("192.168.2.0/23".parse()?, 4);
966    /// pm.insert("192.168.2.0/24".parse()?, 5);
967    /// pm.children_mut(&"192.168.0.0/23".parse()?).for_each(|(_, x)| *x *= 10);
968    /// assert_eq!(
969    ///     pm.into_iter().collect::<Vec<_>>(),
970    ///     vec![
971    ///         ("192.168.0.0/22".parse()?, 1),
972    ///         ("192.168.0.0/23".parse()?, 20),
973    ///         ("192.168.0.0/24".parse()?, 30),
974    ///         ("192.168.2.0/23".parse()?, 4),
975    ///         ("192.168.2.0/24".parse()?, 5),
976    ///     ]
977    /// );
978    /// # Ok(())
979    /// # }
980    /// # #[cfg(not(feature = "ipnet"))]
981    /// # fn main() {}
982    /// ```
983    pub fn children_mut<'a>(&'a mut self, prefix: &P) -> IterMut<'a, P, T> {
984        let nodes = lpm_children_iter_start(&self.table, prefix);
985        IterMut {
986            table: Some(&self.table),
987            nodes,
988        }
989    }
990
991    /// Get an iterator over the node itself and all children with a value. All elements returned
992    /// have a prefix that is contained within `prefix` itself (or are the same). This function will
993    /// consume `self`, returning an iterator over all owned children.
994    ///
995    /// ```
996    /// # use prefix_trie::*;
997    /// # #[cfg(feature = "ipnet")]
998    /// # fn main() -> Result<(), Box<dyn std::error::Error>> {
999    /// let mut pm: PrefixMap<ipnet::Ipv4Net, _> = PrefixMap::new();
1000    /// pm.insert("192.168.0.0/22".parse()?, 1);
1001    /// pm.insert("192.168.0.0/23".parse()?, 2);
1002    /// pm.insert("192.168.2.0/23".parse()?, 3);
1003    /// pm.insert("192.168.0.0/24".parse()?, 4);
1004    /// pm.insert("192.168.2.0/24".parse()?, 5);
1005    /// assert_eq!(
1006    ///     pm.into_children(&"192.168.0.0/23".parse()?).collect::<Vec<_>>(),
1007    ///     vec![
1008    ///         ("192.168.0.0/23".parse()?, 2),
1009    ///         ("192.168.0.0/24".parse()?, 4),
1010    ///     ]
1011    /// );
1012    /// # Ok(())
1013    /// # }
1014    /// # #[cfg(not(feature = "ipnet"))]
1015    /// # fn main() {}
1016    /// ```
1017    pub fn into_children(self, prefix: &P) -> IntoIter<P, T> {
1018        let nodes = lpm_children_iter_start(&self.table, prefix);
1019        IntoIter {
1020            table: self.table.into_inner(),
1021            nodes,
1022        }
1023    }
1024}
1025
1026/// Private function implementations
1027impl<P, T> PrefixMap<P, T>
1028where
1029    P: Prefix,
1030{
1031    /// remove all elements from that point onwards.
1032    fn _do_remove_children(&mut self, idx: usize, right: bool) {
1033        let mut to_free = vec![self.table.get_child(idx, right).unwrap()];
1034        self.table.clear_child(idx, right);
1035        while let Some(idx) = to_free.pop() {
1036            let mut dec = 0;
1037            let node = &mut self.table[idx.get()];
1038            let value = node.value.take();
1039            // decrease the count if `value` is something
1040            if value.is_some() {
1041                dec = 1;
1042            }
1043            if let Some(left) = node.left.take() {
1044                to_free.push(left)
1045            }
1046            if let Some(right) = node.right.take() {
1047                to_free.push(right)
1048            }
1049            self.free.push(idx);
1050            self.count -= dec;
1051        }
1052    }
1053
1054    /// insert a new node into the table and return its index. This function also increments the
1055    /// count by 1, but only if `value` is `Some`.
1056    #[inline(always)]
1057    fn new_node(&mut self, prefix: P, value: Option<T>) -> NonZeroUsize {
1058        if value.is_some() {
1059            self.count += 1;
1060        }
1061        if let Some(idx) = self.free.pop() {
1062            let node = &mut self.table[idx.get()];
1063            node.prefix = prefix;
1064            node.value = value;
1065            node.left = None;
1066            node.right = None;
1067            idx
1068        } else {
1069            let table = self.table.as_mut();
1070            let idx = NonZeroUsize::new(table.len()).expect("Table is never empty.");
1071            table.push(Node {
1072                prefix,
1073                value,
1074                left: None,
1075                right: None,
1076            });
1077            idx
1078        }
1079    }
1080
1081    /// Remove a child from the tree. If the parent was removed, return `true` as a second return parameter
1082    fn _remove_node(
1083        &mut self,
1084        idx: usize,
1085        par: Option<usize>,
1086        par_right: bool,
1087        grp: Option<usize>,
1088        grp_right: bool,
1089    ) -> (Option<T>, bool) {
1090        // if we reach this point, then `idx` is the element to remove, `parent` is its parent,
1091        // and `parent_right` stores the direction of `idx` at `parent`.
1092        let node = &mut self.table[idx];
1093        let value = node.value.take();
1094        let has_left = node.left.is_some();
1095        let has_right = node.right.is_some();
1096
1097        // decrease the number of elements if value is something
1098        if value.is_some() {
1099            self.count -= 1;
1100        }
1101
1102        if has_left && has_right {
1103            // if the node has both left and right set, then it must remain in the tree.
1104        } else if !(has_left || has_right) {
1105            if let Some(par) = par {
1106                let idx = NonZeroUsize::new(idx).expect("Parent is set, so must be non-root");
1107                // if the node is a leaf, simply remove it.
1108                self.table.clear_child(par, par_right);
1109                self.free.push(idx);
1110                // now, if the parent has no value, also remove the parent and replace it with the
1111                // current node. but only do that if the grandparent is something.
1112                if let Some(grp) = grp {
1113                    if self.table[par].value.is_none() {
1114                        let par_idx = NonZeroUsize::new(par)
1115                            .expect("Grandparent is set, so parent must be non-root");
1116                        if let Some(sibling) = self.table.get_child(par, !par_right) {
1117                            self.table.set_child(grp, sibling, grp_right);
1118                            self.free.push(par_idx);
1119                            return (value, true);
1120                        } else {
1121                            self.table.clear_child(grp, grp_right);
1122                            self.free.push(par_idx);
1123                        }
1124                    }
1125                }
1126            }
1127        } else {
1128            // one child remains. simply connect that child directly to the parent if the parent is Something.
1129            if let Some(par) = par {
1130                let idx = NonZeroUsize::new(idx).expect("Parent is set, so must be non-root");
1131                let child_right = has_right;
1132                let child = self.table.clear_child(idx, child_right).unwrap();
1133                self.table.set_child(par, child, par_right);
1134                self.free.push(idx);
1135            }
1136        }
1137        (value, false)
1138    }
1139
1140    /// recursive retain implementation
1141    pub(crate) fn _retain<F>(
1142        &mut self,
1143        idx: usize,
1144        par: Option<usize>,
1145        par_right: bool,
1146        grp: Option<usize>,
1147        grp_right: bool,
1148        mut f: F,
1149    ) -> (F, bool)
1150    where
1151        F: FnMut(&P, &T) -> bool,
1152    {
1153        // first, do the recursion
1154        let mut idx_removed = false;
1155        let mut par_removed = false;
1156        if let Some(left) = self.table[idx].left {
1157            (f, idx_removed) = self._retain(left.get(), Some(idx), false, par, par_right, f);
1158        }
1159        if let Some(right) = self.table[idx].right {
1160            if idx_removed {
1161                (f, par_removed) = self._retain(right.get(), par, par_right, grp, grp_right, f);
1162            } else {
1163                (f, _) = self._retain(right.get(), Some(idx), true, par, par_right, f);
1164            }
1165        }
1166        // then, check if we need to delete the node
1167        if let Some(val) = self.table[idx].value.as_ref() {
1168            if !f(&self.table[idx].prefix, val) {
1169                // deletion is necessary.
1170                let (_, par_del) = self._remove_node(idx, par, par_right, grp, grp_right);
1171                par_removed = par_del;
1172            }
1173        }
1174        (f, par_removed)
1175    }
1176}
1177
1178impl<P, L, Rhs> PartialEq<Rhs> for PrefixMap<P, L>
1179where
1180    P: Prefix + PartialEq,
1181    L: PartialEq<Rhs::T>,
1182    Rhs: crate::AsView<P = P>,
1183{
1184    fn eq(&self, other: &Rhs) -> bool {
1185        self.iter()
1186            .zip(other.view().iter())
1187            .all(|((lp, lt), (rp, rt))| lt == rt && lp == rp)
1188    }
1189}
1190
1191impl<P, T> Eq for PrefixMap<P, T>
1192where
1193    P: Prefix + Eq,
1194    T: Eq,
1195{
1196}
1197
1198#[cfg(test)]
1199impl<P, T> PrefixMap<P, T> {
1200    /// Check that no memory was leaked in the datastructure.
1201    #[track_caller]
1202    pub(crate) fn assert_no_memory_leak(&self) {
1203        let mut unmarked = std::collections::BTreeSet::from_iter(0..self.table.as_ref().len());
1204        let mut stack = vec![0usize];
1205        while let Some(node) = stack.pop() {
1206            unmarked.remove(&node);
1207            if let Some(left) = self.table.as_ref().get(node).and_then(|x| x.left) {
1208                stack.push(left.into());
1209            }
1210            if let Some(right) = self.table.as_ref().get(node).and_then(|x| x.right) {
1211                stack.push(right.into());
1212            }
1213        }
1214        for node in self.free.iter() {
1215            let node: usize = (*node).into();
1216            unmarked.remove(&node);
1217        }
1218        assert!(unmarked.is_empty(), "Memory leak detected!");
1219    }
1220}