1
2pub struct PackedArray {
8 cells: Vec<u64>,
9 length: usize,
10 byte_size: u8,
11}
12
13
14impl PackedArray {
15
16 pub fn new(length: usize, byte_size: u8, default: Option<u64>) -> Self {
19
20 Self::check_byte_size(byte_size);
21
22 let default_value = match default {
23 Some(default) if default != 0 => {
24 assert!(default <= Self::calc_mask(byte_size), "Given default value does not fit in {} bits.", byte_size);
25 let vpc = Self::calc_values_per_cell(byte_size);
26 let mut value = default;
27 for _ in 1..vpc {
28 value <<= byte_size;
29 value |= default;
30 }
31 value
32 },
33 _ => 0
34 };
35
36 Self {
37 cells: vec![default_value; Self::calc_cells_capacity(length, byte_size)],
38 length,
39 byte_size,
40 }
41
42 }
43
44 pub fn from_raw(length: usize, byte_size: u8, cells: Vec<u64>) -> Option<Self> {
45 Self::check_byte_size(byte_size);
46 if cells.len() >= Self::calc_cells_capacity(length, byte_size) {
47 Some(Self {
48 cells,
49 length,
50 byte_size
51 })
52 } else {
53 None
54 }
55 }
56
57 pub fn get(&self, index: usize) -> Option<u64> {
59 if index < self.length {
60 let (cell_index, bit_index) = self.get_indices(index);
61 let cell = self.cells[cell_index];
62 Some((cell >> bit_index) & Self::calc_mask(self.byte_size))
63 } else {
64 None
65 }
66 }
67
68 pub fn set(&mut self, index: usize, value: u64) -> u64 {
73 if index < self.length {
74 let mask = Self::calc_mask(self.byte_size);
75 if value <= mask {
76 self.internal_set(index, value, mask)
77 } else {
78 panic!("Given value {} does not fit in {} bits.", value, self.byte_size);
79 }
80 } else {
81 panic!("Index out of bounds, {} with length {}.", index, self.length);
82 }
83 }
84
85 pub fn set_with_resize(&mut self, index: usize, value: u64) -> u64 {
88 let mask = Self::calc_mask(self.byte_size);
89 if value > mask {
90 self.resize_byte(Self::calc_min_byte_size(value));
91 }
92 self.internal_set(index, value, mask)
93 }
94
95 #[inline]
96 fn internal_set(&mut self, index: usize, value: u64, mask: u64) -> u64 {
97 let (cell_index, bit_index) = self.get_indices(index);
98 let cell = &mut self.cells[cell_index];
99 let old_value = (*cell >> bit_index) & mask;
100 *cell = (*cell & !(mask << bit_index)) | (value << bit_index); old_value
102 }
103
104 fn get_indices(&self, index: usize) -> (usize, usize) {
105 let vpc = Self::calc_values_per_cell(self.byte_size);
106 let cell_index = index / vpc;
107 let bit_index = (index % vpc) * self.byte_size as usize;
108 (cell_index, bit_index)
109 }
110
111 #[inline]
112 pub fn iter<'a>(&'a self) -> impl Iterator<Item = u64> + 'a {
113 self.cells.iter().copied().unpack_aligned(self.byte_size).take(self.length)
114 }
115
116 pub fn replace(&mut self, mut replacer: impl FnMut(usize, u64) -> u64) {
117 let byte_size = self.byte_size as usize;
118 let vpc = Self::calc_values_per_cell(self.byte_size);
119 let mask = Self::calc_mask(self.byte_size);
120 let mut index = 0;
121 for mut_cell in &mut self.cells {
122 let mut old_cell = *mut_cell;
123 let mut new_cell = 0;
124 for value_index in 0..vpc {
125 let bit_index = value_index * byte_size;
126 new_cell |= (replacer(index, old_cell & mask) & mask) << bit_index;
127 old_cell >>= self.byte_size;
128 index += 1;
129 if index >= self.length {
130 break;
131 }
132 }
133 *mut_cell = new_cell;
134 }
135 }
136
137 pub fn resize_byte(&mut self, new_byte_size: u8) {
138 self.internal_resize_byte::<fn(usize, u64) -> u64>(new_byte_size, None);
139 }
140
141 pub fn resize_byte_and_replace<F>(&mut self, new_byte_size: u8, replacer: F)
142 where
143 F: FnMut(usize, u64) -> u64
144 {
145 self.internal_resize_byte(new_byte_size, Some(replacer));
146 }
147
148 fn internal_resize_byte<F>(&mut self, new_byte_size: u8, mut replacer: Option<F>)
149 where
150 F: FnMut(usize, u64) -> u64
151 {
152
153 if new_byte_size == self.byte_size {
154 if let Some(replacer) = replacer {
155 self.replace(replacer);
156 return;
157 }
158 }
159
160 Self::check_byte_size(new_byte_size);
161 assert!(new_byte_size > self.byte_size, "New byte size should be greater than previous.");
162
163 let old_byte_size = self.byte_size;
164 self.byte_size = new_byte_size;
165
166 let old_mask = Self::calc_mask(old_byte_size);
167 let new_mask = Self::calc_mask(new_byte_size);
168
169 let new_cells_cap = Self::calc_cells_capacity(self.length, new_byte_size);
170
171 let old_vpc = Self::calc_values_per_cell(old_byte_size);
172 let new_vpc = Self::calc_values_per_cell(new_byte_size);
173
174 let old_byte_size = old_byte_size as usize;
175 let new_byte_size = new_byte_size as usize;
176
177 let old_cells_cap = self.cells.len();
178 self.cells.resize(new_cells_cap, 0u64);
179
180 for old_cell_index in (0..old_cells_cap).rev() {
181 let old_cell = self.cells[old_cell_index];
182 for value_index in 0..old_vpc {
183 let index = old_cell_index * old_vpc + value_index;
184 if index < self.length {
185
186 let old_bit_index = value_index * old_byte_size;
187 let mut value = (old_cell >> old_bit_index) & old_mask;
188
189 let new_cell_index = index / new_vpc;
190 let new_bit_index = (index % new_vpc) * new_byte_size;
191
192 if let Some(ref mut replacer) = replacer {
193 value = replacer(index, value);
194 }
195
196 let cell = &mut self.cells[new_cell_index];
197 *cell = (*cell & !(new_mask << new_bit_index)) | (value << new_bit_index);
198
199 }
200 }
201 }
202
203 }
204
205 #[inline]
206 pub fn len(&self) -> usize {
207 self.length
208 }
209
210 #[inline]
211 pub fn is_empty(&self) -> bool {
212 self.length == 0
213 }
214
215 #[inline]
216 pub fn byte_size(&self) -> u8 {
217 self.byte_size
218 }
219
220 pub fn max_value(&self) -> u64 {
221 Self::calc_mask(self.byte_size)
222 }
223
224 #[inline]
225 pub fn cells_len(&self) -> usize {
226 self.cells.len()
227 }
228
229 pub fn get_cell(&self, index: usize) -> u64 {
232 self.cells[index]
233 }
234
235 pub unsafe fn set_cell(&mut self, index: usize, cell: u64) {
236 self.cells[index] = cell;
237 }
238
239 pub unsafe fn resize_raw(&mut self, new_byte_size: u8) {
240 Self::check_byte_size(new_byte_size);
241 self.byte_size = new_byte_size;
242 let new_cells_cap = Self::calc_cells_capacity(self.length, new_byte_size);
243 self.cells.resize(new_cells_cap, 0u64);
244 }
245
246 pub unsafe fn clear_cells(&mut self) {
247 self.cells.iter_mut().for_each(|c| *c = 0);
248 }
249
250 #[inline]
251 pub fn into_inner(self) -> Vec<u64> {
252 self.cells
253 }
254
255 #[inline]
258 pub fn calc_values_per_cell(byte_size: u8) -> usize {
259 64 / byte_size as usize
260 }
261
262 #[inline]
263 pub fn calc_cells_capacity(length: usize, byte_size: u8) -> usize {
264 let vpc = Self::calc_values_per_cell(byte_size);
265 (length + vpc - 1) / vpc
266 }
267
268 #[inline]
269 pub fn calc_mask(byte_size: u8) -> u64 {
270 if byte_size == 64 {
271 u64::MAX
272 } else {
273 (1u64 << byte_size) - 1
274 }
275 }
276
277 #[inline]
281 pub fn calc_min_byte_size(value: u64) -> u8 {
282 if value == 0 {
283 1
284 } else {
285 (u64::BITS - value.leading_zeros()) as u8
286 }
287 }
288
289 #[inline]
290 fn check_byte_size(byte_size: u8) {
291 assert!(byte_size <= 64, "Byte size is greater than 64.");
292 }
293
294}
295
296
297pub trait PackedIterator: Iterator<Item = u64> {
301
302 #[inline]
303 fn unpack_aligned(self, byte_size: u8) -> UnpackAlignedIter<Self>
304 where
305 Self: Sized
306 {
307 UnpackAlignedIter::new(self, byte_size)
308 }
309
310 #[inline]
311 fn pack_aligned(self, byte_size: u8) -> PackAlignedIter<Self>
312 where
313 Self: Sized
314 {
315 PackAlignedIter::new(self, byte_size)
316 }
317
318}
319
320impl<I> PackedIterator for I
321where
322 I: Iterator<Item = u64>
323{
324 }
326
327
328pub struct UnpackAlignedIter<I> {
345 inner: I,
346 byte_size: u8,
347 mask: u64,
348 vpc: usize,
349 index: usize,
350 value: u64
351}
352
353impl<I> UnpackAlignedIter<I>
354where
355 I: Iterator<Item = u64>
356{
357
358 pub fn new(inner: I, byte_size: u8) -> Self {
359 Self {
360 inner,
361 byte_size,
362 mask: PackedArray::calc_mask(byte_size),
363 vpc: PackedArray::calc_values_per_cell(byte_size),
364 index: 0,
365 value: 0
366 }
367 }
368
369}
370
371impl<I> Iterator for UnpackAlignedIter<I>
372where
373 I: Iterator<Item = u64>
374{
375
376 type Item = u64;
377
378 fn next(&mut self) -> Option<Self::Item> {
379
380 if self.index % self.vpc == 0 {
381 self.value = self.inner.next()?;
382 }
383
384 let ret = self.value & self.mask;
385 self.value >>= self.byte_size;
386 self.index += 1;
387 Some(ret)
388
389 }
390
391 }
396
397
398pub struct PackAlignedIter<I> {
400 inner: I,
401 byte_size: u8,
402 mask: u64,
403}
404
405impl<I> PackAlignedIter<I>
406where
407 I: Iterator<Item = u64>
408{
409
410 pub fn new(inner: I, byte_size: u8) -> Self {
411 Self {
412 inner,
413 byte_size,
414 mask: PackedArray::calc_mask(byte_size)
415 }
416 }
417
418}
419
420impl<I> Iterator for PackAlignedIter<I>
421where
422 I: Iterator<Item = u64>
423{
424
425 type Item = u64;
426
427 fn next(&mut self) -> Option<Self::Item> {
428
429 let mut value = match self.inner.next() {
430 None => return None,
431 Some(val) => val & self.mask
432 };
433
434 let mut shift = self.byte_size;
435 let shift_limit = 64 - self.byte_size;
436
437 while shift <= shift_limit {
438 match self.inner.next() {
439 None => break,
440 Some(cell) => {
441 value |= (cell & self.mask) << shift;
442 shift += self.byte_size;
443 }
444 }
445 }
446
447 Some(value)
448
449 }
450
451}
452
453
454#[cfg(test)]
455mod tests {
456
457 use super::*;
458
459 #[test]
460 fn valid_byte_size() {
461 PackedArray::new(1, 64, None);
462 }
463
464 #[test]
465 #[should_panic]
466 fn invalid_byte_size() {
467 PackedArray::new(1, 65, None);
468 }
469
470 #[test]
471 fn min_byte_size() {
472 assert_eq!(PackedArray::calc_min_byte_size(0), 1);
473 assert_eq!(PackedArray::calc_min_byte_size(1), 1);
474 assert_eq!(PackedArray::calc_min_byte_size(2), 2);
475 assert_eq!(PackedArray::calc_min_byte_size(7), 3);
476 assert_eq!(PackedArray::calc_min_byte_size(63), 6);
477 assert_eq!(PackedArray::calc_min_byte_size(64), 7);
478 assert_eq!(PackedArray::calc_min_byte_size(127), 7);
479 }
480
481 #[test]
482 #[should_panic]
483 fn invalid_default_value() {
484 PackedArray::new(1, 4, Some(16));
485 }
486
487 #[test]
488 #[should_panic]
489 fn invalid_value() {
490 let mut array = PackedArray::new(1, 4, None);
491 array.set(0, 16);
492 }
493
494 #[test]
495 #[should_panic]
496 fn out_of_range_get() {
497 PackedArray::new(10, 4, None).get(10).unwrap();
498 }
499
500 #[test]
501 #[should_panic]
502 fn out_of_range_set() {
503 PackedArray::new(10, 4, None).set(10, 15);
504 }
505
506 #[test]
507 #[should_panic]
508 fn invalid_resize() {
509 PackedArray::new(10, 4, None).resize_byte(4);
510 }
511
512 #[test]
513 fn valid_usage() {
514
515 const LEN: usize = 32;
516
517 let mut array = PackedArray::new(LEN, 4, Some(15));
518
519 assert_eq!(array.cells.len(), 2);
520 assert_eq!(array.cells[0], u64::MAX);
521 assert_eq!(array.cells[1], u64::MAX);
522
523 for value in array.iter() {
524 assert_eq!(value, 15, "construction failed");
525 }
526
527 array.set(2, 3);
528
529 for (i, value) in array.iter().enumerate() {
530 assert_eq!(value, if i == 2 { 3 } else { 15 }, "set failed");
531 }
532
533 array.replace(|_, val| val / 2);
534
535 for (i, value) in array.iter().enumerate() {
536 assert_eq!(value, if i == 2 { 1 } else { 7 }, "replace failed");
537 }
538
539 array.resize_byte(5);
540 assert_eq!(array.cells.len(), 3, "resize failed to change cells len");
541 assert_eq!(array.byte_size, 5, "resize failed to set the new byte size");
542
543 for (i, value) in array.iter().enumerate() {
544 assert_eq!(value, if i == 2 { 1 } else { 7 }, "resize failed to transform values");
545 }
546
547 array.resize_byte_and_replace(16, |_, val| val * 5678);
548 assert_eq!(array.cells.len(), 8, "resize and replace failed to change cells len");
549 assert_eq!(array.byte_size, 16, "resize and replace failed to set the new byte size");
550
551 for (i, value) in array.iter().enumerate() {
552 assert_eq!(value, if i == 2 { 5678 } else { 7 * 5678 }, "resize and replace failed to transform values");
553 }
554
555 }
556
557 #[test]
558 fn iter_unpack_aligned() {
559
560 let raw = [u64::MAX, u64::MAX, u64::MAX];
561
562 assert!(raw.iter().copied().unpack_aligned(4).all(|v| v == 15), "byte size = 4, wrong values");
563 assert_eq!(raw.iter().copied().unpack_aligned(4).count(), 48, "byte size = 4, invalid values count");
564
565 assert!(raw.iter().copied().unpack_aligned(16).all(|v| v == 65_535), "byte size = 16, wrong values");
566 assert_eq!(raw.iter().copied().unpack_aligned(16).count(), 12, "byte size = 16, invalid values count");
567
568 assert!(raw.iter().copied().unpack_aligned(33).all(|v| v == 0x0001_FFFF_FFFF), "byte size = 33, wrong values");
569 assert_eq!(raw.iter().copied().unpack_aligned(33).count(), 3, "byte size = 33, invalid values count");
570
571 }
572
573 #[test]
574 fn iter_pack_aligned() {
575
576 let raw = [0, u32::MAX as u64, u64::MAX];
577
578 let out: Vec<u64> = raw.iter()
579 .copied()
580 .unpack_aligned(4)
581 .pack_aligned(4)
582 .collect();
583
584 assert_eq!(&raw[..], &out[..]);
585
586 }
587
588}