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}