subspace_networking/utils/
key_with_distance.rs

1use libp2p::kad::KBucketDistance;
2pub use libp2p::kad::RecordKey;
3pub use libp2p::PeerId;
4use std::cmp::Ordering;
5use std::hash::Hash;
6
7type KademliaBucketKey<T> = libp2p::kad::KBucketKey<T>;
8
9/// Helper structure. It wraps Kademlia distance to a given peer for heap-metrics.
10#[derive(Debug, Clone, Eq)]
11pub struct KeyWithDistance {
12    key: RecordKey,
13    distance: KBucketDistance,
14}
15
16impl KeyWithDistance {
17    /// Creates a new [`KeyWithDistance`] instance with the given `PeerId` and `K` key.
18    ///
19    /// The `distance` is calculated as the distance between the `KademliaBucketKey` derived
20    /// from the `PeerId` and the `KademliaBucketKey` derived from the `K` key.
21    pub fn new<K>(peer_id: PeerId, key: K) -> Self
22    where
23        RecordKey: From<K>,
24    {
25        Self::new_with_record_key(peer_id, RecordKey::from(key))
26    }
27
28    /// Creates a new [`KeyWithDistance`] instance with the given `PeerId` and `RecordKey`.
29    pub fn new_with_record_key(peer_id: PeerId, key: RecordKey) -> Self {
30        let peer_key = KademliaBucketKey::from(peer_id);
31        let distance = KademliaBucketKey::new(key.as_ref()).distance(&peer_key);
32        Self { key, distance }
33    }
34
35    /// Returns a reference to the record key.
36    pub fn record_key(&self) -> &RecordKey {
37        &self.key
38    }
39}
40
41impl PartialEq for KeyWithDistance {
42    fn eq(&self, other: &Self) -> bool {
43        self.key == other.key
44    }
45}
46
47impl PartialOrd for KeyWithDistance {
48    fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
49        Some(self.cmp(other))
50    }
51}
52
53impl Ord for KeyWithDistance {
54    fn cmp(&self, other: &Self) -> Ordering {
55        self.distance.cmp(&other.distance)
56    }
57}
58
59impl Hash for KeyWithDistance {
60    fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
61        self.key.hash(state);
62    }
63}