lifetime cleanup
This commit is contained in:
parent
92b22d5af5
commit
941cf9309e
@ -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 {
|
||||
|
@ -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,
|
||||
¤t_node.0,
|
||||
¤t_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,
|
||||
¤t_node.0,
|
||||
¤t_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,
|
||||
¤t_node.0,
|
||||
¤t_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,
|
||||
¤t_node.0,
|
||||
¤t_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);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user