checkpoint
This commit is contained in:
@@ -964,6 +964,16 @@ impl RoutingTable {
|
||||
.find_closest_nodes(node_count, node_id, filters, transform)
|
||||
}
|
||||
|
||||
pub fn sort_and_clean_closest_noderefs(
|
||||
&self,
|
||||
node_id: TypedKey,
|
||||
closest_nodes: &mut Vec<NodeRef>,
|
||||
) {
|
||||
self.inner
|
||||
.read()
|
||||
.sort_and_clean_closest_noderefs(node_id, closest_nodes)
|
||||
}
|
||||
|
||||
#[instrument(level = "trace", skip(self), ret)]
|
||||
pub fn register_find_node_answer(
|
||||
&self,
|
||||
|
@@ -1153,7 +1153,6 @@ impl RoutingTableInner {
|
||||
let vcrypto = self.unlocked_inner.crypto().get(crypto_kind).unwrap();
|
||||
|
||||
// Filter to ensure entries support the crypto kind in use
|
||||
|
||||
let filter = Box::new(
|
||||
move |_rti: &RoutingTableInner, opt_entry: Option<Arc<BucketEntry>>| {
|
||||
if let Some(entry) = opt_entry {
|
||||
@@ -1219,4 +1218,71 @@ impl RoutingTableInner {
|
||||
log_rtab!(">> find_closest_nodes: node count = {}", out.len());
|
||||
out
|
||||
}
|
||||
|
||||
pub fn sort_and_clean_closest_noderefs(
|
||||
&self,
|
||||
node_id: TypedKey,
|
||||
closest_nodes: &mut Vec<NodeRef>,
|
||||
) {
|
||||
// Lock all noderefs
|
||||
let kind = node_id.kind;
|
||||
let mut closest_nodes_locked: Vec<NodeRefLocked> = closest_nodes
|
||||
.iter()
|
||||
.filter_map(|x| {
|
||||
if x.node_ids().kinds().contains(&kind) {
|
||||
Some(x.locked(self))
|
||||
} else {
|
||||
None
|
||||
}
|
||||
})
|
||||
.collect();
|
||||
|
||||
// Sort closest
|
||||
let sort = make_closest_noderef_sort(self.unlocked_inner.crypto(), node_id);
|
||||
closest_nodes_locked.sort_by(sort);
|
||||
|
||||
// Unlock noderefs
|
||||
*closest_nodes = closest_nodes_locked.iter().map(|x| x.unlocked()).collect();
|
||||
}
|
||||
}
|
||||
|
||||
fn make_closest_noderef_sort(
|
||||
crypto: Crypto,
|
||||
node_id: TypedKey,
|
||||
) -> impl Fn(&NodeRefLocked, &NodeRefLocked) -> core::cmp::Ordering {
|
||||
let cur_ts = get_aligned_timestamp();
|
||||
let kind = node_id.kind;
|
||||
// Get cryptoversion to check distance with
|
||||
let vcrypto = crypto.get(node_id.kind).unwrap();
|
||||
|
||||
move |a: &NodeRefLocked, b: &NodeRefLocked| -> core::cmp::Ordering {
|
||||
// same nodes are always the same
|
||||
if a.same_entry(b) {
|
||||
return core::cmp::Ordering::Equal;
|
||||
}
|
||||
|
||||
// reliable nodes come first, pessimistically treating our own node as unreliable
|
||||
a.operate(|_rti, a_entry| {
|
||||
b.operate(|_rti, b_entry| {
|
||||
let ra = a_entry.check_reliable(cur_ts);
|
||||
let rb = b_entry.check_reliable(cur_ts);
|
||||
if ra != rb {
|
||||
if ra {
|
||||
return core::cmp::Ordering::Less;
|
||||
} else {
|
||||
return core::cmp::Ordering::Greater;
|
||||
}
|
||||
}
|
||||
|
||||
// get keys
|
||||
let a_key = a_entry.node_ids().get(node_id.kind).unwrap();
|
||||
let b_key = b_entry.node_ids().get(node_id.kind).unwrap();
|
||||
|
||||
// distance is the next metric, closer nodes first
|
||||
let da = vcrypto.distance(&a_key.value, &node_id.value);
|
||||
let db = vcrypto.distance(&b_key.value, &node_id.value);
|
||||
da.cmp(&db)
|
||||
})
|
||||
})
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user