1#[cfg(not(feature = "std"))]
7use alloc::{collections::VecDeque, vec::Vec};
8use bytes::{Buf, BufMut};
9use commonware_codec::{util::at_least, EncodeSize, Error as CodecError, Read, ReadExt, Write};
10use core::{
11 fmt::{self, Formatter, Write as _},
12 ops::{BitAnd, BitOr, BitXor, Index},
13};
14#[cfg(feature = "std")]
15use std::collections::VecDeque;
16
17mod prunable;
18pub use prunable::Prunable;
19
20pub mod historical;
21
22pub const DEFAULT_CHUNK_SIZE: usize = 8;
24
25#[derive(Clone, PartialEq, Eq, Hash)]
32pub struct BitMap<const N: usize = DEFAULT_CHUNK_SIZE> {
33 chunks: VecDeque<[u8; N]>,
39
40 len: u64,
42}
43
44impl<const N: usize> BitMap<N> {
45 const _CHUNK_SIZE_NON_ZERO_ASSERT: () = assert!(N > 0, "chunk size must be > 0");
46
47 pub const CHUNK_SIZE_BITS: u64 = (N * 8) as u64;
49
50 const EMPTY_CHUNK: [u8; N] = [0u8; N];
52
53 const FULL_CHUNK: [u8; N] = [u8::MAX; N];
55
56 pub fn new() -> Self {
60 #[allow(path_statements)]
61 Self::_CHUNK_SIZE_NON_ZERO_ASSERT; Self {
64 chunks: VecDeque::new(),
65 len: 0,
66 }
67 }
68
69 pub fn with_capacity(size: u64) -> Self {
71 #[allow(path_statements)]
72 Self::_CHUNK_SIZE_NON_ZERO_ASSERT; Self {
75 chunks: VecDeque::with_capacity(size.div_ceil(Self::CHUNK_SIZE_BITS) as usize),
76 len: 0,
77 }
78 }
79
80 pub fn zeroes(size: u64) -> Self {
82 #[allow(path_statements)]
83 Self::_CHUNK_SIZE_NON_ZERO_ASSERT; let num_chunks = size.div_ceil(Self::CHUNK_SIZE_BITS) as usize;
86 let mut chunks = VecDeque::with_capacity(num_chunks);
87 for _ in 0..num_chunks {
88 chunks.push_back(Self::EMPTY_CHUNK);
89 }
90 Self { chunks, len: size }
91 }
92
93 pub fn ones(size: u64) -> Self {
95 #[allow(path_statements)]
96 Self::_CHUNK_SIZE_NON_ZERO_ASSERT; let num_chunks = size.div_ceil(Self::CHUNK_SIZE_BITS) as usize;
99 let mut chunks = VecDeque::with_capacity(num_chunks);
100 for _ in 0..num_chunks {
101 chunks.push_back(Self::FULL_CHUNK);
102 }
103 let mut result = Self { chunks, len: size };
104 result.clear_trailing_bits();
106 result
107 }
108
109 #[inline]
113 pub fn len(&self) -> u64 {
114 self.len
115 }
116
117 #[inline]
119 pub fn is_empty(&self) -> bool {
120 self.len() == 0
121 }
122
123 #[inline]
125 pub fn is_chunk_aligned(&self) -> bool {
126 self.len.is_multiple_of(Self::CHUNK_SIZE_BITS)
127 }
128
129 fn chunks_len(&self) -> usize {
131 self.chunks.len()
132 }
133
134 #[inline]
142 pub fn get(&self, bit: u64) -> bool {
143 let chunk = self.get_chunk_containing(bit);
144 Self::get_from_chunk(chunk, bit)
145 }
146
147 #[inline]
153 fn get_chunk_containing(&self, bit: u64) -> &[u8; N] {
154 assert!(
155 bit < self.len(),
156 "bit {} out of bounds (len: {})",
157 bit,
158 self.len()
159 );
160 &self.chunks[Self::chunk(bit)]
161 }
162
163 #[inline]
166 pub(super) fn get_chunk(&self, chunk: usize) -> &[u8; N] {
167 assert!(
168 chunk < self.chunks.len(),
169 "chunk {} out of bounds (chunks: {})",
170 chunk,
171 self.chunks.len()
172 );
173 &self.chunks[chunk]
174 }
175
176 #[inline]
179 fn get_from_chunk(chunk: &[u8; N], bit: u64) -> bool {
180 let byte = Self::chunk_byte_offset(bit);
181 let byte = chunk[byte];
182 let mask = Self::chunk_byte_bitmask(bit);
183 (byte & mask) != 0
184 }
185
186 #[inline]
192 fn last_chunk(&self) -> (&[u8; N], u64) {
193 let rem = self.len % Self::CHUNK_SIZE_BITS;
194 let bits_in_last_chunk = if rem == 0 { Self::CHUNK_SIZE_BITS } else { rem };
195 (self.chunks.back().unwrap(), bits_in_last_chunk)
196 }
197
198 pub fn push(&mut self, bit: bool) {
202 if self.is_chunk_aligned() {
204 self.chunks.push_back(Self::EMPTY_CHUNK);
205 }
206
207 if bit {
209 let last_chunk = self.chunks.back_mut().unwrap();
210 let chunk_byte = Self::chunk_byte_offset(self.len);
211 last_chunk[chunk_byte] |= Self::chunk_byte_bitmask(self.len);
212 }
213 self.len += 1;
215 }
216
217 pub fn pop(&mut self) -> bool {
223 assert!(!self.is_empty(), "Cannot pop from empty bitmap");
224
225 let last_bit_pos = self.len - 1;
227 let bit = Self::get_from_chunk(self.chunks.back().unwrap(), last_bit_pos);
228
229 self.len -= 1;
231
232 if bit {
234 let pos_in_chunk = last_bit_pos % Self::CHUNK_SIZE_BITS;
235 let chunk_byte = (pos_in_chunk / 8) as usize;
236 let mask = Self::chunk_byte_bitmask(last_bit_pos);
237 self.chunks.back_mut().unwrap()[chunk_byte] &= !mask;
238 }
239
240 if self.is_chunk_aligned() {
242 self.chunks.pop_back();
243 }
244
245 bit
246 }
247
248 pub(super) fn pop_chunk(&mut self) -> [u8; N] {
254 assert!(
255 self.len() >= Self::CHUNK_SIZE_BITS,
256 "cannot pop chunk: bitmap has fewer than CHUNK_SIZE_BITS bits"
257 );
258 assert!(
259 self.is_chunk_aligned(),
260 "cannot pop chunk when not chunk aligned"
261 );
262
263 let chunk = self.chunks.pop_back().expect("chunk must exist");
265 self.len -= Self::CHUNK_SIZE_BITS;
266 chunk
267 }
268
269 #[inline]
275 pub fn flip(&mut self, bit: u64) {
276 self.assert_bit(bit);
277 let chunk = Self::chunk(bit);
278 let byte = Self::chunk_byte_offset(bit);
279 let mask = Self::chunk_byte_bitmask(bit);
280 self.chunks[chunk][byte] ^= mask;
281 }
282
283 pub fn flip_all(&mut self) {
285 for chunk in &mut self.chunks {
286 for byte in chunk {
287 *byte = !*byte;
288 }
289 }
290 self.clear_trailing_bits();
292 }
293
294 pub fn set(&mut self, bit: u64, value: bool) {
300 assert!(
301 bit < self.len(),
302 "bit {} out of bounds (len: {})",
303 bit,
304 self.len()
305 );
306
307 let chunk = &mut self.chunks[Self::chunk(bit)];
308 let byte = Self::chunk_byte_offset(bit);
309 let mask = Self::chunk_byte_bitmask(bit);
310 if value {
311 chunk[byte] |= mask;
312 } else {
313 chunk[byte] &= !mask;
314 }
315 }
316
317 #[inline]
319 pub fn set_all(&mut self, bit: bool) {
320 let value = if bit { u8::MAX } else { 0 };
321 for chunk in &mut self.chunks {
322 chunk.fill(value);
323 }
324 if bit {
326 self.clear_trailing_bits();
327 }
328 }
329
330 fn push_byte(&mut self, byte: u8) {
336 assert!(
337 self.len.is_multiple_of(8),
338 "cannot add byte when not byte aligned"
339 );
340
341 if self.is_chunk_aligned() {
343 self.chunks.push_back(Self::EMPTY_CHUNK);
344 }
345
346 let chunk_byte = Self::chunk_byte_offset(self.len);
347 self.chunks.back_mut().unwrap()[chunk_byte] = byte;
348 self.len += 8;
349 }
350
351 pub fn push_chunk(&mut self, chunk: &[u8; N]) {
357 assert!(
358 self.is_chunk_aligned(),
359 "cannot add chunk when not chunk aligned"
360 );
361 self.chunks.push_back(*chunk);
362 self.len += Self::CHUNK_SIZE_BITS;
363 }
364
365 fn clear_trailing_bits(&mut self) -> bool {
370 if self.chunks.is_empty() {
371 return false;
372 }
373
374 let pos_in_chunk = self.len % Self::CHUNK_SIZE_BITS;
375 if pos_in_chunk == 0 {
376 return false;
378 }
379
380 let mut flipped_any = false;
381 let last_chunk = self.chunks.back_mut().unwrap();
382
383 let last_byte_index = ((pos_in_chunk - 1) / 8) as usize;
385 for byte in last_chunk.iter_mut().skip(last_byte_index + 1) {
386 if *byte != 0 {
387 flipped_any = true;
388 *byte = 0;
389 }
390 }
391
392 let bits_in_last_byte = pos_in_chunk % 8;
394 if bits_in_last_byte != 0 {
395 let mask = (1u8 << bits_in_last_byte) - 1;
396 let old_byte = last_chunk[last_byte_index];
397 let new_byte = old_byte & mask;
398 if old_byte != new_byte {
399 flipped_any = true;
400 last_chunk[last_byte_index] = new_byte;
401 }
402 }
403
404 flipped_any
405 }
406
407 fn prune_chunks(&mut self, chunks: usize) {
415 assert!(
416 chunks <= self.chunks.len(),
417 "cannot prune {chunks} chunks, only {} available",
418 self.chunks.len()
419 );
420 self.chunks.drain(..chunks);
421 let bits_removed = (chunks as u64) * Self::CHUNK_SIZE_BITS;
423 self.len = self.len.saturating_sub(bits_removed);
424 }
425
426 pub(super) fn prepend_chunk(&mut self, chunk: &[u8; N]) {
428 self.chunks.push_front(*chunk);
429 self.len += Self::CHUNK_SIZE_BITS;
430 }
431
432 pub(super) fn set_chunk_by_index(&mut self, chunk_index: usize, chunk_data: &[u8; N]) {
442 assert!(
443 chunk_index < self.chunks.len(),
444 "chunk index {chunk_index} out of bounds (chunks_len: {})",
445 self.chunks.len()
446 );
447 self.chunks[chunk_index].copy_from_slice(chunk_data);
448 }
449
450 #[inline]
454 pub fn count_ones(&self) -> u64 {
455 self.chunks
458 .iter()
459 .flat_map(|chunk| chunk.iter())
460 .map(|byte| byte.count_ones() as u64)
461 .sum()
462 }
463
464 #[inline]
466 pub fn count_zeros(&self) -> u64 {
467 self.len() - self.count_ones()
468 }
469
470 #[inline]
474 pub(super) fn chunk_byte_bitmask(bit: u64) -> u8 {
475 1 << (bit % 8)
476 }
477
478 #[inline]
480 pub(super) fn chunk_byte_offset(bit: u64) -> usize {
481 ((bit / 8) % N as u64) as usize
482 }
483
484 #[inline]
490 pub(super) fn chunk(bit: u64) -> usize {
491 let chunk = bit / Self::CHUNK_SIZE_BITS;
492 assert!(
493 chunk <= usize::MAX as u64,
494 "chunk overflow: {chunk} exceeds usize::MAX",
495 );
496 chunk as usize
497 }
498
499 pub fn iter(&self) -> Iterator<'_, N> {
503 Iterator {
504 bitmap: self,
505 pos: 0,
506 }
507 }
508
509 #[inline]
513 fn binary_op<F: Fn(u8, u8) -> u8>(&mut self, other: &BitMap<N>, op: F) {
514 self.assert_eq_len(other);
515 for (a_chunk, b_chunk) in self.chunks.iter_mut().zip(other.chunks.iter()) {
516 for (a_byte, b_byte) in a_chunk.iter_mut().zip(b_chunk.iter()) {
517 *a_byte = op(*a_byte, *b_byte);
518 }
519 }
520 self.clear_trailing_bits();
522 }
523
524 pub fn and(&mut self, other: &BitMap<N>) {
530 self.binary_op(other, |a, b| a & b);
531 }
532
533 pub fn or(&mut self, other: &BitMap<N>) {
539 self.binary_op(other, |a, b| a | b);
540 }
541
542 pub fn xor(&mut self, other: &BitMap<N>) {
548 self.binary_op(other, |a, b| a ^ b);
549 }
550
551 #[inline(always)]
555 fn assert_bit(&self, bit: u64) {
556 assert!(
557 bit < self.len(),
558 "bit {} out of bounds (len: {})",
559 bit,
560 self.len()
561 );
562 }
563
564 #[inline(always)]
566 fn assert_eq_len(&self, other: &BitMap<N>) {
567 assert_eq!(
568 self.len(),
569 other.len(),
570 "BitMap lengths don't match: {} vs {}",
571 self.len(),
572 other.len()
573 );
574 }
575}
576
577impl<const N: usize> Default for BitMap<N> {
578 fn default() -> Self {
579 Self::new()
580 }
581}
582
583impl<T: AsRef<[bool]>, const N: usize> From<T> for BitMap<N> {
584 fn from(t: T) -> Self {
585 let bools = t.as_ref();
586 let mut bv = Self::new();
587 for &b in bools {
588 bv.push(b);
589 }
590 bv
591 }
592}
593
594impl<const N: usize> From<BitMap<N>> for Vec<bool> {
595 fn from(bv: BitMap<N>) -> Self {
596 bv.iter().collect()
597 }
598}
599
600impl<const N: usize> fmt::Debug for BitMap<N> {
601 fn fmt(&self, f: &mut Formatter<'_>) -> core::fmt::Result {
602 const MAX_DISPLAY: u64 = 64;
604 const HALF_DISPLAY: u64 = MAX_DISPLAY / 2;
605
606 let write_bit = |formatter: &mut Formatter<'_>, bit: u64| -> core::fmt::Result {
608 formatter.write_char(if self.get(bit) { '1' } else { '0' })
609 };
610
611 f.write_str("BitMap[")?;
612 let len = self.len();
613 if len <= MAX_DISPLAY {
614 for i in 0..len {
616 write_bit(f, i)?;
617 }
618 } else {
619 for i in 0..HALF_DISPLAY {
621 write_bit(f, i)?;
622 }
623
624 f.write_str("...")?;
625
626 for i in (len - HALF_DISPLAY)..len {
627 write_bit(f, i)?;
628 }
629 }
630 f.write_str("]")
631 }
632}
633
634impl<const N: usize> Index<u64> for BitMap<N> {
635 type Output = bool;
636
637 #[inline]
641 fn index(&self, bit: u64) -> &Self::Output {
642 self.assert_bit(bit);
643 let value = self.get(bit);
644 if value {
645 &true
646 } else {
647 &false
648 }
649 }
650}
651
652impl<const N: usize> BitAnd for &BitMap<N> {
653 type Output = BitMap<N>;
654
655 fn bitand(self, rhs: Self) -> Self::Output {
656 self.assert_eq_len(rhs);
657 let mut result = self.clone();
658 result.and(rhs);
659 result
660 }
661}
662
663impl<const N: usize> BitOr for &BitMap<N> {
664 type Output = BitMap<N>;
665
666 fn bitor(self, rhs: Self) -> Self::Output {
667 self.assert_eq_len(rhs);
668 let mut result = self.clone();
669 result.or(rhs);
670 result
671 }
672}
673
674impl<const N: usize> BitXor for &BitMap<N> {
675 type Output = BitMap<N>;
676
677 fn bitxor(self, rhs: Self) -> Self::Output {
678 self.assert_eq_len(rhs);
679 let mut result = self.clone();
680 result.xor(rhs);
681 result
682 }
683}
684
685impl<const N: usize> Write for BitMap<N> {
686 fn write(&self, buf: &mut impl BufMut) {
687 self.len().write(buf);
689
690 for chunk in &self.chunks {
692 for &byte in chunk {
693 byte.write(buf);
694 }
695 }
696 }
697}
698
699impl<const N: usize> Read for BitMap<N> {
700 type Cfg = u64; fn read_cfg(buf: &mut impl Buf, max_len: &Self::Cfg) -> Result<Self, CodecError> {
703 let len = u64::read(buf)?;
705 if len > *max_len {
706 return Err(CodecError::InvalidLength(len as usize));
707 }
708
709 let num_chunks = len.div_ceil(Self::CHUNK_SIZE_BITS) as usize;
711
712 let mut chunks = VecDeque::with_capacity(num_chunks);
714 for _ in 0..num_chunks {
715 at_least(buf, N)?;
716 let mut chunk = [0u8; N];
717 buf.copy_to_slice(&mut chunk);
718 chunks.push_back(chunk);
719 }
720
721 let mut result = BitMap { chunks, len };
722
723 if result.clear_trailing_bits() {
725 return Err(CodecError::Invalid(
726 "BitMap",
727 "Invalid trailing bits in encoded data",
728 ));
729 }
730
731 Ok(result)
732 }
733}
734
735impl<const N: usize> EncodeSize for BitMap<N> {
736 fn encode_size(&self) -> usize {
737 self.len().encode_size() + (self.chunks.len() * N)
739 }
740}
741
742pub struct Iterator<'a, const N: usize> {
744 bitmap: &'a BitMap<N>,
746
747 pos: u64,
749}
750
751impl<const N: usize> core::iter::Iterator for Iterator<'_, N> {
752 type Item = bool;
753
754 fn next(&mut self) -> Option<Self::Item> {
755 if self.pos >= self.bitmap.len() {
756 return None;
757 }
758
759 let bit = self.bitmap.get(self.pos);
760 self.pos += 1;
761 Some(bit)
762 }
763
764 fn size_hint(&self) -> (usize, Option<usize>) {
765 let remaining = self.bitmap.len().saturating_sub(self.pos);
766 let capped = remaining.min(usize::MAX as u64) as usize;
767 (capped, Some(capped))
768 }
769}
770
771impl<const N: usize> ExactSizeIterator for Iterator<'_, N> {}
772
773#[cfg(test)]
774mod tests {
775 use super::*;
776 use crate::hex;
777 use bytes::BytesMut;
778 use commonware_codec::{Decode, Encode};
779
780 #[test]
781 fn test_constructors() {
782 let bv: BitMap<4> = BitMap::new();
784 assert_eq!(bv.len(), 0);
785 assert!(bv.is_empty());
786
787 let bv: BitMap<4> = Default::default();
789 assert_eq!(bv.len(), 0);
790 assert!(bv.is_empty());
791
792 let bv: BitMap<4> = BitMap::with_capacity(0);
794 assert_eq!(bv.len(), 0);
795 assert!(bv.is_empty());
796
797 let bv: BitMap<4> = BitMap::with_capacity(10);
798 assert_eq!(bv.len(), 0);
799 assert!(bv.is_empty());
800 }
801
802 #[test]
803 fn test_zeroes() {
804 let bv: BitMap<1> = BitMap::zeroes(0);
805 assert_eq!(bv.len(), 0);
806 assert!(bv.is_empty());
807 assert_eq!(bv.count_ones(), 0);
808 assert_eq!(bv.count_zeros(), 0);
809
810 let bv: BitMap<1> = BitMap::zeroes(1);
811 assert_eq!(bv.len(), 1);
812 assert!(!bv.is_empty());
813 assert_eq!(bv.len(), 1);
814 assert!(!bv.get(0));
815 assert_eq!(bv.count_ones(), 0);
816 assert_eq!(bv.count_zeros(), 1);
817
818 let bv: BitMap<1> = BitMap::zeroes(10);
819 assert_eq!(bv.len(), 10);
820 assert!(!bv.is_empty());
821 assert_eq!(bv.len(), 10);
822 for i in 0..10 {
823 assert!(!bv.get(i as u64));
824 }
825 assert_eq!(bv.count_ones(), 0);
826 assert_eq!(bv.count_zeros(), 10);
827 }
828
829 #[test]
830 fn test_ones() {
831 let bv: BitMap<1> = BitMap::ones(0);
832 assert_eq!(bv.len(), 0);
833 assert!(bv.is_empty());
834 assert_eq!(bv.count_ones(), 0);
835 assert_eq!(bv.count_zeros(), 0);
836
837 let bv: BitMap<1> = BitMap::ones(1);
838 assert_eq!(bv.len(), 1);
839 assert!(!bv.is_empty());
840 assert_eq!(bv.len(), 1);
841 assert!(bv.get(0));
842 assert_eq!(bv.count_ones(), 1);
843 assert_eq!(bv.count_zeros(), 0);
844
845 let bv: BitMap<1> = BitMap::ones(10);
846 assert_eq!(bv.len(), 10);
847 assert!(!bv.is_empty());
848 assert_eq!(bv.len(), 10);
849 for i in 0..10 {
850 assert!(bv.get(i as u64));
851 }
852 assert_eq!(bv.count_ones(), 10);
853 assert_eq!(bv.count_zeros(), 0);
854 }
855
856 #[test]
857 fn test_invariant_trailing_bits_are_zero() {
858 fn check_trailing_bits_zero<const N: usize>(bitmap: &BitMap<N>) {
860 let (last_chunk, next_bit) = bitmap.last_chunk();
861
862 for bit_idx in next_bit..((N * 8) as u64) {
864 let byte_idx = (bit_idx / 8) as usize;
865 let bit_in_byte = bit_idx % 8;
866 let mask = 1u8 << bit_in_byte;
867 assert_eq!(last_chunk[byte_idx] & mask, 0);
868 }
869 }
870
871 let bv: BitMap<4> = BitMap::ones(15);
873 check_trailing_bits_zero(&bv);
874
875 let bv: BitMap<4> = BitMap::ones(33);
876 check_trailing_bits_zero(&bv);
877
878 let mut bv: BitMap<4> = BitMap::new();
880 for i in 0..37 {
881 bv.push(i % 2 == 0);
882 check_trailing_bits_zero(&bv);
883 }
884
885 let mut bv: BitMap<4> = BitMap::ones(40);
887 check_trailing_bits_zero(&bv);
888 for _ in 0..15 {
889 bv.pop();
890 check_trailing_bits_zero(&bv);
891 }
892
893 let mut bv: BitMap<4> = BitMap::ones(25);
895 bv.flip_all();
896 check_trailing_bits_zero(&bv);
897
898 let bv1: BitMap<4> = BitMap::ones(20);
900 let bv2: BitMap<4> = BitMap::zeroes(20);
901
902 let mut bv_and = bv1.clone();
903 bv_and.and(&bv2);
904 check_trailing_bits_zero(&bv_and);
905
906 let mut bv_or = bv1.clone();
907 bv_or.or(&bv2);
908 check_trailing_bits_zero(&bv_or);
909
910 let mut bv_xor = bv1.clone();
911 bv_xor.xor(&bv2);
912 check_trailing_bits_zero(&bv_xor);
913
914 let original: BitMap<4> = BitMap::ones(27);
916 let encoded = original.encode();
917 let decoded: BitMap<4> =
918 BitMap::decode_cfg(&mut encoded.as_ref(), &(usize::MAX as u64)).unwrap();
919 check_trailing_bits_zero(&decoded);
920
921 let mut bv_clean: BitMap<4> = BitMap::ones(20);
923 assert!(!bv_clean.clear_trailing_bits());
925
926 let mut bv_dirty: BitMap<4> = BitMap::ones(20);
928 let last_chunk = bv_dirty.chunks.back_mut().unwrap();
930 last_chunk[3] |= 0xF0; assert!(bv_dirty.clear_trailing_bits());
933 assert!(!bv_dirty.clear_trailing_bits());
935 check_trailing_bits_zero(&bv_dirty);
936 }
937
938 #[test]
939 fn test_get_set() {
940 let mut bv: BitMap<4> = BitMap::new();
941
942 assert_eq!(bv.len(), 0);
944 assert!(bv.is_empty());
945
946 bv.push(true);
948 bv.push(false);
949 bv.push(true);
950 assert_eq!(bv.len(), 3);
951 assert!(!bv.is_empty());
952
953 assert!(bv.get(0));
955 assert!(!bv.get(1));
956 assert!(bv.get(2));
957
958 bv.set(1, true);
959 assert!(bv.get(1));
960 bv.set(2, false);
961 assert!(!bv.get(2));
962
963 bv.flip(0); assert!(!bv.get(0));
966 bv.flip(0); assert!(bv.get(0));
968 }
969
970 #[test]
971 fn test_chunk_operations() {
972 let mut bv: BitMap<4> = BitMap::new();
973 let test_chunk = hex!("0xABCDEF12");
974
975 bv.push_chunk(&test_chunk);
977 assert_eq!(bv.len(), 32); let chunk = bv.get_chunk(0);
981 assert_eq!(chunk, &test_chunk);
982
983 let chunk = bv.get_chunk_containing(0);
985 assert_eq!(chunk, &test_chunk);
986
987 let (last_chunk, next_bit) = bv.last_chunk();
989 assert_eq!(next_bit, BitMap::<4>::CHUNK_SIZE_BITS); assert_eq!(last_chunk, &test_chunk); }
992
993 #[test]
994 fn test_pop() {
995 let mut bv: BitMap<3> = BitMap::new();
996 bv.push(true);
997 assert!(bv.pop());
998 assert_eq!(bv.len(), 0);
999
1000 bv.push(false);
1001 assert!(!bv.pop());
1002 assert_eq!(bv.len(), 0);
1003
1004 bv.push(true);
1005 bv.push(false);
1006 bv.push(true);
1007 assert!(bv.pop());
1008 assert_eq!(bv.len(), 2);
1009 assert!(!bv.pop());
1010 assert_eq!(bv.len(), 1);
1011 assert!(bv.pop());
1012 assert_eq!(bv.len(), 0);
1013
1014 for i in 0..100 {
1015 bv.push(i % 2 == 0);
1016 }
1017 assert_eq!(bv.len(), 100);
1018 for i in (0..100).rev() {
1019 assert_eq!(bv.pop(), i % 2 == 0);
1020 }
1021 assert_eq!(bv.len(), 0);
1022 assert!(bv.is_empty());
1023 }
1024
1025 #[test]
1026 fn test_pop_chunk() {
1027 let mut bv: BitMap<3> = BitMap::new();
1028 const CHUNK_SIZE: u64 = BitMap::<3>::CHUNK_SIZE_BITS;
1029
1030 let chunk1 = hex!("0xAABBCC");
1032 bv.push_chunk(&chunk1);
1033 assert_eq!(bv.len(), CHUNK_SIZE);
1034 let popped = bv.pop_chunk();
1035 assert_eq!(popped, chunk1);
1036 assert_eq!(bv.len(), 0);
1037 assert!(bv.is_empty());
1038
1039 let chunk2 = hex!("0x112233");
1041 let chunk3 = hex!("0x445566");
1042 let chunk4 = hex!("0x778899");
1043
1044 bv.push_chunk(&chunk2);
1045 bv.push_chunk(&chunk3);
1046 bv.push_chunk(&chunk4);
1047 assert_eq!(bv.len(), CHUNK_SIZE * 3);
1048
1049 assert_eq!(bv.pop_chunk(), chunk4);
1050 assert_eq!(bv.len(), CHUNK_SIZE * 2);
1051
1052 assert_eq!(bv.pop_chunk(), chunk3);
1053 assert_eq!(bv.len(), CHUNK_SIZE);
1054
1055 assert_eq!(bv.pop_chunk(), chunk2);
1056 assert_eq!(bv.len(), 0);
1057
1058 let first_chunk = hex!("0xAABBCC");
1060 let second_chunk = hex!("0x112233");
1061 bv.push_chunk(&first_chunk);
1062 bv.push_chunk(&second_chunk);
1063
1064 assert_eq!(bv.pop_chunk(), second_chunk);
1066 assert_eq!(bv.len(), CHUNK_SIZE);
1067
1068 for i in 0..CHUNK_SIZE {
1069 let byte_idx = (i / 8) as usize;
1070 let bit_idx = i % 8;
1071 let expected = (first_chunk[byte_idx] >> bit_idx) & 1 == 1;
1072 assert_eq!(bv.get(i), expected);
1073 }
1074
1075 assert_eq!(bv.pop_chunk(), first_chunk);
1076 assert_eq!(bv.len(), 0);
1077 }
1078
1079 #[test]
1080 #[should_panic(expected = "cannot pop chunk when not chunk aligned")]
1081 fn test_pop_chunk_not_aligned() {
1082 let mut bv: BitMap<3> = BitMap::new();
1083
1084 bv.push_chunk(&[0xFF; 3]);
1086 bv.push(true);
1087
1088 bv.pop_chunk();
1090 }
1091
1092 #[test]
1093 #[should_panic(expected = "cannot pop chunk: bitmap has fewer than CHUNK_SIZE_BITS bits")]
1094 fn test_pop_chunk_insufficient_bits() {
1095 let mut bv: BitMap<3> = BitMap::new();
1096
1097 bv.push(true);
1099 bv.push(false);
1100
1101 bv.pop_chunk();
1103 }
1104
1105 #[test]
1106 fn test_byte_operations() {
1107 let mut bv: BitMap<4> = BitMap::new();
1108
1109 bv.push_byte(0xFF);
1111 assert_eq!(bv.len(), 8);
1112
1113 for i in 0..8 {
1115 assert!(bv.get(i as u64));
1116 }
1117
1118 bv.push_byte(0x00);
1119 assert_eq!(bv.len(), 16);
1120
1121 for i in 8..16 {
1123 assert!(!bv.get(i as u64));
1124 }
1125 }
1126
1127 #[test]
1128 fn test_count_operations() {
1129 let mut bv: BitMap<4> = BitMap::new();
1130
1131 assert_eq!(bv.count_ones(), 0);
1133 assert_eq!(bv.count_zeros(), 0);
1134
1135 bv.push(true);
1137 bv.push(false);
1138 bv.push(true);
1139 bv.push(true);
1140 bv.push(false);
1141
1142 assert_eq!(bv.count_ones(), 3);
1143 assert_eq!(bv.count_zeros(), 2);
1144 assert_eq!(bv.len(), 5);
1145
1146 let mut bv2: BitMap<4> = BitMap::new();
1148 bv2.push_byte(0xFF); bv2.push_byte(0x00); bv2.push_byte(0xAA); assert_eq!(bv2.count_ones(), 12);
1153 assert_eq!(bv2.count_zeros(), 12);
1154 assert_eq!(bv2.len(), 24);
1155 }
1156
1157 #[test]
1158 fn test_set_all() {
1159 let mut bv: BitMap<1> = BitMap::new();
1160
1161 bv.push(true);
1163 bv.push(false);
1164 bv.push(true);
1165 bv.push(false);
1166 bv.push(true);
1167 bv.push(false);
1168 bv.push(true);
1169 bv.push(false);
1170 bv.push(true);
1171 bv.push(false);
1172
1173 assert_eq!(bv.len(), 10);
1174 assert_eq!(bv.count_ones(), 5);
1175 assert_eq!(bv.count_zeros(), 5);
1176
1177 bv.set_all(true);
1179 assert_eq!(bv.len(), 10);
1180 assert_eq!(bv.count_ones(), 10);
1181 assert_eq!(bv.count_zeros(), 0);
1182
1183 bv.set_all(false);
1185 assert_eq!(bv.len(), 10);
1186 assert_eq!(bv.count_ones(), 0);
1187 assert_eq!(bv.count_zeros(), 10);
1188 }
1189
1190 #[test]
1191 fn test_flip_all() {
1192 let mut bv: BitMap<4> = BitMap::new();
1193
1194 bv.push(true);
1195 bv.push(false);
1196 bv.push(true);
1197 bv.push(false);
1198 bv.push(true);
1199
1200 let original_ones = bv.count_ones();
1201 let original_zeros = bv.count_zeros();
1202 let original_len = bv.len();
1203
1204 bv.flip_all();
1205
1206 assert_eq!(bv.len(), original_len);
1208
1209 assert_eq!(bv.count_ones(), original_zeros);
1211 assert_eq!(bv.count_zeros(), original_ones);
1212
1213 assert!(!bv.get(0));
1215 assert!(bv.get(1));
1216 assert!(!bv.get(2));
1217 assert!(bv.get(3));
1218 assert!(!bv.get(4));
1219 }
1220
1221 #[test]
1222 fn test_bitwise_and() {
1223 let mut bv1: BitMap<4> = BitMap::new();
1224 let mut bv2: BitMap<4> = BitMap::new();
1225
1226 let pattern1 = [true, false, true, true, false];
1228 let pattern2 = [true, true, false, true, false];
1229 let expected = [true, false, false, true, false];
1230
1231 for &bit in &pattern1 {
1232 bv1.push(bit);
1233 }
1234 for &bit in &pattern2 {
1235 bv2.push(bit);
1236 }
1237
1238 bv1.and(&bv2);
1239
1240 assert_eq!(bv1.len(), 5);
1241 for (i, &expected_bit) in expected.iter().enumerate() {
1242 assert_eq!(bv1.get(i as u64), expected_bit);
1243 }
1244 }
1245
1246 #[test]
1247 fn test_bitwise_or() {
1248 let mut bv1: BitMap<4> = BitMap::new();
1249 let mut bv2: BitMap<4> = BitMap::new();
1250
1251 let pattern1 = [true, false, true, true, false];
1253 let pattern2 = [true, true, false, true, false];
1254 let expected = [true, true, true, true, false];
1255
1256 for &bit in &pattern1 {
1257 bv1.push(bit);
1258 }
1259 for &bit in &pattern2 {
1260 bv2.push(bit);
1261 }
1262
1263 bv1.or(&bv2);
1264
1265 assert_eq!(bv1.len(), 5);
1266 for (i, &expected_bit) in expected.iter().enumerate() {
1267 assert_eq!(bv1.get(i as u64), expected_bit);
1268 }
1269 }
1270
1271 #[test]
1272 fn test_bitwise_xor() {
1273 let mut bv1: BitMap<4> = BitMap::new();
1274 let mut bv2: BitMap<4> = BitMap::new();
1275
1276 let pattern1 = [true, false, true, true, false];
1278 let pattern2 = [true, true, false, true, false];
1279 let expected = [false, true, true, false, false];
1280
1281 for &bit in &pattern1 {
1282 bv1.push(bit);
1283 }
1284 for &bit in &pattern2 {
1285 bv2.push(bit);
1286 }
1287
1288 bv1.xor(&bv2);
1289
1290 assert_eq!(bv1.len(), 5);
1291 for (i, &expected_bit) in expected.iter().enumerate() {
1292 assert_eq!(bv1.get(i as u64), expected_bit);
1293 }
1294 }
1295
1296 #[test]
1297 fn test_multi_chunk_operations() {
1298 let mut bv1: BitMap<4> = BitMap::new();
1299 let mut bv2: BitMap<4> = BitMap::new();
1300
1301 let chunk1 = hex!("0xAABBCCDD"); let chunk2 = hex!("0x55667788"); bv1.push_chunk(&chunk1);
1306 bv1.push_chunk(&chunk1);
1307 bv2.push_chunk(&chunk2);
1308 bv2.push_chunk(&chunk2);
1309
1310 assert_eq!(bv1.len(), 64);
1311 assert_eq!(bv2.len(), 64);
1312
1313 let mut bv_and = bv1.clone();
1315 bv_and.and(&bv2);
1316
1317 let mut bv_or = bv1.clone();
1319 bv_or.or(&bv2);
1320
1321 let mut bv_xor = bv1.clone();
1323 bv_xor.xor(&bv2);
1324
1325 assert_eq!(bv_and.len(), 64);
1327 assert_eq!(bv_or.len(), 64);
1328 assert_eq!(bv_xor.len(), 64);
1329
1330 assert!(bv_and.count_ones() <= bv1.count_ones());
1332 assert!(bv_and.count_ones() <= bv2.count_ones());
1333
1334 assert!(bv_or.count_ones() >= bv1.count_ones());
1336 assert!(bv_or.count_ones() >= bv2.count_ones());
1337 }
1338
1339 #[test]
1340 fn test_partial_chunk_operations() {
1341 let mut bv1: BitMap<4> = BitMap::new();
1342 let mut bv2: BitMap<4> = BitMap::new();
1343
1344 for i in 0..35 {
1346 bv1.push(i % 2 == 0);
1348 bv2.push(i % 3 == 0);
1349 }
1350
1351 assert_eq!(bv1.len(), 35);
1352 assert_eq!(bv2.len(), 35);
1353
1354 let mut bv_and = bv1.clone();
1356 bv_and.and(&bv2);
1357
1358 let mut bv_or = bv1.clone();
1359 bv_or.or(&bv2);
1360
1361 let mut bv_xor = bv1.clone();
1362 bv_xor.xor(&bv2);
1363
1364 assert_eq!(bv_and.len(), 35);
1366 assert_eq!(bv_or.len(), 35);
1367 assert_eq!(bv_xor.len(), 35);
1368
1369 let mut bv_inv = bv1.clone();
1371 let original_ones = bv_inv.count_ones();
1372 let original_zeros = bv_inv.count_zeros();
1373 bv_inv.flip_all();
1374 assert_eq!(bv_inv.count_ones(), original_zeros);
1375 assert_eq!(bv_inv.count_zeros(), original_ones);
1376 }
1377
1378 #[test]
1379 #[should_panic(expected = "bit 1 out of bounds (len: 1)")]
1380 fn test_flip_out_of_bounds() {
1381 let mut bv: BitMap<4> = BitMap::new();
1382 bv.push(true);
1383 bv.flip(1); }
1385
1386 #[test]
1387 #[should_panic(expected = "BitMap lengths don't match: 2 vs 1")]
1388 fn test_and_length_mismatch() {
1389 let mut bv1: BitMap<4> = BitMap::new();
1390 let mut bv2: BitMap<4> = BitMap::new();
1391
1392 bv1.push(true);
1393 bv1.push(false);
1394 bv2.push(true); bv1.and(&bv2);
1397 }
1398
1399 #[test]
1400 #[should_panic(expected = "BitMap lengths don't match: 1 vs 2")]
1401 fn test_or_length_mismatch() {
1402 let mut bv1: BitMap<4> = BitMap::new();
1403 let mut bv2: BitMap<4> = BitMap::new();
1404
1405 bv1.push(true);
1406 bv2.push(true);
1407 bv2.push(false); bv1.or(&bv2);
1410 }
1411
1412 #[test]
1413 #[should_panic(expected = "BitMap lengths don't match: 3 vs 2")]
1414 fn test_xor_length_mismatch() {
1415 let mut bv1: BitMap<4> = BitMap::new();
1416 let mut bv2: BitMap<4> = BitMap::new();
1417
1418 bv1.push(true);
1419 bv1.push(false);
1420 bv1.push(true);
1421 bv2.push(true);
1422 bv2.push(false); bv1.xor(&bv2);
1425 }
1426
1427 #[test]
1428 fn test_equality() {
1429 assert_eq!(BitMap::<4>::new(), BitMap::<4>::new());
1431 assert_eq!(BitMap::<8>::new(), BitMap::<8>::new());
1432
1433 let pattern = [true, false, true, true, false, false, true, false, true];
1435 let bv4: BitMap<4> = pattern.as_ref().into();
1436 assert_eq!(bv4, BitMap::<4>::from(pattern.as_ref()));
1437 let bv8: BitMap<8> = pattern.as_ref().into();
1438 assert_eq!(bv8, BitMap::<8>::from(pattern.as_ref()));
1439
1440 let mut bv1: BitMap<4> = BitMap::new();
1442 let mut bv2: BitMap<4> = BitMap::new();
1443 for i in 0..33 {
1444 let bit = i % 3 == 0;
1445 bv1.push(bit);
1446 bv2.push(bit);
1447 }
1448 assert_eq!(bv1, bv2);
1449
1450 bv1.push(true);
1452 assert_ne!(bv1, bv2);
1453 bv1.pop(); assert_eq!(bv1, bv2);
1455
1456 bv1.flip(15);
1458 assert_ne!(bv1, bv2);
1459 bv1.flip(15); assert_eq!(bv1, bv2);
1461
1462 let mut bv_ops1 = BitMap::<16>::ones(25);
1464 let mut bv_ops2 = BitMap::<16>::ones(25);
1465 bv_ops1.flip_all();
1466 bv_ops2.flip_all();
1467 assert_eq!(bv_ops1, bv_ops2);
1468
1469 let mask_bits: Vec<bool> = (0..33).map(|i| i % 3 == 0).collect();
1470 let mask = BitMap::<4>::from(mask_bits);
1471 bv1.and(&mask);
1472 bv2.and(&mask);
1473 assert_eq!(bv1, bv2);
1474 }
1475
1476 #[test]
1477 fn test_different_chunk_sizes() {
1478 let mut bv8: BitMap<8> = BitMap::new();
1480 let mut bv16: BitMap<16> = BitMap::new();
1481 let mut bv32: BitMap<32> = BitMap::new();
1482
1483 let chunk8 = [0xFF; 8];
1485 let chunk16 = [0xAA; 16];
1486 let chunk32 = [0x55; 32];
1487
1488 bv8.push_chunk(&chunk8);
1489 bv16.push_chunk(&chunk16);
1490 bv32.push_chunk(&chunk32);
1491
1492 bv8.push(true);
1494 bv8.push(false);
1495 assert_eq!(bv8.len(), 64 + 2);
1496 assert_eq!(bv8.count_ones(), 64 + 1); assert_eq!(bv8.count_zeros(), 1);
1498
1499 bv16.push(true);
1500 bv16.push(false);
1501 assert_eq!(bv16.len(), 128 + 2);
1502 assert_eq!(bv16.count_ones(), 64 + 1); assert_eq!(bv16.count_zeros(), 64 + 1);
1504
1505 bv32.push(true);
1506 bv32.push(false);
1507 assert_eq!(bv32.len(), 256 + 2);
1508 assert_eq!(bv32.count_ones(), 128 + 1); assert_eq!(bv32.count_zeros(), 128 + 1);
1510 }
1511
1512 #[test]
1513 fn test_iterator() {
1514 let bv: BitMap<4> = BitMap::new();
1516 let mut iter = bv.iter();
1517 assert_eq!(iter.next(), None);
1518 assert_eq!(iter.size_hint(), (0, Some(0)));
1519
1520 let pattern = [true, false, true, false, true];
1522 let bv: BitMap<4> = pattern.as_ref().into();
1523
1524 let collected: Vec<bool> = bv.iter().collect();
1526 assert_eq!(collected, pattern);
1527
1528 let mut iter = bv.iter();
1530 assert_eq!(iter.size_hint(), (5, Some(5)));
1531
1532 assert_eq!(iter.next(), Some(true));
1534 assert_eq!(iter.size_hint(), (4, Some(4)));
1535
1536 let iter = bv.iter();
1538 assert_eq!(iter.len(), 5);
1539
1540 let mut large_bv: BitMap<8> = BitMap::new();
1542 for i in 0..100 {
1543 large_bv.push(i % 3 == 0);
1544 }
1545
1546 let collected: Vec<bool> = large_bv.iter().collect();
1547 assert_eq!(collected.len(), 100);
1548 for (i, &bit) in collected.iter().enumerate() {
1549 assert_eq!(bit, i % 3 == 0);
1550 }
1551 }
1552
1553 #[test]
1554 fn test_iterator_edge_cases() {
1555 let mut bv: BitMap<4> = BitMap::new();
1557 bv.push(true);
1558
1559 let collected: Vec<bool> = bv.iter().collect();
1560 assert_eq!(collected, vec![true]);
1561
1562 let mut bv: BitMap<4> = BitMap::new();
1564 for i in 0..32 {
1566 bv.push(i % 2 == 0);
1567 }
1568 bv.push(true);
1570 bv.push(false);
1571 bv.push(true);
1572
1573 let collected: Vec<bool> = bv.iter().collect();
1574 assert_eq!(collected.len(), 35);
1575
1576 for (i, &bit) in collected.iter().enumerate().take(32) {
1578 assert_eq!(bit, i % 2 == 0);
1579 }
1580 assert!(collected[32]);
1581 assert!(!collected[33]);
1582 assert!(collected[34]);
1583 }
1584
1585 #[test]
1586 fn test_codec_roundtrip() {
1587 let original: BitMap<4> = BitMap::new();
1589 let encoded = original.encode();
1590 let decoded = BitMap::decode_cfg(&mut encoded.as_ref(), &(usize::MAX as u64)).unwrap();
1591 assert_eq!(original, decoded);
1592
1593 let pattern = [true, false, true, false, true];
1595 let original: BitMap<4> = pattern.as_ref().into();
1596 let encoded = original.encode();
1597 let decoded = BitMap::decode_cfg(&mut encoded.as_ref(), &(usize::MAX as u64)).unwrap();
1598 assert_eq!(original, decoded);
1599
1600 for (i, &expected) in pattern.iter().enumerate() {
1602 assert_eq!(decoded.get(i as u64), expected);
1603 }
1604
1605 let mut large_original: BitMap<8> = BitMap::new();
1607 for i in 0..100 {
1608 large_original.push(i % 7 == 0);
1609 }
1610
1611 let encoded = large_original.encode();
1612 let decoded = BitMap::decode_cfg(&mut encoded.as_ref(), &(usize::MAX as u64)).unwrap();
1613 assert_eq!(large_original, decoded);
1614
1615 assert_eq!(decoded.len(), 100);
1617 for i in 0..100 {
1618 assert_eq!(decoded.get(i as u64), i % 7 == 0);
1619 }
1620 }
1621
1622 #[test]
1623 fn test_codec_different_chunk_sizes() {
1624 let pattern = [true, false, true, true, false, false, true];
1625
1626 let bv4: BitMap<4> = pattern.as_ref().into();
1628 let bv8: BitMap<8> = pattern.as_ref().into();
1629 let bv16: BitMap<16> = pattern.as_ref().into();
1630
1631 let encoded4 = bv4.encode();
1633 let decoded4 = BitMap::decode_cfg(&mut encoded4.as_ref(), &(usize::MAX as u64)).unwrap();
1634 assert_eq!(bv4, decoded4);
1635
1636 let encoded8 = bv8.encode();
1637 let decoded8 = BitMap::decode_cfg(&mut encoded8.as_ref(), &(usize::MAX as u64)).unwrap();
1638 assert_eq!(bv8, decoded8);
1639
1640 let encoded16 = bv16.encode();
1641 let decoded16 = BitMap::decode_cfg(&mut encoded16.as_ref(), &(usize::MAX as u64)).unwrap();
1642 assert_eq!(bv16, decoded16);
1643
1644 for (i, &expected) in pattern.iter().enumerate() {
1646 let i = i as u64;
1647 assert_eq!(decoded4.get(i), expected);
1648 assert_eq!(decoded8.get(i), expected);
1649 assert_eq!(decoded16.get(i), expected);
1650 }
1651 }
1652
1653 #[test]
1654 fn test_codec_edge_cases() {
1655 let mut bv: BitMap<4> = BitMap::new();
1657 for i in 0..32 {
1658 bv.push(i % 2 == 0);
1659 }
1660
1661 let encoded = bv.encode();
1662 let decoded = BitMap::decode_cfg(&mut encoded.as_ref(), &(usize::MAX as u64)).unwrap();
1663 assert_eq!(bv, decoded);
1664 assert_eq!(decoded.len(), 32);
1665
1666 let mut bv2: BitMap<4> = BitMap::new();
1668 for i in 0..35 {
1669 bv2.push(i % 3 == 0);
1671 }
1672
1673 let encoded2 = bv2.encode();
1674 let decoded2 = BitMap::decode_cfg(&mut encoded2.as_ref(), &(usize::MAX as u64)).unwrap();
1675 assert_eq!(bv2, decoded2);
1676 assert_eq!(decoded2.len(), 35);
1677 }
1678
1679 #[test]
1680 fn test_encode_size() {
1681 let bv: BitMap<4> = BitMap::new();
1683 let encoded = bv.encode();
1684 assert_eq!(bv.encode_size(), encoded.len());
1685
1686 let pattern = [true, false, true, false, true];
1688 let bv: BitMap<4> = pattern.as_ref().into();
1689 let encoded = bv.encode();
1690 assert_eq!(bv.encode_size(), encoded.len());
1691
1692 let mut large_bv: BitMap<8> = BitMap::new();
1694 for i in 0..100 {
1695 large_bv.push(i % 2 == 0);
1696 }
1697 let encoded = large_bv.encode();
1698 assert_eq!(large_bv.encode_size(), encoded.len());
1699 }
1700
1701 #[test]
1702 fn test_codec_empty_chunk_optimization() {
1703 let bv_empty: BitMap<4> = BitMap::new();
1707 let encoded_empty = bv_empty.encode();
1708 let decoded_empty: BitMap<4> =
1709 BitMap::decode_cfg(&mut encoded_empty.as_ref(), &(usize::MAX as u64)).unwrap();
1710 assert_eq!(bv_empty, decoded_empty);
1711 assert_eq!(bv_empty.len(), decoded_empty.len());
1712 assert_eq!(encoded_empty.len(), bv_empty.len().encode_size());
1714
1715 let mut bv_exact: BitMap<4> = BitMap::new();
1717 for _ in 0..32 {
1718 bv_exact.push(true);
1719 }
1720 let encoded_exact = bv_exact.encode();
1721 let decoded_exact: BitMap<4> =
1722 BitMap::decode_cfg(&mut encoded_exact.as_ref(), &(usize::MAX as u64)).unwrap();
1723 assert_eq!(bv_exact, decoded_exact);
1724
1725 let mut bv_partial: BitMap<4> = BitMap::new();
1727 for _ in 0..35 {
1728 bv_partial.push(true);
1729 }
1730 let encoded_partial = bv_partial.encode();
1731 let decoded_partial: BitMap<4> =
1732 BitMap::decode_cfg(&mut encoded_partial.as_ref(), &(usize::MAX as u64)).unwrap();
1733 assert_eq!(bv_partial, decoded_partial);
1734 assert_eq!(bv_partial.len(), decoded_partial.len());
1735
1736 assert!(encoded_exact.len() < encoded_partial.len());
1738 assert_eq!(encoded_exact.len(), bv_exact.len().encode_size() + 4); assert_eq!(encoded_partial.len(), bv_partial.len().encode_size() + 8); }
1741
1742 #[test]
1743 fn test_codec_error_cases() {
1744 let mut buf = BytesMut::new();
1746 100u64.write(&mut buf); for _ in 0..4 {
1750 [0u8; 4].write(&mut buf);
1751 }
1752
1753 let result = BitMap::<4>::decode_cfg(&mut buf, &99);
1755 assert!(matches!(result, Err(CodecError::InvalidLength(100))));
1756
1757 let mut buf = BytesMut::new();
1759 100u64.write(&mut buf); [0u8; 4].write(&mut buf);
1762 [0u8; 4].write(&mut buf);
1763 [0u8; 4].write(&mut buf);
1764
1765 let result = BitMap::<4>::decode_cfg(&mut buf, &(usize::MAX as u64));
1766 assert!(result.is_err());
1768
1769 let original: BitMap<4> = BitMap::ones(20);
1773 let mut buf = BytesMut::new();
1774 original.write(&mut buf);
1775
1776 let corrupted_data = buf.freeze();
1778 let mut corrupted_bytes = corrupted_data.to_vec();
1779
1780 let last_byte_idx = corrupted_bytes.len() - 1;
1784 corrupted_bytes[last_byte_idx] |= 0xF0;
1785
1786 let result = BitMap::<4>::read_cfg(&mut corrupted_bytes.as_slice(), &(usize::MAX as u64));
1788 assert!(matches!(
1789 result,
1790 Err(CodecError::Invalid(
1791 "BitMap",
1792 "Invalid trailing bits in encoded data"
1793 ))
1794 ));
1795 }
1796
1797 #[test]
1798 fn test_codec_range_config() {
1799 let mut original: BitMap<4> = BitMap::new();
1803 for i in 0..100 {
1804 original.push(i % 3 == 0);
1805 }
1806
1807 let mut buf = BytesMut::new();
1809 original.write(&mut buf);
1810
1811 let result = BitMap::<4>::decode_cfg(&mut buf.as_ref(), &50);
1813 assert!(matches!(result, Err(CodecError::InvalidLength(100))));
1814
1815 let decoded = BitMap::<4>::decode_cfg(&mut buf.as_ref(), &100).unwrap();
1817 assert_eq!(decoded.len(), 100);
1818 assert_eq!(decoded, original);
1819
1820 let decoded = BitMap::<4>::decode_cfg(&mut buf.as_ref(), &101).unwrap();
1822 assert_eq!(decoded.len(), 100);
1823 assert_eq!(decoded, original);
1824
1825 let empty = BitMap::<4>::new();
1827 let mut buf = BytesMut::new();
1828 empty.write(&mut buf);
1829
1830 let decoded = BitMap::<4>::decode_cfg(&mut buf.as_ref(), &0).unwrap();
1832 assert_eq!(decoded.len(), 0);
1833 assert!(decoded.is_empty());
1834
1835 let decoded = BitMap::<4>::decode_cfg(&mut buf.as_ref(), &1).unwrap();
1837 assert_eq!(decoded.len(), 0);
1838 assert!(decoded.is_empty());
1839 }
1840
1841 #[test]
1842 fn test_from() {
1843 let vec_bool = vec![true, false, true, false, true];
1847 let bv: BitMap<4> = vec_bool.into();
1848 assert_eq!(bv.len(), 5);
1849 assert_eq!(bv.count_ones(), 3);
1850 assert_eq!(bv.count_zeros(), 2);
1851 for (i, &expected) in [true, false, true, false, true].iter().enumerate() {
1852 assert_eq!(bv.get(i as u64), expected);
1853 }
1854
1855 let array = [false, true, true, false];
1857 let bv: BitMap<4> = (&array).into();
1858 assert_eq!(bv.len(), 4);
1859 assert_eq!(bv.count_ones(), 2);
1860 assert_eq!(bv.count_zeros(), 2);
1861 for (i, &expected) in array.iter().enumerate() {
1862 assert_eq!(bv.get(i as u64), expected);
1863 }
1864
1865 let empty: Vec<bool> = vec![];
1867 let bv: BitMap<4> = empty.into();
1868 assert_eq!(bv.len(), 0);
1869 assert!(bv.is_empty());
1870
1871 let large: Vec<bool> = (0..100).map(|i| i % 3 == 0).collect();
1873 let bv: BitMap<8> = large.clone().into();
1874 assert_eq!(bv.len(), 100);
1875 for (i, &expected) in large.iter().enumerate() {
1876 assert_eq!(bv.get(i as u64), expected);
1877 }
1878 }
1879
1880 #[test]
1881 fn test_debug_formatting() {
1882 let bv: BitMap<4> = BitMap::new();
1886 let debug_str = format!("{bv:?}");
1887 assert_eq!(debug_str, "BitMap[]");
1888
1889 let bv: BitMap<4> = [true, false, true, false, true].as_ref().into();
1891 let debug_str = format!("{bv:?}");
1892 assert_eq!(debug_str, "BitMap[10101]");
1893
1894 let pattern: Vec<bool> = (0..64).map(|i| i % 2 == 0).collect();
1896 let bv: BitMap<8> = pattern.into();
1897 let debug_str = format!("{bv:?}");
1898 let expected_pattern = "1010".repeat(16); assert_eq!(debug_str, format!("BitMap[{expected_pattern}]"));
1900
1901 let large_pattern: Vec<bool> = (0..100).map(|i| i % 2 == 0).collect();
1903 let bv: BitMap<16> = large_pattern.into();
1904 let debug_str = format!("{bv:?}");
1905
1906 let first_32 = "10".repeat(16); let last_32 = "10".repeat(16); let expected = format!("BitMap[{first_32}...{last_32}]");
1910 assert_eq!(debug_str, expected);
1911
1912 let bv: BitMap<4> = [true].as_ref().into();
1914 assert_eq!(format!("{bv:?}"), "BitMap[1]");
1915
1916 let bv: BitMap<4> = [false].as_ref().into();
1917 assert_eq!(format!("{bv:?}"), "BitMap[0]");
1918
1919 let pattern: Vec<bool> = (0..65).map(|i| i == 0 || i == 64).collect(); let bv: BitMap<16> = pattern.into();
1922 let debug_str = format!("{bv:?}");
1923
1924 let first_32 = "1".to_string() + &"0".repeat(31);
1926 let last_32 = "0".repeat(31) + "1";
1927 let expected = format!("BitMap[{first_32}...{last_32}]");
1928 assert_eq!(debug_str, expected);
1929 }
1930
1931 #[test]
1932 fn test_from_different_chunk_sizes() {
1933 let pattern = [true, false, true, true, false, false, true];
1935
1936 let bv4: BitMap<4> = pattern.as_ref().into();
1937 let bv8: BitMap<8> = pattern.as_ref().into();
1938 let bv16: BitMap<16> = pattern.as_ref().into();
1939
1940 for bv in [&bv4] {
1943 assert_eq!(bv.len(), 7);
1944 assert_eq!(bv.count_ones(), 4);
1945 assert_eq!(bv.count_zeros(), 3);
1946 for (i, &expected) in pattern.iter().enumerate() {
1947 assert_eq!(bv.get(i as u64), expected);
1948 }
1949 }
1950
1951 assert_eq!(bv8.len(), 7);
1952 assert_eq!(bv8.count_ones(), 4);
1953 assert_eq!(bv8.count_zeros(), 3);
1954 for (i, &expected) in pattern.iter().enumerate() {
1955 assert_eq!(bv8.get(i as u64), expected);
1956 }
1957
1958 assert_eq!(bv16.len(), 7);
1959 assert_eq!(bv16.count_ones(), 4);
1960 assert_eq!(bv16.count_zeros(), 3);
1961 for (i, &expected) in pattern.iter().enumerate() {
1962 assert_eq!(bv16.get(i as u64), expected);
1963 }
1964 }
1965
1966 #[test]
1967 fn test_prune_chunks() {
1968 let mut bv: BitMap<4> = BitMap::new();
1969 bv.push_chunk(&[1, 2, 3, 4]);
1970 bv.push_chunk(&[5, 6, 7, 8]);
1971 bv.push_chunk(&[9, 10, 11, 12]);
1972
1973 assert_eq!(bv.len(), 96);
1974 assert_eq!(bv.get_chunk(0), &[1, 2, 3, 4]);
1975
1976 bv.prune_chunks(1);
1978 assert_eq!(bv.len(), 64);
1979 assert_eq!(bv.get_chunk(0), &[5, 6, 7, 8]);
1980 assert_eq!(bv.get_chunk(1), &[9, 10, 11, 12]);
1981
1982 bv.prune_chunks(1);
1984 assert_eq!(bv.len(), 32);
1985 assert_eq!(bv.get_chunk(0), &[9, 10, 11, 12]);
1986 }
1987
1988 #[test]
1989 #[should_panic(expected = "cannot prune")]
1990 fn test_prune_too_many_chunks() {
1991 let mut bv: BitMap<4> = BitMap::new();
1992 bv.push_chunk(&[1, 2, 3, 4]);
1993 bv.push_chunk(&[5, 6, 7, 8]);
1994 bv.push(true);
1995
1996 bv.prune_chunks(4);
1998 }
1999
2000 #[test]
2001 fn test_prune_with_partial_last_chunk() {
2002 let mut bv: BitMap<4> = BitMap::new();
2003 bv.push_chunk(&[1, 2, 3, 4]);
2004 bv.push_chunk(&[5, 6, 7, 8]);
2005 bv.push(true);
2006 bv.push(false);
2007
2008 assert_eq!(bv.len(), 66);
2009
2010 bv.prune_chunks(1);
2012 assert_eq!(bv.len(), 34);
2013 assert_eq!(bv.get_chunk(0), &[5, 6, 7, 8]);
2014
2015 assert!(bv.get(32));
2017 assert!(!bv.get(33));
2018 }
2019
2020 #[test]
2021 fn test_prune_all_chunks_resets_next_bit() {
2022 let mut bv: BitMap<4> = BitMap::new();
2023 bv.push_chunk(&[1, 2, 3, 4]);
2024 bv.push_chunk(&[5, 6, 7, 8]);
2025 bv.push(true);
2026 bv.push(false);
2027 bv.push(true);
2028
2029 assert_eq!(bv.len(), 67);
2031
2032 bv.prune_chunks(3);
2034
2035 assert_eq!(bv.len(), 0);
2037 assert!(bv.is_empty());
2038
2039 bv.push(true);
2041 assert_eq!(bv.len(), 1);
2042 assert!(bv.get(0));
2043 }
2044
2045 #[test]
2046 fn test_is_chunk_aligned() {
2047 let bv: BitMap<4> = BitMap::new();
2049 assert!(bv.is_chunk_aligned());
2050
2051 let mut bv4: BitMap<4> = BitMap::new();
2053 assert!(bv4.is_chunk_aligned());
2054
2055 for i in 1..=32 {
2057 bv4.push(i % 2 == 0);
2058 if i == 32 {
2059 assert!(bv4.is_chunk_aligned()); } else {
2061 assert!(!bv4.is_chunk_aligned()); }
2063 }
2064
2065 for i in 33..=64 {
2067 bv4.push(i % 2 == 0);
2068 if i == 64 {
2069 assert!(bv4.is_chunk_aligned()); } else {
2071 assert!(!bv4.is_chunk_aligned()); }
2073 }
2074
2075 let mut bv: BitMap<8> = BitMap::new();
2077 assert!(bv.is_chunk_aligned());
2078 bv.push_chunk(&[0xFF; 8]);
2079 assert!(bv.is_chunk_aligned()); bv.push_chunk(&[0xAA; 8]);
2081 assert!(bv.is_chunk_aligned()); bv.push(true);
2083 assert!(!bv.is_chunk_aligned()); let mut bv: BitMap<4> = BitMap::new();
2087 for _ in 0..4 {
2088 bv.push_byte(0xFF);
2089 }
2090 assert!(bv.is_chunk_aligned()); bv.pop();
2094 assert!(!bv.is_chunk_aligned()); let bv_zeroes: BitMap<4> = BitMap::zeroes(64);
2098 assert!(bv_zeroes.is_chunk_aligned());
2099
2100 let bv_ones: BitMap<4> = BitMap::ones(96);
2101 assert!(bv_ones.is_chunk_aligned());
2102
2103 let bv_partial: BitMap<4> = BitMap::zeroes(65);
2104 assert!(!bv_partial.is_chunk_aligned());
2105 }
2106
2107 #[test]
2108 fn test_unprune_restores_length() {
2109 let mut prunable: Prunable<4> = Prunable::new_with_pruned_chunks(1).unwrap();
2110 assert_eq!(prunable.len(), Prunable::<4>::CHUNK_SIZE_BITS);
2111 assert_eq!(prunable.pruned_chunks(), 1);
2112 let chunk = [0xDE, 0xAD, 0xBE, 0xEF];
2113
2114 prunable.unprune_chunks(&[chunk]);
2115
2116 assert_eq!(prunable.pruned_chunks(), 0);
2117 assert_eq!(prunable.len(), Prunable::<4>::CHUNK_SIZE_BITS);
2118 assert_eq!(prunable.get_chunk_containing(0), &chunk);
2119 }
2120}