pallet_broker/
core_mask.rs1use codec::{Decode, DecodeWithMemTracking, Encode, MaxEncodedLen};
19use core::ops::{BitAnd, BitAndAssign, BitOr, BitOrAssign, BitXor, BitXorAssign, Not};
20use scale_info::TypeInfo;
21use sp_core::RuntimeDebug;
22
23pub const CORE_MASK_BITS: usize = 80;
25
26#[derive(
28 Encode,
29 Decode,
30 DecodeWithMemTracking,
31 Default,
32 Copy,
33 Clone,
34 PartialEq,
35 Eq,
36 RuntimeDebug,
37 TypeInfo,
38 MaxEncodedLen,
39)]
40pub struct CoreMask([u8; 10]);
41impl CoreMask {
42 pub fn void() -> Self {
43 Self([0u8; 10])
44 }
45 pub fn complete() -> Self {
46 Self([255u8; 10])
47 }
48 pub fn is_void(&self) -> bool {
49 &self.0 == &[0u8; 10]
50 }
51 pub fn is_complete(&self) -> bool {
52 &self.0 == &[255u8; 10]
53 }
54 pub fn set(&mut self, i: u32) -> Self {
55 if i < 80 {
56 self.0[(i / 8) as usize] |= 128 >> (i % 8);
57 }
58 *self
59 }
60 pub fn clear(&mut self, i: u32) -> Self {
61 if i < 80 {
62 self.0[(i / 8) as usize] &= !(128 >> (i % 8));
63 }
64 *self
65 }
66 pub fn count_zeros(&self) -> u32 {
67 self.0.iter().map(|i| i.count_zeros()).sum()
68 }
69 pub fn count_ones(&self) -> u32 {
70 self.0.iter().map(|i| i.count_ones()).sum()
71 }
72 pub fn from_chunk(from: u32, to: u32) -> Self {
73 let mut v = [0u8; 10];
74 for i in (from.min(80) as usize)..(to.min(80) as usize) {
75 v[i / 8] |= 128 >> (i % 8);
76 }
77 Self(v)
78 }
79}
80impl From<u128> for CoreMask {
81 fn from(x: u128) -> Self {
82 let mut v = [0u8; 10];
83 v.iter_mut().rev().fold(x, |a, i| {
84 *i = a as u8;
85 a >> 8
86 });
87 Self(v)
88 }
89}
90impl From<CoreMask> for u128 {
91 fn from(x: CoreMask) -> Self {
92 x.0.into_iter().fold(0u128, |a, i| (a << 8) | i as u128)
93 }
94}
95impl BitAnd<Self> for CoreMask {
96 type Output = Self;
97 fn bitand(mut self, rhs: Self) -> Self {
98 self.bitand_assign(rhs);
99 self
100 }
101}
102impl BitAndAssign<Self> for CoreMask {
103 fn bitand_assign(&mut self, rhs: Self) {
104 for i in 0..10 {
105 self.0[i].bitand_assign(rhs.0[i]);
106 }
107 }
108}
109impl BitOr<Self> for CoreMask {
110 type Output = Self;
111 fn bitor(mut self, rhs: Self) -> Self {
112 self.bitor_assign(rhs);
113 self
114 }
115}
116impl BitOrAssign<Self> for CoreMask {
117 fn bitor_assign(&mut self, rhs: Self) {
118 for i in 0..10 {
119 self.0[i].bitor_assign(rhs.0[i]);
120 }
121 }
122}
123impl BitXor<Self> for CoreMask {
124 type Output = Self;
125 fn bitxor(mut self, rhs: Self) -> Self {
126 self.bitxor_assign(rhs);
127 self
128 }
129}
130impl BitXorAssign<Self> for CoreMask {
131 fn bitxor_assign(&mut self, rhs: Self) {
132 for i in 0..10 {
133 self.0[i].bitxor_assign(rhs.0[i]);
134 }
135 }
136}
137impl Not for CoreMask {
138 type Output = Self;
139 fn not(self) -> Self {
140 let mut result = [0u8; 10];
141 for i in 0..10 {
142 result[i] = self.0[i].not();
143 }
144 Self(result)
145 }
146}
147
148#[cfg(test)]
149mod tests {
150 use super::*;
151
152 #[test]
153 fn complete_works() {
154 assert_eq!(CoreMask::complete(), CoreMask([0xff; 10]));
155 assert!(CoreMask([0xff; 10]).is_complete());
156 for i in 0..80 {
157 assert!(!CoreMask([0xff; 10]).clear(i).is_complete());
158 }
159 }
160
161 #[test]
162 fn void_works() {
163 assert_eq!(CoreMask::void(), CoreMask([0; 10]));
164 assert!(CoreMask([0; 10]).is_void());
165 for i in 0..80 {
166 assert!(!(CoreMask([0; 10]).set(i).is_void()));
167 }
168 }
169
170 #[test]
171 fn from_works() {
172 assert!(CoreMask::from(0xfffff_fffff_fffff_fffff).is_complete());
173 assert_eq!(
174 CoreMask::from(0x12345_67890_abcde_f0123),
175 CoreMask([0x12, 0x34, 0x56, 0x78, 0x90, 0xab, 0xcd, 0xef, 0x01, 0x23]),
176 );
177 }
178
179 #[test]
180 fn into_works() {
181 assert_eq!(u128::from(CoreMask::complete()), 0xfffff_fffff_fffff_fffff);
182 assert_eq!(
183 0x12345_67890_abcde_f0123u128,
184 CoreMask([0x12, 0x34, 0x56, 0x78, 0x90, 0xab, 0xcd, 0xef, 0x01, 0x23]).into(),
185 );
186 }
187
188 #[test]
189 fn chunk_works() {
190 assert_eq!(CoreMask::from_chunk(40, 60), CoreMask::from(0x00000_00000_fffff_00000),);
191 }
192
193 #[test]
194 fn bit_or_works() {
195 assert_eq!(
196 CoreMask::from(0x02040_a0c0e_d0a0b_0ffff) | CoreMask::from(0x10305_0b0d0_0e0d0_e0000),
197 CoreMask::from(0x12345_abcde_deadb_effff),
198 );
199 }
200
201 #[test]
202 fn bit_or_assign_works() {
203 let mut a = CoreMask::from(0x02040_a0c0e_d0a0b_0ffff);
204 a |= CoreMask::from(0x10305_0b0d0_0e0d0_e0000);
205 assert_eq!(a, CoreMask::from(0x12345_abcde_deadb_effff));
206 }
207
208 #[test]
209 fn bit_and_works() {
210 assert_eq!(
211 CoreMask::from(0x00000_abcde_deadb_efff0) & CoreMask::from(0x02040_00000_d0a0b_0ff0f),
212 CoreMask::from(0x00000_00000_d0a0b_0ff00),
213 );
214 }
215
216 #[test]
217 fn bit_and_assign_works() {
218 let mut a = CoreMask::from(0x00000_abcde_deadb_efff0);
219 a &= CoreMask::from(0x02040_00000_d0a0b_0ff0f);
220 assert_eq!(a, CoreMask::from(0x00000_00000_d0a0b_0ff00));
221 }
222
223 #[test]
224 fn bit_xor_works() {
225 assert_eq!(
226 CoreMask::from(0x10010_10010_10010_10010) ^ CoreMask::from(0x01110_01110_01110_01110),
227 CoreMask::from(0x11100_11100_11100_11100),
228 );
229 }
230
231 #[test]
232 fn bit_xor_assign_works() {
233 let mut a = CoreMask::from(0x10010_10010_10010_10010);
234 a ^= CoreMask::from(0x01110_01110_01110_01110);
235 assert_eq!(a, CoreMask::from(0x11100_11100_11100_11100));
236 }
237}