atm0s_sdn_identity/
node_id.rs1pub type NodeId = u32;
2
3#[derive(Clone, Copy, Debug, Eq, PartialEq)]
4pub enum NodeSegment {
6 Public,
7 Private(u8),
8}
9
10pub trait NodeIdType: Clone {
11 fn random() -> NodeId;
13 fn segment(&self) -> NodeSegment;
15 fn distance(&self, other: &NodeId) -> u32;
17 fn distance_bits(&self, other: &NodeId) -> u8;
27 fn bucket_index(&self) -> u8;
29
30 fn build(geo1: u8, geo2: u8, group: u8, index: u8) -> Self;
39 fn build2(zone_id: u16, group: u8, index: u8) -> Self;
41 fn layer(&self, index: u8) -> u8;
43 fn geo1(&self) -> u8;
45 fn geo2(&self) -> u8;
47 fn group(&self) -> u8;
49 fn index(&self) -> u8;
51 fn eq_util_layer(&self, other: &Self) -> u8;
53}
54
55impl NodeIdType for NodeId {
56 fn random() -> NodeId {
57 rand::random()
58 }
59
60 fn segment(&self) -> NodeSegment {
61 NodeSegment::Public
62 }
63
64 fn distance(&self, other: &NodeId) -> u32 {
65 self ^ *other
66 }
67
68 fn distance_bits(&self, other: &NodeId) -> u8 {
69 let distance = self.distance(other);
70 (32 - distance.leading_zeros()) as u8
71 }
72
73 fn bucket_index(&self) -> u8 {
74 (32 - self.leading_zeros()) as u8
75 }
76
77 fn layer(&self, index: u8) -> u8 {
78 assert!(index <= 3);
79
80 (*self >> (8 * index)) as u8
81 }
82
83 fn build(geo1: u8, geo2: u8, group: u8, index: u8) -> Self {
84 ((geo1 as u32) << (8 * 3)) | ((geo2 as u32) << (8 * 2)) | ((group as u32) << 8) | (index as u32)
85 }
86
87 fn build2(zone_id: u16, group: u8, index: u8) -> Self {
88 ((zone_id as u32) << 16) | ((group as u32) << 8) | (index as u32)
89 }
90
91 fn geo1(&self) -> u8 {
92 (*self >> (8 * 3)) as u8
93 }
94
95 fn geo2(&self) -> u8 {
96 (*self >> (8 * 2)) as u8
97 }
98
99 fn group(&self) -> u8 {
100 (*self >> 8) as u8
101 }
102
103 fn index(&self) -> u8 {
104 *self as u8
105 }
106
107 fn eq_util_layer(&self, other: &Self) -> u8 {
109 if self.layer(3) != other.layer(3) {
110 return 4;
111 }
112
113 if self.layer(2) != other.layer(2) {
114 return 3;
115 }
116
117 if self.layer(1) != other.layer(1) {
118 return 2;
119 }
120
121 if self.layer(0) != other.layer(0) {
122 return 1;
123 }
124
125 0
126 }
127}
128
129#[cfg(test)]
130mod tests {
131 use crate::NodeSegment;
132
133 use super::{NodeId, NodeIdType};
134
135 #[test]
136 fn my_distance() {
137 let id1: NodeId = 30;
138 assert_eq!(id1.distance(&id1), 0);
139 assert_eq!(id1.distance_bits(&id1), 0);
140 }
141
142 #[test]
143 fn test_random() {
144 let id1 = NodeId::random();
145 let id2 = NodeId::random();
146 assert_ne!(id1, id2);
147 }
148
149 #[test]
150 fn test_segment() {
151 let id1: NodeId = 30;
152 assert_eq!(id1.segment(), NodeSegment::Public);
153 }
154
155 #[test]
156 fn test_distance() {
157 let id1: NodeId = 0;
158 let id2: NodeId = 1;
159 let id3: NodeId = 2;
160 let id4: NodeId = 3;
161 let id5: NodeId = u32::MAX;
162
163 assert_eq!(id1.distance(&id1), 0);
164 assert_eq!(id1.distance_bits(&id1), 0);
165
166 assert_eq!(id1.distance_bits(&id2), 1);
167 assert_eq!(id1.distance_bits(&id3), 2);
168 assert_eq!(id1.distance_bits(&id4), 2);
169 assert_eq!(id1.distance_bits(&id5), 32);
170 }
171
172 #[test]
173 fn test_bucket_index() {
174 let id1: NodeId = 0;
175 let id2: NodeId = 1;
176 let id3: NodeId = 2;
177 let id4: NodeId = 3;
178 let id5: NodeId = u32::MAX;
179
180 assert_eq!(id1.bucket_index(), 0);
181 assert_eq!(id2.bucket_index(), 1);
182 assert_eq!(id3.bucket_index(), 2);
183 assert_eq!(id4.bucket_index(), 2);
184 assert_eq!(id5.bucket_index(), 32);
185 }
186
187 #[test]
188 fn test_layer() {
189 let id1: NodeId = 0x12345678;
190 assert_eq!(id1.layer(0), 0x78);
191 assert_eq!(id1.layer(1), 0x56);
192 assert_eq!(id1.layer(2), 0x34);
193 assert_eq!(id1.layer(3), 0x12);
194 }
195
196 #[test]
197 fn test_eq_util_layer() {
198 let id1: NodeId = 0x12345678;
199 let id2: NodeId = 0x12345679;
200 let id3: NodeId = 0x12345778;
201 let id4: NodeId = 0x12355678;
202 let id5: NodeId = 0x12345678;
203
204 assert_eq!(id1.eq_util_layer(&id2), 1);
205 assert_eq!(id1.eq_util_layer(&id3), 2);
206 assert_eq!(id1.eq_util_layer(&id4), 3);
207 assert_eq!(id1.eq_util_layer(&id5), 0);
208 }
209}