lifetime cleanup

This commit is contained in:
John Smith 2022-11-02 16:29:29 -04:00
parent 92b22d5af5
commit 941cf9309e
2 changed files with 97 additions and 87 deletions

View File

@ -34,8 +34,8 @@ pub struct LowLevelPortInfo {
pub low_level_protocol_ports: LowLevelProtocolPorts, pub low_level_protocol_ports: LowLevelProtocolPorts,
pub protocol_to_port: ProtocolToPortMapping, pub protocol_to_port: ProtocolToPortMapping,
} }
pub type RoutingTableEntryFilter = pub type RoutingTableEntryFilter<'t> =
Box<dyn for<'r> FnMut(&'r RoutingTableInner, DHTKey, Option<Arc<BucketEntry>>) -> bool + Send>; Box<dyn FnMut(&RoutingTableInner, DHTKey, Option<Arc<BucketEntry>>) -> bool + Send + 't>;
#[derive(Clone, Debug, Default)] #[derive(Clone, Debug, Default)]
pub struct RoutingTableHealth { pub struct RoutingTableHealth {
@ -550,7 +550,7 @@ impl RoutingTable {
pub fn make_inbound_dial_info_entry_filter<'a>( pub fn make_inbound_dial_info_entry_filter<'a>(
routing_domain: RoutingDomain, routing_domain: RoutingDomain,
dial_info_filter: DialInfoFilter, dial_info_filter: DialInfoFilter,
) -> RoutingTableEntryFilter { ) -> RoutingTableEntryFilter<'a> {
// does it have matching public dial info? // does it have matching public dial info?
Box::new(move |rti, _k, e| { Box::new(move |rti, _k, e| {
if let Some(e) = e { if let Some(e) = e {
@ -575,10 +575,10 @@ impl RoutingTable {
} }
/// Makes a filter that finds nodes capable of dialing a particular outbound dialinfo /// Makes a filter that finds nodes capable of dialing a particular outbound dialinfo
pub fn make_outbound_dial_info_entry_filter( pub fn make_outbound_dial_info_entry_filter<'a>(
routing_domain: RoutingDomain, routing_domain: RoutingDomain,
dial_info: DialInfo, dial_info: DialInfo,
) -> RoutingTableEntryFilter { ) -> RoutingTableEntryFilter<'a> {
// does the node's outbound capabilities match the dialinfo? // does the node's outbound capabilities match the dialinfo?
Box::new(move |rti, _k, e| { Box::new(move |rti, _k, e| {
if let Some(e) = e { if let Some(e) = e {

View File

@ -138,13 +138,17 @@ fn _get_route_permutation_count(hop_count: usize) -> usize {
(3..hop_count).into_iter().fold(2usize, |acc, x| acc * x) (3..hop_count).into_iter().fold(2usize, |acc, x| acc * x)
} }
type PermFunc<'t> = Box<dyn Fn(&[usize]) -> Option<(Vec<usize>, Vec<u8>)> + Send + 't>;
/// get the route permutation at particular 'perm' index, starting at the 'start' index /// get the route permutation at particular 'perm' index, starting at the 'start' index
/// for a set of 'hop_count' nodes. the first node is always fixed, and the maximum /// for a set of 'hop_count' nodes. the first node is always fixed, and the maximum
/// number of permutations is given by get_route_permutation_count() /// number of permutations is given by get_route_permutation_count()
fn with_route_permutations<F>(hop_count: usize, start: usize, mut f: F) -> bool
where fn with_route_permutations(
F: FnMut(&[usize]) -> bool, hop_count: usize,
{ start: usize,
f: &PermFunc,
) -> Option<(Vec<usize>, Vec<u8>)> {
if hop_count == 0 { if hop_count == 0 {
unreachable!(); unreachable!();
} }
@ -159,20 +163,19 @@ where
} }
// heaps algorithm, but skipping the first element // heaps algorithm, but skipping the first element
fn heaps_permutation<F>(permutation: &mut [usize], size: usize, mut f: F) -> bool fn heaps_permutation(
where permutation: &mut [usize],
F: FnMut(&[usize]) -> bool, size: usize,
{ f: &PermFunc,
) -> Option<(Vec<usize>, Vec<u8>)> {
if size == 1 { if size == 1 {
if f(&permutation) { return f(&permutation);
return true;
}
return false;
} }
for i in 0..size { for i in 0..size {
if heaps_permutation(permutation, size - 1, &mut f) { let out = heaps_permutation(permutation, size - 1, f);
return true; if out.is_some() {
return out;
} }
if size % 2 == 1 { if size % 2 == 1 {
permutation.swap(1, size); permutation.swap(1, size);
@ -180,7 +183,8 @@ where
permutation.swap(1 + i, size); permutation.swap(1 + i, size);
} }
} }
false
None
} }
// recurse // recurse
@ -502,77 +506,81 @@ impl RouteSpecStore {
} }
// Now go through nodes and try to build a route we haven't seen yet // Now go through nodes and try to build a route we haven't seen yet
let perm_func = Box::new(|permutation: &[usize]| {
// Get the route cache key
let cache_key = route_permutation_to_hop_cache(&nodes, permutation);
// Skip routes we have already seen
if inner.cache.hop_cache.contains(&cache_key) {
return None;
}
// Ensure this route is viable by checking that each node can contact the next one
if directions.contains(Direction::Outbound) {
let our_node_info = rti.get_own_node_info(RoutingDomain::PublicInternet);
let our_node_id = rti.node_id();
let mut previous_node = &(our_node_id, our_node_info);
let mut reachable = true;
for n in permutation {
let current_node = nodes.get(*n).unwrap();
let cm = rti.get_contact_method(
RoutingDomain::PublicInternet,
&previous_node.0,
&previous_node.1,
&current_node.0,
&current_node.1,
DialInfoFilter::all(),
sequencing,
);
if matches!(cm, ContactMethod::Unreachable) {
reachable = false;
break;
}
previous_node = current_node;
}
if !reachable {
return None;
}
}
if directions.contains(Direction::Inbound) {
let our_node_info = rti.get_own_node_info(RoutingDomain::PublicInternet);
let our_node_id = rti.node_id();
let mut next_node = &(our_node_id, our_node_info);
let mut reachable = true;
for n in permutation.iter().rev() {
let current_node = nodes.get(*n).unwrap();
let cm = rti.get_contact_method(
RoutingDomain::PublicInternet,
&next_node.0,
&next_node.1,
&current_node.0,
&current_node.1,
DialInfoFilter::all(),
sequencing,
);
if matches!(cm, ContactMethod::Unreachable) {
reachable = false;
break;
}
next_node = current_node;
}
if !reachable {
return None;
}
}
// Keep this route
let route_nodes = permutation.to_vec();
Some((route_nodes, cache_key))
}) as PermFunc;
let mut route_nodes: Vec<usize> = Vec::new(); let mut route_nodes: Vec<usize> = Vec::new();
let mut cache_key: Vec<u8> = Vec::new(); let mut cache_key: Vec<u8> = Vec::new();
for start in 0..(nodes.len() - hop_count) { for start in 0..(nodes.len() - hop_count) {
// Try the permutations available starting with 'start' // Try the permutations available starting with 'start'
let done = with_route_permutations(hop_count, start, |permutation: &[usize]| { if let Some((rn, ck)) = with_route_permutations(hop_count, start, &perm_func) {
// Get the route cache key route_nodes = rn;
cache_key = route_permutation_to_hop_cache(&nodes, permutation); cache_key = ck;
// Skip routes we have already seen
if inner.cache.hop_cache.contains(&cache_key) {
return false;
}
// Ensure this route is viable by checking that each node can contact the next one
if directions.contains(Direction::Outbound) {
let our_node_info = rti.get_own_node_info(RoutingDomain::PublicInternet);
let our_node_id = rti.node_id();
let mut previous_node = &(our_node_id, our_node_info);
let mut reachable = true;
for n in permutation {
let current_node = nodes.get(*n).unwrap();
let cm = rti.get_contact_method(
RoutingDomain::PublicInternet,
&previous_node.0,
&previous_node.1,
&current_node.0,
&current_node.1,
DialInfoFilter::all(),
sequencing,
);
if matches!(cm, ContactMethod::Unreachable) {
reachable = false;
break;
}
previous_node = current_node;
}
if !reachable {
return false;
}
}
if directions.contains(Direction::Inbound) {
let our_node_info = rti.get_own_node_info(RoutingDomain::PublicInternet);
let our_node_id = rti.node_id();
let mut next_node = &(our_node_id, our_node_info);
let mut reachable = true;
for n in permutation.iter().rev() {
let current_node = nodes.get(*n).unwrap();
let cm = rti.get_contact_method(
RoutingDomain::PublicInternet,
&next_node.0,
&next_node.1,
&current_node.0,
&current_node.1,
DialInfoFilter::all(),
sequencing,
);
if matches!(cm, ContactMethod::Unreachable) {
reachable = false;
break;
}
next_node = current_node;
}
if !reachable {
return false;
}
}
// Keep this route
route_nodes = permutation.to_vec();
true
});
if done {
break; break;
} }
} }
@ -611,6 +619,8 @@ impl RouteSpecStore {
sequencing, sequencing,
}; };
drop(perm_func);
// Add to cache // Add to cache
Self::add_to_cache(&mut inner.cache, cache_key, &rsd); Self::add_to_cache(&mut inner.cache, cache_key, &rsd);