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 protocol_to_port: ProtocolToPortMapping,
}
pub type RoutingTableEntryFilter =
Box<dyn for<'r> FnMut(&'r RoutingTableInner, DHTKey, Option<Arc<BucketEntry>>) -> bool + Send>;
pub type RoutingTableEntryFilter<'t> =
Box<dyn FnMut(&RoutingTableInner, DHTKey, Option<Arc<BucketEntry>>) -> bool + Send + 't>;
#[derive(Clone, Debug, Default)]
pub struct RoutingTableHealth {
@ -550,7 +550,7 @@ impl RoutingTable {
pub fn make_inbound_dial_info_entry_filter<'a>(
routing_domain: RoutingDomain,
dial_info_filter: DialInfoFilter,
) -> RoutingTableEntryFilter {
) -> RoutingTableEntryFilter<'a> {
// does it have matching public dial info?
Box::new(move |rti, _k, 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
pub fn make_outbound_dial_info_entry_filter(
pub fn make_outbound_dial_info_entry_filter<'a>(
routing_domain: RoutingDomain,
dial_info: DialInfo,
) -> RoutingTableEntryFilter {
) -> RoutingTableEntryFilter<'a> {
// does the node's outbound capabilities match the dialinfo?
Box::new(move |rti, _k, 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)
}
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
/// 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()
fn with_route_permutations<F>(hop_count: usize, start: usize, mut f: F) -> bool
where
F: FnMut(&[usize]) -> bool,
{
fn with_route_permutations(
hop_count: usize,
start: usize,
f: &PermFunc,
) -> Option<(Vec<usize>, Vec<u8>)> {
if hop_count == 0 {
unreachable!();
}
@ -159,20 +163,19 @@ where
}
// heaps algorithm, but skipping the first element
fn heaps_permutation<F>(permutation: &mut [usize], size: usize, mut f: F) -> bool
where
F: FnMut(&[usize]) -> bool,
{
fn heaps_permutation(
permutation: &mut [usize],
size: usize,
f: &PermFunc,
) -> Option<(Vec<usize>, Vec<u8>)> {
if size == 1 {
if f(&permutation) {
return true;
}
return false;
return f(&permutation);
}
for i in 0..size {
if heaps_permutation(permutation, size - 1, &mut f) {
return true;
let out = heaps_permutation(permutation, size - 1, f);
if out.is_some() {
return out;
}
if size % 2 == 1 {
permutation.swap(1, size);
@ -180,7 +183,8 @@ where
permutation.swap(1 + i, size);
}
}
false
None
}
// recurse
@ -502,77 +506,81 @@ impl RouteSpecStore {
}
// 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 cache_key: Vec<u8> = Vec::new();
for start in 0..(nodes.len() - hop_count) {
// Try the permutations available starting with 'start'
let done = with_route_permutations(hop_count, start, |permutation: &[usize]| {
// Get the route cache key
cache_key = route_permutation_to_hop_cache(&nodes, permutation);
// 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 {
if let Some((rn, ck)) = with_route_permutations(hop_count, start, &perm_func) {
route_nodes = rn;
cache_key = ck;
break;
}
}
@ -611,6 +619,8 @@ impl RouteSpecStore {
sequencing,
};
drop(perm_func);
// Add to cache
Self::add_to_cache(&mut inner.cache, cache_key, &rsd);