1use std::{error::Error, fmt};
2
3#[rustfmt::skip]
4const MAGIC: [(i32, i32, i32); 64] = [
5 (-1, -1, 0),
7 (-0b10000000000000000000000000000000, 0, 0),
8 (0b1010101010101010101010101010101, 0b1010101010101010101010101010101, 0),
9 (-0b10000000000000000000000000000000, 0, 1),
10 (0b110011001100110011001100110011, 0b110011001100110011001100110011, 0),
11 (0b101010101010101010101010101010, 0b101010101010101010101010101010, 0),
12 (0b100100100100100100100100100100, 0b100100100100100100100100100100, 0),
13 (-0b10000000000000000000000000000000, 0, 2),
14 (0b11100011100011100011100011100, 0b11100011100011100011100011100, 0),
15 (0b11001100110011001100110011001, 0b11001100110011001100110011001, 0),
16 (0b10111010001011101000101110100, 0b10111010001011101000101110100, 0),
17 (0b10101010101010101010101010101, 0b10101010101010101010101010101, 0),
18 (0b10011101100010011101100010011, 0b10011101100010011101100010011, 0),
19 (0b10010010010010010010010010010, 0b10010010010010010010010010010, 0),
20 (0b10001000100010001000100010001, 0b10001000100010001000100010001, 0),
21 (-0b10000000000000000000000000000000, 0, 3),
22 (0b1111000011110000111100001111, 0b1111000011110000111100001111, 0),
23 (0b1110001110001110001110001110, 0b1110001110001110001110001110, 0),
24 (0b1101011110010100001101011110, 0b1101011110010100001101011110, 0),
25 (0b1111111111111111111111111111000, 0b1111111111111111111111111111000, 0),
26 (0b1100001100001100001100001100, 0b1100001100001100001100001100, 0),
27 (0b1011101000101110100010111010, 0b1011101000101110100010111010, 0),
28 (0b1011001000010110010000101100, 0b1011001000010110010000101100, 0),
29 (0b1010101010101010101010101010, 0b1010101010101010101010101010, 0),
30 (0b1010001111010111000010100011, 0b1010001111010111000010100011, 0),
31 (0b1001110110001001110110001001, 0b1001110110001001110110001001, 0),
32 (0b1001011110110100001001011110, 0b1001011110110100001001011110, 0),
33 (0b1001001001001001001001001001, 0b1001001001001001001001001001, 0),
34 (0b1000110100111101110010110000, 0b1000110100111101110010110000, 0),
35 (0b1000100010001000100010001000, 0b1000100010001000100010001000, 0),
36 (0b1000010000100001000010000100, 0b1000010000100001000010000100, 0),
37 (-0b10000000000000000000000000000000, 0, 4),
38 (0b111110000011111000001111100, 0b111110000011111000001111100, 0),
39 (0b111100001111000011110000111, 0b111100001111000011110000111, 0),
40 (0b111010100000111010100000111, 0b111010100000111010100000111, 0),
41 (0b111000111000111000111000111, 0b111000111000111000111000111, 0),
42 (0b110111010110011111001000101, 0b110111010110011111001000101, 0),
43 (0b110101111001010000110101111, 0b110101111001010000110101111, 0),
44 (0b110100100000110100100000110, 0b110100100000110100100000110, 0),
45 (0b110011001100110011001100110, 0b110011001100110011001100110, 0),
46 (0b110001111100111000001100011, 0b110001111100111000001100011, 0),
47 (0b110000110000110000110000110, 0b110000110000110000110000110, 0),
48 (0b101111101000001011111010000, 0b101111101000001011111010000, 0),
49 (0b101110100010111010001011101, 0b101110100010111010001011101, 0),
50 (0b101101100000101101100000101, 0b101101100000101101100000101, 0),
51 (0b101100100001011001000010110, 0b101100100001011001000010110, 0),
52 (0b101011100100110001000001010, 0b101011100100110001000001010, 0),
53 (0b101010101010101010101010101, 0b101010101010101010101010101, 0),
54 (0b101001110010111100000101001, 0b101001110010111100000101001, 0),
55 (0b101000111101011100001010001, 0b101000111101011100001010001, 0),
56 (0b101000001010000010100000101, 0b101000001010000010100000101, 0),
57 (0b100111011000100111011000100, 0b100111011000100111011000100, 0),
58 (0b100110101001000011100111110, 0b100110101001000011100111110, 0),
59 (0b100101111011010000100101111, 0b100101111011010000100101111, 0),
60 (0b100101001111001000001001010, 0b100101001111001000001001010, 0),
61 (0b100100100100100100100100100, 0b100100100100100100100100100, 0),
62 (0b100011111011100000100011111, 0b100011111011100000100011111, 0),
63 (0b100011010011110111001011000, 0b100011010011110111001011000, 0),
64 (0b100010101101100011110010111, 0b100010101101100011110010111, 0),
65 (0b100010001000100010001000100, 0b100010001000100010001000100, 0),
66 (0b100001100100101110001010011, 0b100001100100101110001010011, 0),
67 (0b100001000010000100001000010, 0b100001000010000100001000010, 0),
68 (0b100000100000100000100000100, 0b100000100000100000100000100, 0),
69 (-0b10000000000000000000000000000000, 0, 5),
70];
71
72#[derive(Clone, Debug, Default)]
74pub struct BitStorage {
75 pub data: Box<[u64]>,
76 bits: usize,
77 mask: u64,
78 size: usize,
79 values_per_long: usize,
80 divide_mul: u64,
81 divide_add: u64,
82 divide_shift: i32,
83}
84
85#[derive(Debug)]
86pub enum BitStorageError {
87 InvalidLength { got: usize, expected: usize },
88}
89impl fmt::Display for BitStorageError {
90 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
91 match self {
92 BitStorageError::InvalidLength { got, expected } => write!(
93 f,
94 "Invalid length given for storage, got: {got}, but expected: {expected}",
95 ),
96 }
97 }
98}
99impl Error for BitStorageError {}
100
101impl BitStorage {
102 pub fn new(
105 bits: usize,
106 size: usize,
107 data: Option<Box<[u64]>>,
108 ) -> Result<Self, BitStorageError> {
109 if let Some(data) = &data {
110 if data.is_empty() {
112 return Ok(BitStorage {
113 data: Box::new([]),
114 bits,
115 size,
116 ..Default::default()
117 });
118 }
119 }
120
121 debug_assert!((1..=32).contains(&bits));
122
123 let values_per_long = 64 / bits;
124 let magic_index = values_per_long - 1;
125 let (divide_mul, divide_add, divide_shift) = MAGIC[magic_index];
126 let calculated_length = size.div_ceil(values_per_long);
127
128 let mask = (1 << bits) - 1;
129
130 let using_data = if let Some(data) = data {
131 if data.len() != calculated_length {
132 return Err(BitStorageError::InvalidLength {
133 got: data.len(),
134 expected: calculated_length,
135 });
136 }
137 data
138 } else {
139 vec![0; calculated_length].into()
140 };
141
142 Ok(BitStorage {
143 data: using_data,
144 bits,
145 mask,
146 size,
147 values_per_long,
148 divide_mul: divide_mul as u32 as u64,
149 divide_add: divide_add as u32 as u64,
150 divide_shift,
151 })
152 }
153
154 pub fn cell_index(&self, index: u64) -> usize {
155 let first = self.divide_mul;
157 let second = self.divide_add;
158
159 (((index * first) + second) >> 32 >> self.divide_shift) as usize
160 }
161
162 pub fn get(&self, index: usize) -> u64 {
169 assert!(
170 index < self.size,
171 "Index {index} out of bounds (must be less than {})",
172 self.size
173 );
174
175 if self.data.is_empty() {
177 return 0;
178 }
179
180 let cell_index = self.cell_index(index as u64);
181 let cell = &self.data[cell_index];
182 let bit_index = (index - cell_index * self.values_per_long) * self.bits;
183 (cell >> bit_index) & self.mask
184 }
185
186 pub fn get_and_set(&mut self, index: usize, value: u64) -> u64 {
187 if self.data.is_empty() {
189 return 0;
190 }
191
192 debug_assert!(index < self.size);
193 debug_assert!(value <= self.mask);
194 let cell_index = self.cell_index(index as u64);
195 let cell = &mut self.data[cell_index];
196 let bit_index = (index - cell_index * self.values_per_long) * self.bits;
197 let old_value = (*cell >> (bit_index as u64)) & self.mask;
198 *cell = (*cell & !(self.mask << bit_index)) | ((value & self.mask) << bit_index);
199 old_value
200 }
201
202 pub fn set(&mut self, index: usize, value: u64) {
203 if self.data.is_empty() {
205 return;
206 }
207
208 debug_assert!(index < self.size);
209 debug_assert!(value <= self.mask);
210 let cell_index = self.cell_index(index as u64);
211 let cell = &mut self.data[cell_index];
212 let bit_index = (index - cell_index * self.values_per_long) * self.bits;
213 *cell = (*cell & !(self.mask << bit_index)) | ((value & self.mask) << bit_index);
214 }
215
216 #[inline]
218 pub fn size(&self) -> usize {
219 self.size
220 }
221
222 pub fn iter(&self) -> BitStorageIter {
223 BitStorageIter {
224 storage: self,
225 index: 0,
226 }
227 }
228}
229
230pub struct BitStorageIter<'a> {
231 storage: &'a BitStorage,
232 index: usize,
233}
234
235impl Iterator for BitStorageIter<'_> {
236 type Item = u64;
237
238 fn next(&mut self) -> Option<Self::Item> {
239 if self.index >= self.storage.size {
240 return None;
241 }
242
243 let value = self.storage.get(self.index);
244 self.index += 1;
245 Some(value)
246 }
247}
248
249#[cfg(test)]
250mod tests {
251 use super::*;
252
253 #[test]
254 fn test_wikivg_example() {
255 let data = [
256 1, 2, 2, 3, 4, 4, 5, 6, 6, 4, 8, 0, 7, 4, 3, 13, 15, 16, 9, 14, 10, 12, 0, 2,
257 ];
258 let compact_data: [u64; 2] = [0x0020863148418841, 0x01018A7260F68C87];
259 let storage = BitStorage::new(5, data.len(), Some(Box::new(compact_data))).unwrap();
260
261 for (i, expected) in data.iter().enumerate() {
262 assert_eq!(storage.get(i), *expected);
263 }
264 }
265}