redgold_schema/util/
xor_distance.rs1use crate::proto_serde::ProtoSerde;
2use crate::structs::{Hash, NodeMetadata, PartitionInfo, PublicKey};
3use itertools::Itertools;
4
5pub fn xor_distance(v1: &Vec<u8>, v2: &Vec<u8>) -> i64 {
6 let xor_value: Vec<u8> = v1
7 .iter()
8 .zip(v2.iter())
9 .map(|(&x1, &x2)| x1 ^ x2)
10 .collect();
11 let distance: i64 = xor_value.iter().map(|&byte| i64::from(byte)).sum();
12 distance
13}
14
15pub fn xorf_conv_distance(query_hash: &Vec<u8>, peer_marker: &Vec<u8>) -> i64 {
16
17 let mut concat = query_hash.clone();
19 concat.extend(peer_marker.clone());
20 let merged = Hash::digest(concat).vec();
22
23 let mut concat2 = peer_marker.clone();
25 concat2.extend(query_hash.clone());
26
27 let merged2 = Hash::digest(concat2).vec();
28
29 let xor_value: Vec<u8> = merged
30 .iter()
31 .zip(merged2.iter())
32 .map(|(&x1, &x2)| x1 ^ x2)
33 .collect();
34 let distance: i64 = xor_value.iter().map(|&byte| i64::from(byte)).sum();
35 distance
36}
37
38pub fn xorfc_hash(query_hash: &Hash, pk: &PublicKey) -> i64 {
39 let query_hash = query_hash.vec();
40 let pk_bytes = pk.vec();
41 xorf_conv_distance(&query_hash, &pk_bytes)
42}
43
44pub trait XorDistancePartitionInfo {
45 fn tx_hash_distance(&self, hash: &Hash, pk: &PublicKey) -> bool;
46}
47
48impl XorDistancePartitionInfo for Option<PartitionInfo> {
49 fn tx_hash_distance(&self, hash: &Hash, pk: &PublicKey) -> bool {
50 let d = xorfc_hash(hash, &pk);
51 self.as_ref().and_then(|pi| pi.transaction_hash.as_ref())
52 .map(|d_max| &d < d_max).unwrap_or(true)
53 }
54}
55
56pub trait XorfConvDistanceSubset<T> {
57 fn xorf_conv_distance_subset<F>(
58 &self, other: &Vec<u8>, partition_func: F
59 ) -> Vec<&T>
60 where F: FnOnce(&PartitionInfo) -> Option<i64> + Copy;
61}
62
63impl XorfConvDistanceSubset<NodeMetadata> for Vec<NodeMetadata> {
64 fn xorf_conv_distance_subset<F>(
65 &self, other: &Vec<u8>, partition_func: F
66 ) -> Vec<&NodeMetadata>
67 where F: FnOnce(&PartitionInfo) -> Option<i64> + Copy {
68 let res = self.iter()
69 .filter_map(|n| n.public_key.as_ref().map(|p| (p, n)))
70 .filter_map(|(p, n)| p.bytes.as_ref().map(|b| (b.value.clone(), n)))
71 .map(|(p, n)| (xorf_conv_distance(other, &p), n))
72 .filter(|(p, n)|
73 n.partition_info.as_ref().and_then(|i| partition_func(i)).map(|d| d < *p).unwrap_or(true))
74 .sorted_by(|(p1, _), (p2, _)| p1.cmp(p2))
75 .map(|(_p, n)| n)
76 .collect_vec();
77 res
78 }
79}
80
81#[test]
82pub fn xor_test() {
83}