1use crate::{bimap::BiHashMap, timeout::MaybeTimeout};
2use rustc_hash::FxHashMap;
3use std::{net::Ipv4Addr, time::Duration};
4
5#[derive(Debug)]
7pub struct NetworkAddressTable {
8 addr_map: BiHashMap<u32, u32>,
10 timeouts: FxHashMap<(u32, u32), MaybeTimeout>,
12}
13
14impl NetworkAddressTable {
15 #[must_use]
17 pub fn new() -> Self {
18 Self::default()
19 }
20
21 #[profiling::function]
23 pub fn prune(&mut self) {
24 log::trace!("Pruning old network address mappings");
25
26 let now = std::time::Instant::now();
28
29 self.timeouts.retain(|(left, right), timeout| {
31 match timeout {
32 MaybeTimeout::Never => true,
34 MaybeTimeout::After { duration, start } => {
36 let should_retain = now.duration_since(*start) < *duration;
37 if !should_retain {
38 log::trace!(
39 "Mapping {:?} -> {:?} has timed out and will be removed",
40 left,
41 right
42 );
43 self.addr_map.remove(left, right);
44 }
45 should_retain
46 }
47 }
48 });
49 }
50
51 #[profiling::function]
53 pub fn insert_indefinite(&mut self, left: Ipv4Addr, right: Ipv4Addr) {
54 self.prune();
55 let (left, right) = (left.into(), right.into());
56 self.addr_map.insert(left, right);
57 self.timeouts.insert((left, right), MaybeTimeout::Never);
58 }
59
60 #[profiling::function]
62 pub fn insert(&mut self, left: Ipv4Addr, right: Ipv4Addr, duration: Duration) {
63 self.prune();
64 let (left, right) = (left.into(), right.into());
65 self.addr_map.insert(left, right);
66 self.timeouts.insert(
67 (left, right),
68 MaybeTimeout::After {
69 duration,
70 start: std::time::Instant::now(),
71 },
72 );
73 }
74
75 #[must_use]
77 #[profiling::function]
78 pub fn get_right(&self, left: &Ipv4Addr) -> Option<Ipv4Addr> {
79 self.addr_map
80 .get_right(&(*left).into())
81 .map(|addr| (*addr).into())
82 }
83
84 #[must_use]
86 #[profiling::function]
87 pub fn get_left(&self, right: &Ipv4Addr) -> Option<Ipv4Addr> {
88 self.addr_map
89 .get_left(&(*right).into())
90 .map(|addr| (*addr).into())
91 }
92}
93
94impl Default for NetworkAddressTable {
95 fn default() -> Self {
96 Self {
97 addr_map: BiHashMap::new(),
98 timeouts: FxHashMap::default(),
99 }
100 }
101}