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