use std::cmp::Ordering;
#[derive(Debug, Clone, Copy)]
pub(crate) struct Candidate {
pub(crate) distance: f32,
node: u32,
}
#[derive(Debug, Clone, Copy)]
pub(crate) struct RoutingCandidate {
pub(super) score: f32,
pub(super) mask: u16,
pub(super) last: u8,
pub(super) bits: u8,
}
impl RoutingCandidate {
pub(super) fn new(score: f32, mask: u16, bits: u8) -> Self {
Self {
score,
mask,
last: 0,
bits,
}
}
}
impl PartialEq for RoutingCandidate {
fn eq(&self, other: &Self) -> bool {
self.cmp(other) == Ordering::Equal
}
}
impl Eq for RoutingCandidate {}
impl PartialOrd for RoutingCandidate {
fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
Some(self.cmp(other))
}
}
impl Ord for RoutingCandidate {
fn cmp(&self, other: &Self) -> Ordering {
self.score
.total_cmp(&other.score)
.then_with(|| self.mask.cmp(&other.mask))
}
}
impl Candidate {
pub(crate) fn new(distance: f32, index: usize) -> Self {
Self {
distance,
node: u32::try_from(index).expect("vector count is bounded by u32::MAX"),
}
}
pub(crate) fn index(self) -> usize {
self.node as usize
}
}
impl PartialEq for Candidate {
fn eq(&self, other: &Self) -> bool {
self.cmp(other) == Ordering::Equal
}
}
impl Eq for Candidate {}
impl PartialOrd for Candidate {
fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
Some(self.cmp(other))
}
}
impl Ord for Candidate {
fn cmp(&self, other: &Self) -> Ordering {
self.distance
.total_cmp(&other.distance)
.then_with(|| self.node.cmp(&other.node))
}
}
pub(crate) fn splitmix64(mut value: u64) -> u64 {
value = value.wrapping_add(0x9e37_79b9_7f4a_7c15);
value = (value ^ (value >> 30)).wrapping_mul(0xbf58_476d_1ce4_e5b9);
value = (value ^ (value >> 27)).wrapping_mul(0x94d_49bb_1331_11eb);
value ^ (value >> 31)
}