ts_bart/table/
split_stack.rs1use core::net::IpAddr;
2
3use crate::{RouteModification, RoutingTable, iptrie, node, table};
4
5#[derive(Debug, Copy, Clone, Default, PartialEq, Eq, Hash)]
11pub struct SplitStackTable<Node> {
12 table4: table::SimpleTable<Node>,
13 table6: table::SimpleTable<Node>,
14}
15
16impl<T, C> SplitStackTable<crate::Node<T, C>>
17where
18 C: ?Sized + crate::Storage,
19{
20 pub const EMPTY: Self = Self {
22 table4: table::SimpleTable::EMPTY,
23 table6: table::SimpleTable::EMPTY,
24 };
25}
26
27impl<Node> SplitStackTable<Node>
28where
29 Node: node::StrideOps,
30{
31 #[inline]
33 pub fn size4(&self) -> usize {
34 self.table4.size()
35 }
36
37 #[inline]
39 pub fn size6(&self) -> usize {
40 self.table6.size()
41 }
42
43 #[inline]
45 pub const fn root(&self, ipv4: bool) -> &Node {
46 if ipv4 {
47 self.table4.root()
48 } else {
49 self.table6.root()
50 }
51 }
52
53 #[inline]
54 const fn stack_table(&self, ipv4: bool) -> &table::SimpleTable<Node> {
55 if ipv4 { &self.table4 } else { &self.table6 }
56 }
57
58 #[inline]
59 const fn stack_table_mut(&mut self, ipv4: bool) -> &mut table::SimpleTable<Node> {
60 if ipv4 {
61 &mut self.table4
62 } else {
63 &mut self.table6
64 }
65 }
66}
67
68impl<Node> RoutingTable for SplitStackTable<Node>
69where
70 Node: node::StrideOps,
71{
72 type Value = Node::T;
73
74 #[inline]
75 fn contains(&self, ip: IpAddr) -> bool {
76 self.stack_table(ip.is_ipv4()).contains(ip)
77 }
78
79 #[inline]
80 fn insert(&mut self, prefix: ipnet::IpNet, val: Node::T) -> Option<Node::T> {
81 self.stack_table_mut(prefix.addr().is_ipv4())
82 .insert(prefix, val)
83 }
84
85 #[inline]
86 fn remove(&mut self, prefix: ipnet::IpNet) -> Option<Node::T> {
87 self.stack_table_mut(prefix.addr().is_ipv4()).remove(prefix)
88 }
89
90 #[inline]
91 fn modify_impl(
92 &mut self,
93 prefix: ipnet::IpNet,
94 modify: &mut dyn FnMut(Option<&mut Node::T>) -> RouteModification<Node::T>,
95 ) -> Option<Node::T> {
96 self.stack_table_mut(prefix.addr().is_ipv4())
97 .modify_impl(prefix, modify)
98 }
99
100 #[inline]
101 fn clear(&mut self) {
102 self.table4.clear();
103 self.table6.clear();
104 }
105
106 #[inline]
107 fn lookup(&self, ip: IpAddr) -> Option<&Node::T> {
108 self.stack_table(ip.is_ipv4()).lookup(ip)
109 }
110
111 fn lookup_all(&self, ip: IpAddr) -> iptrie::LookupIter<'_, Self::Value> {
112 self.stack_table(ip.is_ipv4()).lookup_all(ip)
113 }
114
115 #[inline]
116 fn lookup_prefix_exact(&self, prefix: ipnet::IpNet) -> Option<&Node::T> {
117 self.stack_table(prefix.addr().is_ipv4())
118 .lookup_prefix_exact(prefix)
119 }
120
121 #[inline]
122 fn lookup_prefix(&self, prefix: ipnet::IpNet) -> Option<&Node::T> {
123 self.stack_table(prefix.addr().is_ipv4())
124 .lookup_prefix(prefix)
125 }
126
127 #[inline]
128 fn lookup_prefix_lpm(&self, prefix: ipnet::IpNet) -> Option<(ipnet::IpNet, &Node::T)> {
129 self.stack_table(prefix.addr().is_ipv4())
130 .lookup_prefix_lpm(prefix)
131 }
132
133 #[inline]
134 fn size(&self) -> usize {
135 self.table4.size() + self.table6.size()
136 }
137}