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 iter,
13 ops::{BitAnd, BitOr, BitXor, Index, Range},
14};
15#[cfg(feature = "std")]
16use std::collections::VecDeque;
17
18mod prunable;
19pub use prunable::Prunable;
20
21pub mod historical;
22
23pub const DEFAULT_CHUNK_SIZE: usize = 8;
25
26#[derive(Clone, PartialEq, Eq, Hash)]
33pub struct BitMap<const N: usize = DEFAULT_CHUNK_SIZE> {
34 chunks: VecDeque<[u8; N]>,
40
41 len: u64,
43}
44
45impl<const N: usize> BitMap<N> {
46 const _CHUNK_SIZE_NON_ZERO_ASSERT: () = assert!(N > 0, "chunk size must be > 0");
47
48 pub const CHUNK_SIZE_BITS: u64 = (N * 8) as u64;
50
51 const EMPTY_CHUNK: [u8; N] = [0u8; N];
53
54 const FULL_CHUNK: [u8; N] = [u8::MAX; N];
56
57 pub const fn new() -> Self {
61 #[allow(path_statements)]
62 Self::_CHUNK_SIZE_NON_ZERO_ASSERT; Self {
65 chunks: VecDeque::new(),
66 len: 0,
67 }
68 }
69
70 pub fn with_capacity(size: u64) -> Self {
72 #[allow(path_statements)]
73 Self::_CHUNK_SIZE_NON_ZERO_ASSERT; Self {
76 chunks: VecDeque::with_capacity(size.div_ceil(Self::CHUNK_SIZE_BITS) as usize),
77 len: 0,
78 }
79 }
80
81 pub fn zeroes(size: u64) -> Self {
83 #[allow(path_statements)]
84 Self::_CHUNK_SIZE_NON_ZERO_ASSERT; let num_chunks = size.div_ceil(Self::CHUNK_SIZE_BITS) as usize;
87 let mut chunks = VecDeque::with_capacity(num_chunks);
88 for _ in 0..num_chunks {
89 chunks.push_back(Self::EMPTY_CHUNK);
90 }
91 Self { chunks, len: size }
92 }
93
94 pub fn ones(size: u64) -> Self {
96 #[allow(path_statements)]
97 Self::_CHUNK_SIZE_NON_ZERO_ASSERT; let num_chunks = size.div_ceil(Self::CHUNK_SIZE_BITS) as usize;
100 let mut chunks = VecDeque::with_capacity(num_chunks);
101 for _ in 0..num_chunks {
102 chunks.push_back(Self::FULL_CHUNK);
103 }
104 let mut result = Self { chunks, len: size };
105 result.clear_trailing_bits();
107 result
108 }
109
110 #[inline]
114 pub const fn len(&self) -> u64 {
115 self.len
116 }
117
118 #[inline]
120 pub const fn is_empty(&self) -> bool {
121 self.len() == 0
122 }
123
124 #[inline]
126 pub const fn is_chunk_aligned(&self) -> bool {
127 self.len.is_multiple_of(Self::CHUNK_SIZE_BITS)
128 }
129
130 fn chunks_len(&self) -> usize {
132 self.chunks.len()
133 }
134
135 #[inline]
143 pub fn get(&self, bit: u64) -> bool {
144 let chunk = self.get_chunk_containing(bit);
145 Self::get_bit_from_chunk(chunk, bit)
146 }
147
148 #[inline]
154 fn get_chunk_containing(&self, bit: u64) -> &[u8; N] {
155 assert!(
156 bit < self.len(),
157 "bit {} out of bounds (len: {})",
158 bit,
159 self.len()
160 );
161 &self.chunks[Self::to_chunk_index(bit)]
162 }
163
164 #[inline]
171 pub(super) fn get_chunk(&self, chunk: usize) -> &[u8; N] {
172 assert!(
173 chunk < self.chunks.len(),
174 "chunk {} out of bounds (chunks: {})",
175 chunk,
176 self.chunks.len()
177 );
178 &self.chunks[chunk]
179 }
180
181 #[inline]
184 pub const fn get_bit_from_chunk(chunk: &[u8; N], bit: u64) -> bool {
185 let byte = Self::chunk_byte_offset(bit);
186 let byte = chunk[byte];
187 let mask = Self::chunk_byte_bitmask(bit);
188 (byte & mask) != 0
189 }
190
191 #[inline]
197 fn last_chunk(&self) -> (&[u8; N], u64) {
198 let rem = self.len % Self::CHUNK_SIZE_BITS;
199 let bits_in_last_chunk = if rem == 0 { Self::CHUNK_SIZE_BITS } else { rem };
200 (self.chunks.back().unwrap(), bits_in_last_chunk)
201 }
202
203 pub fn push(&mut self, bit: bool) {
207 if self.is_chunk_aligned() {
209 self.chunks.push_back(Self::EMPTY_CHUNK);
210 }
211
212 if bit {
214 let last_chunk = self.chunks.back_mut().unwrap();
215 let chunk_byte = Self::chunk_byte_offset(self.len);
216 last_chunk[chunk_byte] |= Self::chunk_byte_bitmask(self.len);
217 }
218 self.len += 1;
220 }
221
222 pub fn pop(&mut self) -> bool {
228 assert!(!self.is_empty(), "Cannot pop from empty bitmap");
229
230 let last_bit_pos = self.len - 1;
232 let bit = Self::get_bit_from_chunk(self.chunks.back().unwrap(), last_bit_pos);
233
234 self.len -= 1;
236
237 if bit {
239 let chunk_byte = Self::chunk_byte_offset(last_bit_pos);
240 let mask = Self::chunk_byte_bitmask(last_bit_pos);
241 self.chunks.back_mut().unwrap()[chunk_byte] &= !mask;
242 }
243
244 if self.is_chunk_aligned() {
246 self.chunks.pop_back();
247 }
248
249 bit
250 }
251
252 pub(super) fn pop_chunk(&mut self) -> [u8; N] {
258 assert!(
259 self.len() >= Self::CHUNK_SIZE_BITS,
260 "cannot pop chunk: bitmap has fewer than CHUNK_SIZE_BITS bits"
261 );
262 assert!(
263 self.is_chunk_aligned(),
264 "cannot pop chunk when not chunk aligned"
265 );
266
267 let chunk = self.chunks.pop_back().expect("chunk must exist");
269 self.len -= Self::CHUNK_SIZE_BITS;
270 chunk
271 }
272
273 #[inline]
279 pub fn flip(&mut self, bit: u64) {
280 self.assert_bit(bit);
281 let chunk = Self::to_chunk_index(bit);
282 let byte = Self::chunk_byte_offset(bit);
283 let mask = Self::chunk_byte_bitmask(bit);
284 self.chunks[chunk][byte] ^= mask;
285 }
286
287 pub fn flip_all(&mut self) {
289 for chunk in &mut self.chunks {
290 for byte in chunk {
291 *byte = !*byte;
292 }
293 }
294 self.clear_trailing_bits();
296 }
297
298 pub fn set(&mut self, bit: u64, value: bool) {
304 assert!(
305 bit < self.len(),
306 "bit {} out of bounds (len: {})",
307 bit,
308 self.len()
309 );
310
311 let chunk = &mut self.chunks[Self::to_chunk_index(bit)];
312 let byte = Self::chunk_byte_offset(bit);
313 let mask = Self::chunk_byte_bitmask(bit);
314 if value {
315 chunk[byte] |= mask;
316 } else {
317 chunk[byte] &= !mask;
318 }
319 }
320
321 #[inline]
323 pub fn set_all(&mut self, bit: bool) {
324 let value = if bit { u8::MAX } else { 0 };
325 for chunk in &mut self.chunks {
326 chunk.fill(value);
327 }
328 if bit {
330 self.clear_trailing_bits();
331 }
332 }
333
334 fn push_byte(&mut self, byte: u8) {
340 assert!(
341 self.len.is_multiple_of(8),
342 "cannot add byte when not byte aligned"
343 );
344
345 if self.is_chunk_aligned() {
347 self.chunks.push_back(Self::EMPTY_CHUNK);
348 }
349
350 let chunk_byte = Self::chunk_byte_offset(self.len);
351 self.chunks.back_mut().unwrap()[chunk_byte] = byte;
352 self.len += 8;
353 }
354
355 pub fn push_chunk(&mut self, chunk: &[u8; N]) {
361 assert!(
362 self.is_chunk_aligned(),
363 "cannot add chunk when not chunk aligned"
364 );
365 self.chunks.push_back(*chunk);
366 self.len += Self::CHUNK_SIZE_BITS;
367 }
368
369 fn clear_trailing_bits(&mut self) -> bool {
374 if self.chunks.is_empty() {
375 return false;
376 }
377
378 let pos_in_chunk = self.len % Self::CHUNK_SIZE_BITS;
379 if pos_in_chunk == 0 {
380 return false;
382 }
383
384 let mut flipped_any = false;
385 let last_chunk = self.chunks.back_mut().unwrap();
386
387 let last_byte_index = ((pos_in_chunk - 1) / 8) as usize;
389 for byte in last_chunk.iter_mut().skip(last_byte_index + 1) {
390 if *byte != 0 {
391 flipped_any = true;
392 *byte = 0;
393 }
394 }
395
396 let bits_in_last_byte = pos_in_chunk % 8;
398 if bits_in_last_byte != 0 {
399 let mask = (1u8 << bits_in_last_byte) - 1;
400 let old_byte = last_chunk[last_byte_index];
401 let new_byte = old_byte & mask;
402 if old_byte != new_byte {
403 flipped_any = true;
404 last_chunk[last_byte_index] = new_byte;
405 }
406 }
407
408 flipped_any
409 }
410
411 fn prune_chunks(&mut self, chunks: usize) {
419 assert!(
420 chunks <= self.chunks.len(),
421 "cannot prune {chunks} chunks, only {} available",
422 self.chunks.len()
423 );
424 self.chunks.drain(..chunks);
425 let bits_removed = (chunks as u64) * Self::CHUNK_SIZE_BITS;
427 self.len = self.len.saturating_sub(bits_removed);
428 }
429
430 pub(super) fn prepend_chunk(&mut self, chunk: &[u8; N]) {
432 self.chunks.push_front(*chunk);
433 self.len += Self::CHUNK_SIZE_BITS;
434 }
435
436 pub(super) fn set_chunk_by_index(&mut self, chunk_index: usize, chunk_data: &[u8; N]) {
446 assert!(
447 chunk_index < self.chunks.len(),
448 "chunk index {chunk_index} out of bounds (chunks_len: {})",
449 self.chunks.len()
450 );
451 self.chunks[chunk_index].copy_from_slice(chunk_data);
452 }
453
454 #[inline]
458 pub fn count_ones(&self) -> u64 {
459 let (front, back) = self.chunks.as_slices();
463 Self::count_ones_in_chunk_slice(front) + Self::count_ones_in_chunk_slice(back)
464 }
465
466 #[inline]
467 fn count_ones_in_chunk_slice(chunks: &[[u8; N]]) -> u64 {
468 let mut total = 0u64;
469 let mut words = chunks.as_flattened().chunks_exact(8);
470 for word in &mut words {
471 total += u64::from_le_bytes(word.try_into().unwrap()).count_ones() as u64;
472 }
473 for byte in words.remainder() {
474 total += byte.count_ones() as u64;
475 }
476 total
477 }
478
479 #[inline]
481 pub fn count_zeros(&self) -> u64 {
482 self.len() - self.count_ones()
483 }
484
485 #[inline]
489 pub(super) const fn chunk_byte_bitmask(bit: u64) -> u8 {
490 1 << (bit % 8)
491 }
492
493 #[inline]
495 pub(super) const fn chunk_byte_offset(bit: u64) -> usize {
496 ((bit / 8) % N as u64) as usize
497 }
498
499 #[inline]
505 pub(super) fn to_chunk_index(bit: u64) -> usize {
506 let chunk = bit / Self::CHUNK_SIZE_BITS;
507 assert!(
508 chunk <= usize::MAX as u64,
509 "chunk overflow: {chunk} exceeds usize::MAX",
510 );
511 chunk as usize
512 }
513
514 pub const fn iter(&self) -> Iterator<'_, N> {
518 Iterator {
519 bitmap: self,
520 pos: 0,
521 }
522 }
523
524 #[inline]
528 fn binary_op<F: Fn(u8, u8) -> u8>(&mut self, other: &Self, op: F) {
529 self.assert_eq_len(other);
530 for (a_chunk, b_chunk) in self.chunks.iter_mut().zip(other.chunks.iter()) {
531 for (a_byte, b_byte) in a_chunk.iter_mut().zip(b_chunk.iter()) {
532 *a_byte = op(*a_byte, *b_byte);
533 }
534 }
535 self.clear_trailing_bits();
537 }
538
539 pub fn and(&mut self, other: &Self) {
545 self.binary_op(other, |a, b| a & b);
546 }
547
548 pub fn or(&mut self, other: &Self) {
554 self.binary_op(other, |a, b| a | b);
555 }
556
557 pub fn xor(&mut self, other: &Self) {
563 self.binary_op(other, |a, b| a ^ b);
564 }
565
566 #[inline(always)]
570 fn assert_bit(&self, bit: u64) {
571 assert!(
572 bit < self.len(),
573 "bit {} out of bounds (len: {})",
574 bit,
575 self.len()
576 );
577 }
578
579 #[inline(always)]
581 fn assert_eq_len(&self, other: &Self) {
582 assert_eq!(
583 self.len(),
584 other.len(),
585 "BitMap lengths don't match: {} vs {}",
586 self.len(),
587 other.len()
588 );
589 }
590
591 pub fn is_unset(&self, range: Range<u64>) -> bool {
614 assert!(
615 range.end <= self.len(),
616 "range end {} out of bounds (len: {})",
617 range.end,
618 self.len()
619 );
620 if range.start >= range.end {
621 return true;
622 }
623 let start = range.start;
624 let end = range.end;
625
626 let end = end - 1;
630
631 let first_chunk = Self::to_chunk_index(start);
633 let last_chunk = Self::to_chunk_index(end);
634
635 let zero = [0u8; N];
638 for full_chunk in (first_chunk + 1)..last_chunk {
639 if self.chunks[full_chunk] != zero {
640 return false;
641 }
642 }
643
644 let start_byte = Self::chunk_byte_offset(start);
646 let end_byte = Self::chunk_byte_offset(end);
647 let start_mask = (0xFFu16 << ((start & 0b111) as u32)) as u8;
648 let end_mask = (0xFFu16 >> (7 - ((end & 0b111) as u32))) as u8;
649 let first = &self.chunks[first_chunk];
650 let first_end_byte = if first_chunk == last_chunk {
651 end_byte
652 } else {
653 N - 1
654 };
655 for (i, &byte) in first
656 .iter()
657 .enumerate()
658 .take(first_end_byte + 1)
659 .skip(start_byte)
660 {
661 let mut mask = 0xFFu8;
662 if i == start_byte {
663 mask &= start_mask;
664 }
665 if first_chunk == last_chunk && i == end_byte {
666 mask &= end_mask;
667 }
668 if (byte & mask) != 0 {
669 return false;
670 }
671 }
672 if first_chunk == last_chunk {
673 return true;
674 }
675
676 let last = &self.chunks[last_chunk];
678 for (i, &byte) in last.iter().enumerate().take(end_byte + 1) {
679 let mask = if i == end_byte { end_mask } else { 0xFF };
680 if (byte & mask) != 0 {
681 return false;
682 }
683 }
684
685 true
686 }
687}
688
689impl<const N: usize> Default for BitMap<N> {
690 fn default() -> Self {
691 Self::new()
692 }
693}
694
695impl<T: AsRef<[bool]>, const N: usize> From<T> for BitMap<N> {
696 fn from(t: T) -> Self {
697 let bools = t.as_ref();
698 let mut bv = Self::with_capacity(bools.len() as u64);
699 for &b in bools {
700 bv.push(b);
701 }
702 bv
703 }
704}
705
706impl<const N: usize> From<BitMap<N>> for Vec<bool> {
707 fn from(bv: BitMap<N>) -> Self {
708 bv.iter().collect()
709 }
710}
711
712impl<const N: usize> fmt::Debug for BitMap<N> {
713 fn fmt(&self, f: &mut Formatter<'_>) -> core::fmt::Result {
714 const MAX_DISPLAY: u64 = 64;
716 const HALF_DISPLAY: u64 = MAX_DISPLAY / 2;
717
718 let write_bit = |formatter: &mut Formatter<'_>, bit: u64| -> core::fmt::Result {
720 formatter.write_char(if self.get(bit) { '1' } else { '0' })
721 };
722
723 f.write_str("BitMap[")?;
724 let len = self.len();
725 if len <= MAX_DISPLAY {
726 for i in 0..len {
728 write_bit(f, i)?;
729 }
730 } else {
731 for i in 0..HALF_DISPLAY {
733 write_bit(f, i)?;
734 }
735
736 f.write_str("...")?;
737
738 for i in (len - HALF_DISPLAY)..len {
739 write_bit(f, i)?;
740 }
741 }
742 f.write_str("]")
743 }
744}
745
746impl<const N: usize> Index<u64> for BitMap<N> {
747 type Output = bool;
748
749 #[inline]
753 fn index(&self, bit: u64) -> &Self::Output {
754 self.assert_bit(bit);
755 let value = self.get(bit);
756 if value {
757 &true
758 } else {
759 &false
760 }
761 }
762}
763
764impl<const N: usize> BitAnd for &BitMap<N> {
765 type Output = BitMap<N>;
766
767 fn bitand(self, rhs: Self) -> Self::Output {
768 self.assert_eq_len(rhs);
769 let mut result = self.clone();
770 result.and(rhs);
771 result
772 }
773}
774
775impl<const N: usize> BitOr for &BitMap<N> {
776 type Output = BitMap<N>;
777
778 fn bitor(self, rhs: Self) -> Self::Output {
779 self.assert_eq_len(rhs);
780 let mut result = self.clone();
781 result.or(rhs);
782 result
783 }
784}
785
786impl<const N: usize> BitXor for &BitMap<N> {
787 type Output = BitMap<N>;
788
789 fn bitxor(self, rhs: Self) -> Self::Output {
790 self.assert_eq_len(rhs);
791 let mut result = self.clone();
792 result.xor(rhs);
793 result
794 }
795}
796
797impl<const N: usize> Write for BitMap<N> {
798 fn write(&self, buf: &mut impl BufMut) {
799 self.len().write(buf);
801
802 for chunk in &self.chunks {
804 for &byte in chunk {
805 byte.write(buf);
806 }
807 }
808 }
809}
810
811impl<const N: usize> Read for BitMap<N> {
812 type Cfg = u64; fn read_cfg(buf: &mut impl Buf, max_len: &Self::Cfg) -> Result<Self, CodecError> {
815 let len = u64::read(buf)?;
817 if len > *max_len {
818 return Err(CodecError::InvalidLength(len as usize));
819 }
820
821 let num_chunks = len.div_ceil(Self::CHUNK_SIZE_BITS) as usize;
823
824 let mut chunks = VecDeque::with_capacity(num_chunks);
826 for _ in 0..num_chunks {
827 at_least(buf, N)?;
828 let mut chunk = [0u8; N];
829 buf.copy_to_slice(&mut chunk);
830 chunks.push_back(chunk);
831 }
832
833 let mut result = Self { chunks, len };
834
835 if result.clear_trailing_bits() {
837 return Err(CodecError::Invalid(
838 "BitMap",
839 "Invalid trailing bits in encoded data",
840 ));
841 }
842
843 Ok(result)
844 }
845}
846
847impl<const N: usize> EncodeSize for BitMap<N> {
848 fn encode_size(&self) -> usize {
849 self.len().encode_size() + (self.chunks.len() * N)
851 }
852}
853
854pub struct Iterator<'a, const N: usize> {
856 bitmap: &'a BitMap<N>,
858
859 pos: u64,
861}
862
863impl<const N: usize> iter::Iterator for Iterator<'_, N> {
864 type Item = bool;
865
866 fn next(&mut self) -> Option<Self::Item> {
867 if self.pos >= self.bitmap.len() {
868 return None;
869 }
870
871 let bit = self.bitmap.get(self.pos);
872 self.pos += 1;
873 Some(bit)
874 }
875
876 fn size_hint(&self) -> (usize, Option<usize>) {
877 let remaining = self.bitmap.len().saturating_sub(self.pos);
878 let capped = remaining.min(usize::MAX as u64) as usize;
879 (capped, Some(capped))
880 }
881}
882
883impl<const N: usize> ExactSizeIterator for Iterator<'_, N> {}
884
885#[cfg(feature = "arbitrary")]
886impl<const N: usize> arbitrary::Arbitrary<'_> for BitMap<N> {
887 fn arbitrary(u: &mut arbitrary::Unstructured<'_>) -> arbitrary::Result<Self> {
888 let size = u.int_in_range(0..=1024)?;
889 let mut bits = Self::with_capacity(size);
890 for _ in 0..size {
891 bits.push(u.arbitrary::<bool>()?);
892 }
893 Ok(bits)
894 }
895}
896
897#[cfg(test)]
898mod tests {
899 use super::*;
900 use crate::hex;
901 use bytes::BytesMut;
902 use commonware_codec::{Decode, Encode};
903
904 #[test]
905 fn test_constructors() {
906 let bv: BitMap<4> = BitMap::new();
908 assert_eq!(bv.len(), 0);
909 assert!(bv.is_empty());
910
911 let bv: BitMap<4> = Default::default();
913 assert_eq!(bv.len(), 0);
914 assert!(bv.is_empty());
915
916 let bv: BitMap<4> = BitMap::with_capacity(0);
918 assert_eq!(bv.len(), 0);
919 assert!(bv.is_empty());
920
921 let bv: BitMap<4> = BitMap::with_capacity(10);
922 assert_eq!(bv.len(), 0);
923 assert!(bv.is_empty());
924 }
925
926 #[test]
927 fn test_zeroes() {
928 let bv: BitMap<1> = BitMap::zeroes(0);
929 assert_eq!(bv.len(), 0);
930 assert!(bv.is_empty());
931 assert_eq!(bv.count_ones(), 0);
932 assert_eq!(bv.count_zeros(), 0);
933
934 let bv: BitMap<1> = BitMap::zeroes(1);
935 assert_eq!(bv.len(), 1);
936 assert!(!bv.is_empty());
937 assert_eq!(bv.len(), 1);
938 assert!(!bv.get(0));
939 assert_eq!(bv.count_ones(), 0);
940 assert_eq!(bv.count_zeros(), 1);
941
942 let bv: BitMap<1> = BitMap::zeroes(10);
943 assert_eq!(bv.len(), 10);
944 assert!(!bv.is_empty());
945 assert_eq!(bv.len(), 10);
946 for i in 0..10 {
947 assert!(!bv.get(i as u64));
948 }
949 assert_eq!(bv.count_ones(), 0);
950 assert_eq!(bv.count_zeros(), 10);
951 }
952
953 #[test]
954 fn test_ones() {
955 let bv: BitMap<1> = BitMap::ones(0);
956 assert_eq!(bv.len(), 0);
957 assert!(bv.is_empty());
958 assert_eq!(bv.count_ones(), 0);
959 assert_eq!(bv.count_zeros(), 0);
960
961 let bv: BitMap<1> = BitMap::ones(1);
962 assert_eq!(bv.len(), 1);
963 assert!(!bv.is_empty());
964 assert_eq!(bv.len(), 1);
965 assert!(bv.get(0));
966 assert_eq!(bv.count_ones(), 1);
967 assert_eq!(bv.count_zeros(), 0);
968
969 let bv: BitMap<1> = BitMap::ones(10);
970 assert_eq!(bv.len(), 10);
971 assert!(!bv.is_empty());
972 assert_eq!(bv.len(), 10);
973 for i in 0..10 {
974 assert!(bv.get(i as u64));
975 }
976 assert_eq!(bv.count_ones(), 10);
977 assert_eq!(bv.count_zeros(), 0);
978 }
979
980 #[test]
981 fn test_invariant_trailing_bits_are_zero() {
982 fn check_trailing_bits_zero<const N: usize>(bitmap: &BitMap<N>) {
984 let (last_chunk, next_bit) = bitmap.last_chunk();
985
986 for bit_idx in next_bit..((N * 8) as u64) {
988 let byte_idx = (bit_idx / 8) as usize;
989 let bit_in_byte = bit_idx % 8;
990 let mask = 1u8 << bit_in_byte;
991 assert_eq!(last_chunk[byte_idx] & mask, 0);
992 }
993 }
994
995 let bv: BitMap<4> = BitMap::ones(15);
997 check_trailing_bits_zero(&bv);
998
999 let bv: BitMap<4> = BitMap::ones(33);
1000 check_trailing_bits_zero(&bv);
1001
1002 let mut bv: BitMap<4> = BitMap::new();
1004 for i in 0..37 {
1005 bv.push(i % 2 == 0);
1006 check_trailing_bits_zero(&bv);
1007 }
1008
1009 let mut bv: BitMap<4> = BitMap::ones(40);
1011 check_trailing_bits_zero(&bv);
1012 for _ in 0..15 {
1013 bv.pop();
1014 check_trailing_bits_zero(&bv);
1015 }
1016
1017 let mut bv: BitMap<4> = BitMap::ones(25);
1019 bv.flip_all();
1020 check_trailing_bits_zero(&bv);
1021
1022 let bv1: BitMap<4> = BitMap::ones(20);
1024 let bv2: BitMap<4> = BitMap::zeroes(20);
1025
1026 let mut bv_and = bv1.clone();
1027 bv_and.and(&bv2);
1028 check_trailing_bits_zero(&bv_and);
1029
1030 let mut bv_or = bv1.clone();
1031 bv_or.or(&bv2);
1032 check_trailing_bits_zero(&bv_or);
1033
1034 let mut bv_xor = bv1;
1035 bv_xor.xor(&bv2);
1036 check_trailing_bits_zero(&bv_xor);
1037
1038 let original: BitMap<4> = BitMap::ones(27);
1040 let encoded = original.encode();
1041 let decoded: BitMap<4> =
1042 BitMap::decode_cfg(&mut encoded.as_ref(), &(usize::MAX as u64)).unwrap();
1043 check_trailing_bits_zero(&decoded);
1044
1045 let mut bv_clean: BitMap<4> = BitMap::ones(20);
1047 assert!(!bv_clean.clear_trailing_bits());
1049
1050 let mut bv_dirty: BitMap<4> = BitMap::ones(20);
1052 let last_chunk = bv_dirty.chunks.back_mut().unwrap();
1054 last_chunk[3] |= 0xF0; assert!(bv_dirty.clear_trailing_bits());
1057 assert!(!bv_dirty.clear_trailing_bits());
1059 check_trailing_bits_zero(&bv_dirty);
1060 }
1061
1062 #[test]
1063 fn test_get_set() {
1064 let mut bv: BitMap<4> = BitMap::new();
1065
1066 assert_eq!(bv.len(), 0);
1068 assert!(bv.is_empty());
1069
1070 bv.push(true);
1072 bv.push(false);
1073 bv.push(true);
1074 assert_eq!(bv.len(), 3);
1075 assert!(!bv.is_empty());
1076
1077 assert!(bv.get(0));
1079 assert!(!bv.get(1));
1080 assert!(bv.get(2));
1081
1082 bv.set(1, true);
1083 assert!(bv.get(1));
1084 bv.set(2, false);
1085 assert!(!bv.get(2));
1086
1087 bv.flip(0); assert!(!bv.get(0));
1090 bv.flip(0); assert!(bv.get(0));
1092 }
1093
1094 #[test]
1095 fn test_chunk_operations() {
1096 let mut bv: BitMap<4> = BitMap::new();
1097 let test_chunk = hex!("0xABCDEF12");
1098
1099 bv.push_chunk(&test_chunk);
1101 assert_eq!(bv.len(), 32); let chunk = bv.get_chunk(0);
1105 assert_eq!(chunk, &test_chunk);
1106
1107 let chunk = bv.get_chunk_containing(0);
1109 assert_eq!(chunk, &test_chunk);
1110
1111 let (last_chunk, next_bit) = bv.last_chunk();
1113 assert_eq!(next_bit, BitMap::<4>::CHUNK_SIZE_BITS); assert_eq!(last_chunk, &test_chunk); }
1116
1117 #[test]
1118 fn test_pop() {
1119 let mut bv: BitMap<3> = BitMap::new();
1120 bv.push(true);
1121 assert!(bv.pop());
1122 assert_eq!(bv.len(), 0);
1123
1124 bv.push(false);
1125 assert!(!bv.pop());
1126 assert_eq!(bv.len(), 0);
1127
1128 bv.push(true);
1129 bv.push(false);
1130 bv.push(true);
1131 assert!(bv.pop());
1132 assert_eq!(bv.len(), 2);
1133 assert!(!bv.pop());
1134 assert_eq!(bv.len(), 1);
1135 assert!(bv.pop());
1136 assert_eq!(bv.len(), 0);
1137
1138 for i in 0..100 {
1139 bv.push(i % 2 == 0);
1140 }
1141 assert_eq!(bv.len(), 100);
1142 for i in (0..100).rev() {
1143 assert_eq!(bv.pop(), i % 2 == 0);
1144 }
1145 assert_eq!(bv.len(), 0);
1146 assert!(bv.is_empty());
1147 }
1148
1149 #[test]
1150 fn test_pop_chunk() {
1151 let mut bv: BitMap<3> = BitMap::new();
1152 const CHUNK_SIZE: u64 = BitMap::<3>::CHUNK_SIZE_BITS;
1153
1154 let chunk1 = hex!("0xAABBCC");
1156 bv.push_chunk(&chunk1);
1157 assert_eq!(bv.len(), CHUNK_SIZE);
1158 let popped = bv.pop_chunk();
1159 assert_eq!(popped, chunk1);
1160 assert_eq!(bv.len(), 0);
1161 assert!(bv.is_empty());
1162
1163 let chunk2 = hex!("0x112233");
1165 let chunk3 = hex!("0x445566");
1166 let chunk4 = hex!("0x778899");
1167
1168 bv.push_chunk(&chunk2);
1169 bv.push_chunk(&chunk3);
1170 bv.push_chunk(&chunk4);
1171 assert_eq!(bv.len(), CHUNK_SIZE * 3);
1172
1173 assert_eq!(bv.pop_chunk(), chunk4);
1174 assert_eq!(bv.len(), CHUNK_SIZE * 2);
1175
1176 assert_eq!(bv.pop_chunk(), chunk3);
1177 assert_eq!(bv.len(), CHUNK_SIZE);
1178
1179 assert_eq!(bv.pop_chunk(), chunk2);
1180 assert_eq!(bv.len(), 0);
1181
1182 let first_chunk = hex!("0xAABBCC");
1184 let second_chunk = hex!("0x112233");
1185 bv.push_chunk(&first_chunk);
1186 bv.push_chunk(&second_chunk);
1187
1188 assert_eq!(bv.pop_chunk(), second_chunk);
1190 assert_eq!(bv.len(), CHUNK_SIZE);
1191
1192 for i in 0..CHUNK_SIZE {
1193 let byte_idx = (i / 8) as usize;
1194 let bit_idx = i % 8;
1195 let expected = (first_chunk[byte_idx] >> bit_idx) & 1 == 1;
1196 assert_eq!(bv.get(i), expected);
1197 }
1198
1199 assert_eq!(bv.pop_chunk(), first_chunk);
1200 assert_eq!(bv.len(), 0);
1201 }
1202
1203 #[test]
1204 #[should_panic(expected = "cannot pop chunk when not chunk aligned")]
1205 fn test_pop_chunk_not_aligned() {
1206 let mut bv: BitMap<3> = BitMap::new();
1207
1208 bv.push_chunk(&[0xFF; 3]);
1210 bv.push(true);
1211
1212 bv.pop_chunk();
1214 }
1215
1216 #[test]
1217 #[should_panic(expected = "cannot pop chunk: bitmap has fewer than CHUNK_SIZE_BITS bits")]
1218 fn test_pop_chunk_insufficient_bits() {
1219 let mut bv: BitMap<3> = BitMap::new();
1220
1221 bv.push(true);
1223 bv.push(false);
1224
1225 bv.pop_chunk();
1227 }
1228
1229 #[test]
1230 fn test_byte_operations() {
1231 let mut bv: BitMap<4> = BitMap::new();
1232
1233 bv.push_byte(0xFF);
1235 assert_eq!(bv.len(), 8);
1236
1237 for i in 0..8 {
1239 assert!(bv.get(i as u64));
1240 }
1241
1242 bv.push_byte(0x00);
1243 assert_eq!(bv.len(), 16);
1244
1245 for i in 8..16 {
1247 assert!(!bv.get(i as u64));
1248 }
1249 }
1250
1251 #[test]
1252 fn test_count_operations() {
1253 let mut bv: BitMap<4> = BitMap::new();
1254
1255 assert_eq!(bv.count_ones(), 0);
1257 assert_eq!(bv.count_zeros(), 0);
1258
1259 bv.push(true);
1261 bv.push(false);
1262 bv.push(true);
1263 bv.push(true);
1264 bv.push(false);
1265
1266 assert_eq!(bv.count_ones(), 3);
1267 assert_eq!(bv.count_zeros(), 2);
1268 assert_eq!(bv.len(), 5);
1269
1270 let mut bv2: BitMap<4> = BitMap::new();
1272 bv2.push_byte(0xFF); bv2.push_byte(0x00); bv2.push_byte(0xAA); assert_eq!(bv2.count_ones(), 12);
1277 assert_eq!(bv2.count_zeros(), 12);
1278 assert_eq!(bv2.len(), 24);
1279 }
1280
1281 #[test]
1282 fn test_set_all() {
1283 let mut bv: BitMap<1> = BitMap::new();
1284
1285 bv.push(true);
1287 bv.push(false);
1288 bv.push(true);
1289 bv.push(false);
1290 bv.push(true);
1291 bv.push(false);
1292 bv.push(true);
1293 bv.push(false);
1294 bv.push(true);
1295 bv.push(false);
1296
1297 assert_eq!(bv.len(), 10);
1298 assert_eq!(bv.count_ones(), 5);
1299 assert_eq!(bv.count_zeros(), 5);
1300
1301 bv.set_all(true);
1303 assert_eq!(bv.len(), 10);
1304 assert_eq!(bv.count_ones(), 10);
1305 assert_eq!(bv.count_zeros(), 0);
1306
1307 bv.set_all(false);
1309 assert_eq!(bv.len(), 10);
1310 assert_eq!(bv.count_ones(), 0);
1311 assert_eq!(bv.count_zeros(), 10);
1312 }
1313
1314 #[test]
1315 fn test_flip_all() {
1316 let mut bv: BitMap<4> = BitMap::new();
1317
1318 bv.push(true);
1319 bv.push(false);
1320 bv.push(true);
1321 bv.push(false);
1322 bv.push(true);
1323
1324 let original_ones = bv.count_ones();
1325 let original_zeros = bv.count_zeros();
1326 let original_len = bv.len();
1327
1328 bv.flip_all();
1329
1330 assert_eq!(bv.len(), original_len);
1332
1333 assert_eq!(bv.count_ones(), original_zeros);
1335 assert_eq!(bv.count_zeros(), original_ones);
1336
1337 assert!(!bv.get(0));
1339 assert!(bv.get(1));
1340 assert!(!bv.get(2));
1341 assert!(bv.get(3));
1342 assert!(!bv.get(4));
1343 }
1344
1345 #[test]
1346 fn test_bitwise_and() {
1347 let mut bv1: BitMap<4> = BitMap::new();
1348 let mut bv2: BitMap<4> = BitMap::new();
1349
1350 let pattern1 = [true, false, true, true, false];
1352 let pattern2 = [true, true, false, true, false];
1353 let expected = [true, false, false, true, false];
1354
1355 for &bit in &pattern1 {
1356 bv1.push(bit);
1357 }
1358 for &bit in &pattern2 {
1359 bv2.push(bit);
1360 }
1361
1362 bv1.and(&bv2);
1363
1364 assert_eq!(bv1.len(), 5);
1365 for (i, &expected_bit) in expected.iter().enumerate() {
1366 assert_eq!(bv1.get(i as u64), expected_bit);
1367 }
1368 }
1369
1370 #[test]
1371 fn test_bitwise_or() {
1372 let mut bv1: BitMap<4> = BitMap::new();
1373 let mut bv2: BitMap<4> = BitMap::new();
1374
1375 let pattern1 = [true, false, true, true, false];
1377 let pattern2 = [true, true, false, true, false];
1378 let expected = [true, true, true, true, false];
1379
1380 for &bit in &pattern1 {
1381 bv1.push(bit);
1382 }
1383 for &bit in &pattern2 {
1384 bv2.push(bit);
1385 }
1386
1387 bv1.or(&bv2);
1388
1389 assert_eq!(bv1.len(), 5);
1390 for (i, &expected_bit) in expected.iter().enumerate() {
1391 assert_eq!(bv1.get(i as u64), expected_bit);
1392 }
1393 }
1394
1395 #[test]
1396 fn test_bitwise_xor() {
1397 let mut bv1: BitMap<4> = BitMap::new();
1398 let mut bv2: BitMap<4> = BitMap::new();
1399
1400 let pattern1 = [true, false, true, true, false];
1402 let pattern2 = [true, true, false, true, false];
1403 let expected = [false, true, true, false, false];
1404
1405 for &bit in &pattern1 {
1406 bv1.push(bit);
1407 }
1408 for &bit in &pattern2 {
1409 bv2.push(bit);
1410 }
1411
1412 bv1.xor(&bv2);
1413
1414 assert_eq!(bv1.len(), 5);
1415 for (i, &expected_bit) in expected.iter().enumerate() {
1416 assert_eq!(bv1.get(i as u64), expected_bit);
1417 }
1418 }
1419
1420 #[test]
1421 fn test_multi_chunk_operations() {
1422 let mut bv1: BitMap<4> = BitMap::new();
1423 let mut bv2: BitMap<4> = BitMap::new();
1424
1425 let chunk1 = hex!("0xAABBCCDD"); let chunk2 = hex!("0x55667788"); bv1.push_chunk(&chunk1);
1430 bv1.push_chunk(&chunk1);
1431 bv2.push_chunk(&chunk2);
1432 bv2.push_chunk(&chunk2);
1433
1434 assert_eq!(bv1.len(), 64);
1435 assert_eq!(bv2.len(), 64);
1436
1437 let mut bv_and = bv1.clone();
1439 bv_and.and(&bv2);
1440
1441 let mut bv_or = bv1.clone();
1443 bv_or.or(&bv2);
1444
1445 let mut bv_xor = bv1.clone();
1447 bv_xor.xor(&bv2);
1448
1449 assert_eq!(bv_and.len(), 64);
1451 assert_eq!(bv_or.len(), 64);
1452 assert_eq!(bv_xor.len(), 64);
1453
1454 assert!(bv_and.count_ones() <= bv1.count_ones());
1456 assert!(bv_and.count_ones() <= bv2.count_ones());
1457
1458 assert!(bv_or.count_ones() >= bv1.count_ones());
1460 assert!(bv_or.count_ones() >= bv2.count_ones());
1461 }
1462
1463 #[test]
1464 fn test_partial_chunk_operations() {
1465 let mut bv1: BitMap<4> = BitMap::new();
1466 let mut bv2: BitMap<4> = BitMap::new();
1467
1468 for i in 0..35 {
1470 bv1.push(i % 2 == 0);
1472 bv2.push(i % 3 == 0);
1473 }
1474
1475 assert_eq!(bv1.len(), 35);
1476 assert_eq!(bv2.len(), 35);
1477
1478 let mut bv_and = bv1.clone();
1480 bv_and.and(&bv2);
1481
1482 let mut bv_or = bv1.clone();
1483 bv_or.or(&bv2);
1484
1485 let mut bv_xor = bv1.clone();
1486 bv_xor.xor(&bv2);
1487
1488 assert_eq!(bv_and.len(), 35);
1490 assert_eq!(bv_or.len(), 35);
1491 assert_eq!(bv_xor.len(), 35);
1492
1493 let mut bv_inv = bv1.clone();
1495 let original_ones = bv_inv.count_ones();
1496 let original_zeros = bv_inv.count_zeros();
1497 bv_inv.flip_all();
1498 assert_eq!(bv_inv.count_ones(), original_zeros);
1499 assert_eq!(bv_inv.count_zeros(), original_ones);
1500 }
1501
1502 #[test]
1503 #[should_panic(expected = "bit 1 out of bounds (len: 1)")]
1504 fn test_flip_out_of_bounds() {
1505 let mut bv: BitMap<4> = BitMap::new();
1506 bv.push(true);
1507 bv.flip(1); }
1509
1510 #[test]
1511 #[should_panic(expected = "BitMap lengths don't match: 2 vs 1")]
1512 fn test_and_length_mismatch() {
1513 let mut bv1: BitMap<4> = BitMap::new();
1514 let mut bv2: BitMap<4> = BitMap::new();
1515
1516 bv1.push(true);
1517 bv1.push(false);
1518 bv2.push(true); bv1.and(&bv2);
1521 }
1522
1523 #[test]
1524 #[should_panic(expected = "BitMap lengths don't match: 1 vs 2")]
1525 fn test_or_length_mismatch() {
1526 let mut bv1: BitMap<4> = BitMap::new();
1527 let mut bv2: BitMap<4> = BitMap::new();
1528
1529 bv1.push(true);
1530 bv2.push(true);
1531 bv2.push(false); bv1.or(&bv2);
1534 }
1535
1536 #[test]
1537 #[should_panic(expected = "BitMap lengths don't match: 3 vs 2")]
1538 fn test_xor_length_mismatch() {
1539 let mut bv1: BitMap<4> = BitMap::new();
1540 let mut bv2: BitMap<4> = BitMap::new();
1541
1542 bv1.push(true);
1543 bv1.push(false);
1544 bv1.push(true);
1545 bv2.push(true);
1546 bv2.push(false); bv1.xor(&bv2);
1549 }
1550
1551 #[test]
1552 fn test_equality() {
1553 assert_eq!(BitMap::<4>::new(), BitMap::<4>::new());
1555 assert_eq!(BitMap::<8>::new(), BitMap::<8>::new());
1556
1557 let pattern = [true, false, true, true, false, false, true, false, true];
1559 let bv4: BitMap<4> = pattern.as_ref().into();
1560 assert_eq!(bv4, BitMap::<4>::from(pattern.as_ref()));
1561 let bv8: BitMap<8> = pattern.as_ref().into();
1562 assert_eq!(bv8, BitMap::<8>::from(pattern.as_ref()));
1563
1564 let mut bv1: BitMap<4> = BitMap::new();
1566 let mut bv2: BitMap<4> = BitMap::new();
1567 for i in 0..33 {
1568 let bit = i % 3 == 0;
1569 bv1.push(bit);
1570 bv2.push(bit);
1571 }
1572 assert_eq!(bv1, bv2);
1573
1574 bv1.push(true);
1576 assert_ne!(bv1, bv2);
1577 bv1.pop(); assert_eq!(bv1, bv2);
1579
1580 bv1.flip(15);
1582 assert_ne!(bv1, bv2);
1583 bv1.flip(15); assert_eq!(bv1, bv2);
1585
1586 let mut bv_ops1 = BitMap::<16>::ones(25);
1588 let mut bv_ops2 = BitMap::<16>::ones(25);
1589 bv_ops1.flip_all();
1590 bv_ops2.flip_all();
1591 assert_eq!(bv_ops1, bv_ops2);
1592
1593 let mask_bits: Vec<bool> = (0..33).map(|i| i % 3 == 0).collect();
1594 let mask = BitMap::<4>::from(mask_bits);
1595 bv1.and(&mask);
1596 bv2.and(&mask);
1597 assert_eq!(bv1, bv2);
1598 }
1599
1600 #[test]
1601 fn test_different_chunk_sizes() {
1602 let mut bv8: BitMap<8> = BitMap::new();
1604 let mut bv16: BitMap<16> = BitMap::new();
1605 let mut bv32: BitMap<32> = BitMap::new();
1606
1607 let chunk8 = [0xFF; 8];
1609 let chunk16 = [0xAA; 16];
1610 let chunk32 = [0x55; 32];
1611
1612 bv8.push_chunk(&chunk8);
1613 bv16.push_chunk(&chunk16);
1614 bv32.push_chunk(&chunk32);
1615
1616 bv8.push(true);
1618 bv8.push(false);
1619 assert_eq!(bv8.len(), 64 + 2);
1620 assert_eq!(bv8.count_ones(), 64 + 1); assert_eq!(bv8.count_zeros(), 1);
1622
1623 bv16.push(true);
1624 bv16.push(false);
1625 assert_eq!(bv16.len(), 128 + 2);
1626 assert_eq!(bv16.count_ones(), 64 + 1); assert_eq!(bv16.count_zeros(), 64 + 1);
1628
1629 bv32.push(true);
1630 bv32.push(false);
1631 assert_eq!(bv32.len(), 256 + 2);
1632 assert_eq!(bv32.count_ones(), 128 + 1); assert_eq!(bv32.count_zeros(), 128 + 1);
1634 }
1635
1636 #[test]
1637 fn test_iterator() {
1638 let bv: BitMap<4> = BitMap::new();
1640 let mut iter = bv.iter();
1641 assert_eq!(iter.next(), None);
1642 assert_eq!(iter.size_hint(), (0, Some(0)));
1643
1644 let pattern = [true, false, true, false, true];
1646 let bv: BitMap<4> = pattern.as_ref().into();
1647
1648 let collected: Vec<bool> = bv.iter().collect();
1650 assert_eq!(collected, pattern);
1651
1652 let mut iter = bv.iter();
1654 assert_eq!(iter.size_hint(), (5, Some(5)));
1655
1656 assert_eq!(iter.next(), Some(true));
1658 assert_eq!(iter.size_hint(), (4, Some(4)));
1659
1660 let iter = bv.iter();
1662 assert_eq!(iter.len(), 5);
1663
1664 let mut large_bv: BitMap<8> = BitMap::new();
1666 for i in 0..100 {
1667 large_bv.push(i % 3 == 0);
1668 }
1669
1670 let collected: Vec<bool> = large_bv.iter().collect();
1671 assert_eq!(collected.len(), 100);
1672 for (i, &bit) in collected.iter().enumerate() {
1673 assert_eq!(bit, i % 3 == 0);
1674 }
1675 }
1676
1677 #[test]
1678 fn test_iterator_edge_cases() {
1679 let mut bv: BitMap<4> = BitMap::new();
1681 bv.push(true);
1682
1683 let collected: Vec<bool> = bv.iter().collect();
1684 assert_eq!(collected, vec![true]);
1685
1686 let mut bv: BitMap<4> = BitMap::new();
1688 for i in 0..32 {
1690 bv.push(i % 2 == 0);
1691 }
1692 bv.push(true);
1694 bv.push(false);
1695 bv.push(true);
1696
1697 let collected: Vec<bool> = bv.iter().collect();
1698 assert_eq!(collected.len(), 35);
1699
1700 for (i, &bit) in collected.iter().enumerate().take(32) {
1702 assert_eq!(bit, i % 2 == 0);
1703 }
1704 assert!(collected[32]);
1705 assert!(!collected[33]);
1706 assert!(collected[34]);
1707 }
1708
1709 #[test]
1710 fn test_codec_roundtrip() {
1711 let original: BitMap<4> = BitMap::new();
1713 let encoded = original.encode();
1714 let decoded = BitMap::decode_cfg(&mut encoded.as_ref(), &(usize::MAX as u64)).unwrap();
1715 assert_eq!(original, decoded);
1716
1717 let pattern = [true, false, true, false, true];
1719 let original: BitMap<4> = pattern.as_ref().into();
1720 let encoded = original.encode();
1721 let decoded = BitMap::decode_cfg(&mut encoded.as_ref(), &(usize::MAX as u64)).unwrap();
1722 assert_eq!(original, decoded);
1723
1724 for (i, &expected) in pattern.iter().enumerate() {
1726 assert_eq!(decoded.get(i as u64), expected);
1727 }
1728
1729 let mut large_original: BitMap<8> = BitMap::new();
1731 for i in 0..100 {
1732 large_original.push(i % 7 == 0);
1733 }
1734
1735 let encoded = large_original.encode();
1736 let decoded = BitMap::decode_cfg(&mut encoded.as_ref(), &(usize::MAX as u64)).unwrap();
1737 assert_eq!(large_original, decoded);
1738
1739 assert_eq!(decoded.len(), 100);
1741 for i in 0..100 {
1742 assert_eq!(decoded.get(i as u64), i % 7 == 0);
1743 }
1744 }
1745
1746 #[test]
1747 fn test_codec_different_chunk_sizes() {
1748 let pattern = [true, false, true, true, false, false, true];
1749
1750 let bv4: BitMap<4> = pattern.as_ref().into();
1752 let bv8: BitMap<8> = pattern.as_ref().into();
1753 let bv16: BitMap<16> = pattern.as_ref().into();
1754
1755 let encoded4 = bv4.encode();
1757 let decoded4 = BitMap::decode_cfg(&mut encoded4.as_ref(), &(usize::MAX as u64)).unwrap();
1758 assert_eq!(bv4, decoded4);
1759
1760 let encoded8 = bv8.encode();
1761 let decoded8 = BitMap::decode_cfg(&mut encoded8.as_ref(), &(usize::MAX as u64)).unwrap();
1762 assert_eq!(bv8, decoded8);
1763
1764 let encoded16 = bv16.encode();
1765 let decoded16 = BitMap::decode_cfg(&mut encoded16.as_ref(), &(usize::MAX as u64)).unwrap();
1766 assert_eq!(bv16, decoded16);
1767
1768 for (i, &expected) in pattern.iter().enumerate() {
1770 let i = i as u64;
1771 assert_eq!(decoded4.get(i), expected);
1772 assert_eq!(decoded8.get(i), expected);
1773 assert_eq!(decoded16.get(i), expected);
1774 }
1775 }
1776
1777 #[test]
1778 fn test_codec_edge_cases() {
1779 let mut bv: BitMap<4> = BitMap::new();
1781 for i in 0..32 {
1782 bv.push(i % 2 == 0);
1783 }
1784
1785 let encoded = bv.encode();
1786 let decoded = BitMap::decode_cfg(&mut encoded.as_ref(), &(usize::MAX as u64)).unwrap();
1787 assert_eq!(bv, decoded);
1788 assert_eq!(decoded.len(), 32);
1789
1790 let mut bv2: BitMap<4> = BitMap::new();
1792 for i in 0..35 {
1793 bv2.push(i % 3 == 0);
1795 }
1796
1797 let encoded2 = bv2.encode();
1798 let decoded2 = BitMap::decode_cfg(&mut encoded2.as_ref(), &(usize::MAX as u64)).unwrap();
1799 assert_eq!(bv2, decoded2);
1800 assert_eq!(decoded2.len(), 35);
1801 }
1802
1803 #[test]
1804 fn test_encode_size() {
1805 let bv: BitMap<4> = BitMap::new();
1807 let encoded = bv.encode();
1808 assert_eq!(bv.encode_size(), encoded.len());
1809
1810 let pattern = [true, false, true, false, true];
1812 let bv: BitMap<4> = pattern.as_ref().into();
1813 let encoded = bv.encode();
1814 assert_eq!(bv.encode_size(), encoded.len());
1815
1816 let mut large_bv: BitMap<8> = BitMap::new();
1818 for i in 0..100 {
1819 large_bv.push(i % 2 == 0);
1820 }
1821 let encoded = large_bv.encode();
1822 assert_eq!(large_bv.encode_size(), encoded.len());
1823 }
1824
1825 #[test]
1826 fn test_codec_empty_chunk_optimization() {
1827 let bv_empty: BitMap<4> = BitMap::new();
1831 let encoded_empty = bv_empty.encode();
1832 let decoded_empty: BitMap<4> =
1833 BitMap::decode_cfg(&mut encoded_empty.as_ref(), &(usize::MAX as u64)).unwrap();
1834 assert_eq!(bv_empty, decoded_empty);
1835 assert_eq!(bv_empty.len(), decoded_empty.len());
1836 assert_eq!(encoded_empty.len(), bv_empty.len().encode_size());
1838
1839 let mut bv_exact: BitMap<4> = BitMap::new();
1841 for _ in 0..32 {
1842 bv_exact.push(true);
1843 }
1844 let encoded_exact = bv_exact.encode();
1845 let decoded_exact: BitMap<4> =
1846 BitMap::decode_cfg(&mut encoded_exact.as_ref(), &(usize::MAX as u64)).unwrap();
1847 assert_eq!(bv_exact, decoded_exact);
1848
1849 let mut bv_partial: BitMap<4> = BitMap::new();
1851 for _ in 0..35 {
1852 bv_partial.push(true);
1853 }
1854 let encoded_partial = bv_partial.encode();
1855 let decoded_partial: BitMap<4> =
1856 BitMap::decode_cfg(&mut encoded_partial.as_ref(), &(usize::MAX as u64)).unwrap();
1857 assert_eq!(bv_partial, decoded_partial);
1858 assert_eq!(bv_partial.len(), decoded_partial.len());
1859
1860 assert!(encoded_exact.len() < encoded_partial.len());
1862 assert_eq!(encoded_exact.len(), bv_exact.len().encode_size() + 4); assert_eq!(encoded_partial.len(), bv_partial.len().encode_size() + 8); }
1865
1866 #[test]
1867 fn test_codec_error_cases() {
1868 let mut buf = BytesMut::new();
1870 100u64.write(&mut buf); for _ in 0..4 {
1874 [0u8; 4].write(&mut buf);
1875 }
1876
1877 let result = BitMap::<4>::decode_cfg(&mut buf, &99);
1879 assert!(matches!(result, Err(CodecError::InvalidLength(100))));
1880
1881 let mut buf = BytesMut::new();
1883 100u64.write(&mut buf); [0u8; 4].write(&mut buf);
1886 [0u8; 4].write(&mut buf);
1887 [0u8; 4].write(&mut buf);
1888
1889 let result = BitMap::<4>::decode_cfg(&mut buf, &(usize::MAX as u64));
1890 assert!(result.is_err());
1892
1893 let original: BitMap<4> = BitMap::ones(20);
1897 let mut buf = BytesMut::new();
1898 original.write(&mut buf);
1899
1900 let corrupted_data = buf.freeze();
1902 let mut corrupted_bytes = corrupted_data.to_vec();
1903
1904 let last_byte_idx = corrupted_bytes.len() - 1;
1908 corrupted_bytes[last_byte_idx] |= 0xF0;
1909
1910 let result = BitMap::<4>::read_cfg(&mut corrupted_bytes.as_slice(), &(usize::MAX as u64));
1912 assert!(matches!(
1913 result,
1914 Err(CodecError::Invalid(
1915 "BitMap",
1916 "Invalid trailing bits in encoded data"
1917 ))
1918 ));
1919 }
1920
1921 #[test]
1922 fn test_codec_range_config() {
1923 let mut original: BitMap<4> = BitMap::new();
1927 for i in 0..100 {
1928 original.push(i % 3 == 0);
1929 }
1930
1931 let mut buf = BytesMut::new();
1933 original.write(&mut buf);
1934
1935 let result = BitMap::<4>::decode_cfg(&mut buf.as_ref(), &50);
1937 assert!(matches!(result, Err(CodecError::InvalidLength(100))));
1938
1939 let decoded = BitMap::<4>::decode_cfg(&mut buf.as_ref(), &100).unwrap();
1941 assert_eq!(decoded.len(), 100);
1942 assert_eq!(decoded, original);
1943
1944 let decoded = BitMap::<4>::decode_cfg(&mut buf.as_ref(), &101).unwrap();
1946 assert_eq!(decoded.len(), 100);
1947 assert_eq!(decoded, original);
1948
1949 let empty = BitMap::<4>::new();
1951 let mut buf = BytesMut::new();
1952 empty.write(&mut buf);
1953
1954 let decoded = BitMap::<4>::decode_cfg(&mut buf.as_ref(), &0).unwrap();
1956 assert_eq!(decoded.len(), 0);
1957 assert!(decoded.is_empty());
1958
1959 let decoded = BitMap::<4>::decode_cfg(&mut buf.as_ref(), &1).unwrap();
1961 assert_eq!(decoded.len(), 0);
1962 assert!(decoded.is_empty());
1963 }
1964
1965 #[test]
1966 fn test_from() {
1967 let vec_bool = vec![true, false, true, false, true];
1971 let bv: BitMap<4> = vec_bool.into();
1972 assert_eq!(bv.len(), 5);
1973 assert_eq!(bv.count_ones(), 3);
1974 assert_eq!(bv.count_zeros(), 2);
1975 for (i, &expected) in [true, false, true, false, true].iter().enumerate() {
1976 assert_eq!(bv.get(i as u64), expected);
1977 }
1978
1979 let array = [false, true, true, false];
1981 let bv: BitMap<4> = (&array).into();
1982 assert_eq!(bv.len(), 4);
1983 assert_eq!(bv.count_ones(), 2);
1984 assert_eq!(bv.count_zeros(), 2);
1985 for (i, &expected) in array.iter().enumerate() {
1986 assert_eq!(bv.get(i as u64), expected);
1987 }
1988
1989 let empty: Vec<bool> = vec![];
1991 let bv: BitMap<4> = empty.into();
1992 assert_eq!(bv.len(), 0);
1993 assert!(bv.is_empty());
1994
1995 let large: Vec<bool> = (0..100).map(|i| i % 3 == 0).collect();
1997 let bv: BitMap<8> = large.clone().into();
1998 assert_eq!(bv.len(), 100);
1999 for (i, &expected) in large.iter().enumerate() {
2000 assert_eq!(bv.get(i as u64), expected);
2001 }
2002 }
2003
2004 #[test]
2005 fn test_debug_formatting() {
2006 let bv: BitMap<4> = BitMap::new();
2010 let debug_str = format!("{bv:?}");
2011 assert_eq!(debug_str, "BitMap[]");
2012
2013 let bv: BitMap<4> = [true, false, true, false, true].as_ref().into();
2015 let debug_str = format!("{bv:?}");
2016 assert_eq!(debug_str, "BitMap[10101]");
2017
2018 let pattern: Vec<bool> = (0..64).map(|i| i % 2 == 0).collect();
2020 let bv: BitMap<8> = pattern.into();
2021 let debug_str = format!("{bv:?}");
2022 let expected_pattern = "1010".repeat(16); assert_eq!(debug_str, format!("BitMap[{expected_pattern}]"));
2024
2025 let large_pattern: Vec<bool> = (0..100).map(|i| i % 2 == 0).collect();
2027 let bv: BitMap<16> = large_pattern.into();
2028 let debug_str = format!("{bv:?}");
2029
2030 let first_32 = "10".repeat(16); let last_32 = "10".repeat(16); let expected = format!("BitMap[{first_32}...{last_32}]");
2034 assert_eq!(debug_str, expected);
2035
2036 let bv: BitMap<4> = [true].as_ref().into();
2038 assert_eq!(format!("{bv:?}"), "BitMap[1]");
2039
2040 let bv: BitMap<4> = [false].as_ref().into();
2041 assert_eq!(format!("{bv:?}"), "BitMap[0]");
2042
2043 let pattern: Vec<bool> = (0..65).map(|i| i == 0 || i == 64).collect(); let bv: BitMap<16> = pattern.into();
2046 let debug_str = format!("{bv:?}");
2047
2048 let first_32 = "1".to_string() + &"0".repeat(31);
2050 let last_32 = "0".repeat(31) + "1";
2051 let expected = format!("BitMap[{first_32}...{last_32}]");
2052 assert_eq!(debug_str, expected);
2053 }
2054
2055 #[test]
2056 fn test_from_different_chunk_sizes() {
2057 let pattern = [true, false, true, true, false, false, true];
2059
2060 let bv4: BitMap<4> = pattern.as_ref().into();
2061 let bv8: BitMap<8> = pattern.as_ref().into();
2062 let bv16: BitMap<16> = pattern.as_ref().into();
2063
2064 for bv in [&bv4] {
2067 assert_eq!(bv.len(), 7);
2068 assert_eq!(bv.count_ones(), 4);
2069 assert_eq!(bv.count_zeros(), 3);
2070 for (i, &expected) in pattern.iter().enumerate() {
2071 assert_eq!(bv.get(i as u64), expected);
2072 }
2073 }
2074
2075 assert_eq!(bv8.len(), 7);
2076 assert_eq!(bv8.count_ones(), 4);
2077 assert_eq!(bv8.count_zeros(), 3);
2078 for (i, &expected) in pattern.iter().enumerate() {
2079 assert_eq!(bv8.get(i as u64), expected);
2080 }
2081
2082 assert_eq!(bv16.len(), 7);
2083 assert_eq!(bv16.count_ones(), 4);
2084 assert_eq!(bv16.count_zeros(), 3);
2085 for (i, &expected) in pattern.iter().enumerate() {
2086 assert_eq!(bv16.get(i as u64), expected);
2087 }
2088 }
2089
2090 #[test]
2091 fn test_prune_chunks() {
2092 let mut bv: BitMap<4> = BitMap::new();
2093 bv.push_chunk(&[1, 2, 3, 4]);
2094 bv.push_chunk(&[5, 6, 7, 8]);
2095 bv.push_chunk(&[9, 10, 11, 12]);
2096
2097 assert_eq!(bv.len(), 96);
2098 assert_eq!(bv.get_chunk(0), &[1, 2, 3, 4]);
2099
2100 bv.prune_chunks(1);
2102 assert_eq!(bv.len(), 64);
2103 assert_eq!(bv.get_chunk(0), &[5, 6, 7, 8]);
2104 assert_eq!(bv.get_chunk(1), &[9, 10, 11, 12]);
2105
2106 bv.prune_chunks(1);
2108 assert_eq!(bv.len(), 32);
2109 assert_eq!(bv.get_chunk(0), &[9, 10, 11, 12]);
2110 }
2111
2112 #[test]
2113 #[should_panic(expected = "cannot prune")]
2114 fn test_prune_too_many_chunks() {
2115 let mut bv: BitMap<4> = BitMap::new();
2116 bv.push_chunk(&[1, 2, 3, 4]);
2117 bv.push_chunk(&[5, 6, 7, 8]);
2118 bv.push(true);
2119
2120 bv.prune_chunks(4);
2122 }
2123
2124 #[test]
2125 fn test_prune_with_partial_last_chunk() {
2126 let mut bv: BitMap<4> = BitMap::new();
2127 bv.push_chunk(&[1, 2, 3, 4]);
2128 bv.push_chunk(&[5, 6, 7, 8]);
2129 bv.push(true);
2130 bv.push(false);
2131
2132 assert_eq!(bv.len(), 66);
2133
2134 bv.prune_chunks(1);
2136 assert_eq!(bv.len(), 34);
2137 assert_eq!(bv.get_chunk(0), &[5, 6, 7, 8]);
2138
2139 assert!(bv.get(32));
2141 assert!(!bv.get(33));
2142 }
2143
2144 #[test]
2145 fn test_prune_all_chunks_resets_next_bit() {
2146 let mut bv: BitMap<4> = BitMap::new();
2147 bv.push_chunk(&[1, 2, 3, 4]);
2148 bv.push_chunk(&[5, 6, 7, 8]);
2149 bv.push(true);
2150 bv.push(false);
2151 bv.push(true);
2152
2153 assert_eq!(bv.len(), 67);
2155
2156 bv.prune_chunks(3);
2158
2159 assert_eq!(bv.len(), 0);
2161 assert!(bv.is_empty());
2162
2163 bv.push(true);
2165 assert_eq!(bv.len(), 1);
2166 assert!(bv.get(0));
2167 }
2168
2169 #[test]
2170 fn test_is_chunk_aligned() {
2171 let bv: BitMap<4> = BitMap::new();
2173 assert!(bv.is_chunk_aligned());
2174
2175 let mut bv4: BitMap<4> = BitMap::new();
2177 assert!(bv4.is_chunk_aligned());
2178
2179 for i in 1..=32 {
2181 bv4.push(i % 2 == 0);
2182 if i == 32 {
2183 assert!(bv4.is_chunk_aligned()); } else {
2185 assert!(!bv4.is_chunk_aligned()); }
2187 }
2188
2189 for i in 33..=64 {
2191 bv4.push(i % 2 == 0);
2192 if i == 64 {
2193 assert!(bv4.is_chunk_aligned()); } else {
2195 assert!(!bv4.is_chunk_aligned()); }
2197 }
2198
2199 let mut bv: BitMap<8> = BitMap::new();
2201 assert!(bv.is_chunk_aligned());
2202 bv.push_chunk(&[0xFF; 8]);
2203 assert!(bv.is_chunk_aligned()); bv.push_chunk(&[0xAA; 8]);
2205 assert!(bv.is_chunk_aligned()); bv.push(true);
2207 assert!(!bv.is_chunk_aligned()); let mut bv: BitMap<4> = BitMap::new();
2211 for _ in 0..4 {
2212 bv.push_byte(0xFF);
2213 }
2214 assert!(bv.is_chunk_aligned()); bv.pop();
2218 assert!(!bv.is_chunk_aligned()); let bv_zeroes: BitMap<4> = BitMap::zeroes(64);
2222 assert!(bv_zeroes.is_chunk_aligned());
2223
2224 let bv_ones: BitMap<4> = BitMap::ones(96);
2225 assert!(bv_ones.is_chunk_aligned());
2226
2227 let bv_partial: BitMap<4> = BitMap::zeroes(65);
2228 assert!(!bv_partial.is_chunk_aligned());
2229 }
2230
2231 #[test]
2232 fn test_unprune_restores_length() {
2233 let mut prunable: Prunable<4> = Prunable::new_with_pruned_chunks(1).unwrap();
2234 assert_eq!(prunable.len(), Prunable::<4>::CHUNK_SIZE_BITS);
2235 assert_eq!(prunable.pruned_chunks(), 1);
2236 let chunk = [0xDE, 0xAD, 0xBE, 0xEF];
2237
2238 prunable.unprune_chunks(&[chunk]);
2239
2240 assert_eq!(prunable.pruned_chunks(), 0);
2241 assert_eq!(prunable.len(), Prunable::<4>::CHUNK_SIZE_BITS);
2242 assert_eq!(prunable.get_chunk_containing(0), &chunk);
2243 }
2244
2245 mod proptests {
2246 use super::*;
2247 use proptest::prelude::*;
2248
2249 proptest! {
2250 #[test]
2251 fn is_unset_matches_naive(
2252 bits in prop::collection::vec(any::<bool>(), 1..=512usize),
2253 start in 0u64..=512,
2254 end in 0u64..=512,
2255 ) {
2256 let bitmap: BitMap = BitMap::from(bits.as_slice());
2257 let len = bitmap.len();
2258 let start = start.min(len);
2259 let end = end.max(start).min(len);
2260 let range = start..end;
2261
2262 let expected = range.clone().all(|i| !bitmap.get(i));
2263
2264 prop_assert_eq!(bitmap.is_unset(range), expected);
2265 }
2266 }
2267 }
2268
2269 #[test]
2270 fn is_unset_all_zeros() {
2271 let bitmap = BitMap::<8>::zeroes(256);
2272 assert!(bitmap.is_unset(0..256));
2273 }
2274
2275 #[test]
2276 fn is_unset_all_ones() {
2277 let bitmap = BitMap::<8>::ones(256);
2278 assert!(!bitmap.is_unset(0..256));
2279 }
2280
2281 #[test]
2282 fn is_unset_single_bit() {
2283 let mut bitmap = BitMap::<8>::zeroes(64);
2284 bitmap.set(31, true);
2285 assert!(bitmap.is_unset(0..31));
2286 assert!(!bitmap.is_unset(0..32));
2287 assert!(!bitmap.is_unset(31..32));
2288 assert!(bitmap.is_unset(32..64));
2289 }
2290
2291 #[test]
2292 fn is_unset_empty_range() {
2293 let bitmap = BitMap::<8>::ones(64);
2294 assert!(bitmap.is_unset(0..0));
2295 assert!(bitmap.is_unset(32..32));
2296 assert!(bitmap.is_unset(64..64));
2297 }
2298
2299 #[test]
2300 fn is_unset_chunk_boundaries() {
2301 let mut bitmap = BitMap::<1>::zeroes(32);
2303 bitmap.set(7, true);
2304 assert!(bitmap.is_unset(0..7));
2305 assert!(!bitmap.is_unset(0..8));
2306 assert!(bitmap.is_unset(8..32));
2307 }
2308
2309 #[test]
2310 fn is_unset_small_chunk_multi_span() {
2311 let mut bitmap = BitMap::<4>::zeroes(128);
2313 bitmap.set(96, true);
2314 assert!(bitmap.is_unset(0..96));
2315 assert!(!bitmap.is_unset(0..97));
2316 assert!(bitmap.is_unset(97..128));
2317 }
2318
2319 #[test]
2320 #[should_panic(expected = "out of bounds")]
2321 fn is_unset_out_of_bounds() {
2322 let bitmap = BitMap::<8>::zeroes(64);
2323 bitmap.is_unset(0..65);
2324 }
2325
2326 #[cfg(feature = "arbitrary")]
2327 mod conformance {
2328 use super::*;
2329 use commonware_codec::conformance::CodecConformance;
2330
2331 commonware_conformance::conformance_tests! {
2332 CodecConformance<BitMap>
2333 }
2334 }
2335}