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;
22commonware_macros::stability_mod!(ALPHA, pub mod roaring);
23
24pub const DEFAULT_CHUNK_SIZE: usize = 8;
26
27#[derive(Clone, PartialEq, Eq, Hash)]
34pub struct BitMap<const N: usize = DEFAULT_CHUNK_SIZE> {
35 chunks: VecDeque<[u8; N]>,
41
42 len: u64,
44}
45
46impl<const N: usize> BitMap<N> {
47 const _CHUNK_SIZE_NON_ZERO_ASSERT: () = assert!(N > 0, "chunk size must be > 0");
48
49 pub const CHUNK_SIZE_BITS: u64 = (N * 8) as u64;
51
52 const EMPTY_CHUNK: [u8; N] = [0u8; N];
54
55 const FULL_CHUNK: [u8; N] = [u8::MAX; N];
57
58 pub const fn new() -> Self {
62 #[allow(path_statements)]
63 Self::_CHUNK_SIZE_NON_ZERO_ASSERT; Self {
66 chunks: VecDeque::new(),
67 len: 0,
68 }
69 }
70
71 pub fn with_capacity(size: u64) -> Self {
73 #[allow(path_statements)]
74 Self::_CHUNK_SIZE_NON_ZERO_ASSERT; Self {
77 chunks: VecDeque::with_capacity(size.div_ceil(Self::CHUNK_SIZE_BITS) as usize),
78 len: 0,
79 }
80 }
81
82 pub fn zeroes(size: u64) -> Self {
84 #[allow(path_statements)]
85 Self::_CHUNK_SIZE_NON_ZERO_ASSERT; let num_chunks = size.div_ceil(Self::CHUNK_SIZE_BITS) as usize;
88 let mut chunks = VecDeque::with_capacity(num_chunks);
89 for _ in 0..num_chunks {
90 chunks.push_back(Self::EMPTY_CHUNK);
91 }
92 Self { chunks, len: size }
93 }
94
95 pub fn ones(size: u64) -> Self {
97 #[allow(path_statements)]
98 Self::_CHUNK_SIZE_NON_ZERO_ASSERT; let num_chunks = size.div_ceil(Self::CHUNK_SIZE_BITS) as usize;
101 let mut chunks = VecDeque::with_capacity(num_chunks);
102 for _ in 0..num_chunks {
103 chunks.push_back(Self::FULL_CHUNK);
104 }
105 let mut result = Self { chunks, len: size };
106 result.clear_trailing_bits();
108 result
109 }
110
111 #[inline]
115 pub const fn len(&self) -> u64 {
116 self.len
117 }
118
119 #[inline]
121 pub const fn is_empty(&self) -> bool {
122 self.len() == 0
123 }
124
125 #[inline]
127 pub const fn is_chunk_aligned(&self) -> bool {
128 self.len.is_multiple_of(Self::CHUNK_SIZE_BITS)
129 }
130
131 fn chunks_len(&self) -> usize {
133 self.chunks.len()
134 }
135
136 #[inline]
144 pub fn get(&self, bit: u64) -> bool {
145 let chunk = self.get_chunk_containing(bit);
146 Self::get_bit_from_chunk(chunk, bit)
147 }
148
149 #[inline]
155 fn get_chunk_containing(&self, bit: u64) -> &[u8; N] {
156 assert!(
157 bit < self.len(),
158 "bit {} out of bounds (len: {})",
159 bit,
160 self.len()
161 );
162 &self.chunks[Self::to_chunk_index(bit)]
163 }
164
165 #[inline]
172 pub(super) fn get_chunk(&self, chunk: usize) -> &[u8; N] {
173 assert!(
174 chunk < self.chunks.len(),
175 "chunk {} out of bounds (chunks: {})",
176 chunk,
177 self.chunks.len()
178 );
179 &self.chunks[chunk]
180 }
181
182 #[inline]
185 pub const fn get_bit_from_chunk(chunk: &[u8; N], bit: u64) -> bool {
186 let byte = Self::chunk_byte_offset(bit);
187 let byte = chunk[byte];
188 let mask = Self::chunk_byte_bitmask(bit);
189 (byte & mask) != 0
190 }
191
192 #[inline]
198 fn last_chunk(&self) -> (&[u8; N], u64) {
199 let rem = self.len % Self::CHUNK_SIZE_BITS;
200 let bits_in_last_chunk = if rem == 0 { Self::CHUNK_SIZE_BITS } else { rem };
201 (self.chunks.back().unwrap(), bits_in_last_chunk)
202 }
203
204 pub fn extend_to(&mut self, new_len: u64) {
209 if new_len <= self.len {
210 return;
211 }
212 let new_chunks_needed = new_len.div_ceil(Self::CHUNK_SIZE_BITS) as usize;
214 let current_chunks = self.chunks.len();
215 for _ in current_chunks..new_chunks_needed {
216 self.chunks.push_back(Self::EMPTY_CHUNK);
217 }
218 self.len = new_len;
219 }
220
221 pub fn push(&mut self, bit: bool) {
223 if self.is_chunk_aligned() {
225 self.chunks.push_back(Self::EMPTY_CHUNK);
226 }
227
228 if bit {
230 let last_chunk = self.chunks.back_mut().unwrap();
231 let chunk_byte = Self::chunk_byte_offset(self.len);
232 last_chunk[chunk_byte] |= Self::chunk_byte_bitmask(self.len);
233 }
234 self.len += 1;
236 }
237
238 pub fn pop(&mut self) -> bool {
244 assert!(!self.is_empty(), "Cannot pop from empty bitmap");
245
246 let last_bit_pos = self.len - 1;
248 let bit = Self::get_bit_from_chunk(self.chunks.back().unwrap(), last_bit_pos);
249
250 self.len -= 1;
252
253 if bit {
255 let chunk_byte = Self::chunk_byte_offset(last_bit_pos);
256 let mask = Self::chunk_byte_bitmask(last_bit_pos);
257 self.chunks.back_mut().unwrap()[chunk_byte] &= !mask;
258 }
259
260 if self.is_chunk_aligned() {
262 self.chunks.pop_back();
263 }
264
265 bit
266 }
267
268 pub fn truncate(&mut self, new_len: u64) {
274 assert!(new_len <= self.len(), "cannot truncate to a larger size");
275
276 while self.len > new_len && !self.is_chunk_aligned() {
278 self.pop();
279 }
280
281 while self.len - new_len >= Self::CHUNK_SIZE_BITS {
283 self.pop_chunk();
284 }
285
286 while self.len > new_len {
288 self.pop();
289 }
290 }
291
292 pub(super) fn pop_chunk(&mut self) -> [u8; N] {
298 assert!(
299 self.len() >= Self::CHUNK_SIZE_BITS,
300 "cannot pop chunk: bitmap has fewer than CHUNK_SIZE_BITS bits"
301 );
302 assert!(
303 self.is_chunk_aligned(),
304 "cannot pop chunk when not chunk aligned"
305 );
306
307 let chunk = self.chunks.pop_back().expect("chunk must exist");
309 self.len -= Self::CHUNK_SIZE_BITS;
310 chunk
311 }
312
313 #[inline]
319 pub fn flip(&mut self, bit: u64) {
320 self.assert_bit(bit);
321 let chunk = Self::to_chunk_index(bit);
322 let byte = Self::chunk_byte_offset(bit);
323 let mask = Self::chunk_byte_bitmask(bit);
324 self.chunks[chunk][byte] ^= mask;
325 }
326
327 pub fn flip_all(&mut self) {
329 for chunk in &mut self.chunks {
330 for byte in chunk {
331 *byte = !*byte;
332 }
333 }
334 self.clear_trailing_bits();
336 }
337
338 pub fn set(&mut self, bit: u64, value: bool) {
344 assert!(
345 bit < self.len(),
346 "bit {} out of bounds (len: {})",
347 bit,
348 self.len()
349 );
350
351 let chunk = &mut self.chunks[Self::to_chunk_index(bit)];
352 let byte = Self::chunk_byte_offset(bit);
353 let mask = Self::chunk_byte_bitmask(bit);
354 if value {
355 chunk[byte] |= mask;
356 } else {
357 chunk[byte] &= !mask;
358 }
359 }
360
361 #[inline]
363 pub fn set_all(&mut self, bit: bool) {
364 let value = if bit { u8::MAX } else { 0 };
365 for chunk in &mut self.chunks {
366 chunk.fill(value);
367 }
368 if bit {
370 self.clear_trailing_bits();
371 }
372 }
373
374 fn push_byte(&mut self, byte: u8) {
380 assert!(
381 self.len.is_multiple_of(8),
382 "cannot add byte when not byte aligned"
383 );
384
385 if self.is_chunk_aligned() {
387 self.chunks.push_back(Self::EMPTY_CHUNK);
388 }
389
390 let chunk_byte = Self::chunk_byte_offset(self.len);
391 self.chunks.back_mut().unwrap()[chunk_byte] = byte;
392 self.len += 8;
393 }
394
395 pub fn push_chunk(&mut self, chunk: &[u8; N]) {
401 assert!(
402 self.is_chunk_aligned(),
403 "cannot add chunk when not chunk aligned"
404 );
405 self.chunks.push_back(*chunk);
406 self.len += Self::CHUNK_SIZE_BITS;
407 }
408
409 fn clear_trailing_bits(&mut self) -> bool {
414 if self.chunks.is_empty() {
415 return false;
416 }
417
418 let pos_in_chunk = self.len % Self::CHUNK_SIZE_BITS;
419 if pos_in_chunk == 0 {
420 return false;
422 }
423
424 let mut flipped_any = false;
425 let last_chunk = self.chunks.back_mut().unwrap();
426
427 let last_byte_index = ((pos_in_chunk - 1) / 8) as usize;
429 for byte in last_chunk.iter_mut().skip(last_byte_index + 1) {
430 if *byte != 0 {
431 flipped_any = true;
432 *byte = 0;
433 }
434 }
435
436 let bits_in_last_byte = pos_in_chunk % 8;
438 if bits_in_last_byte != 0 {
439 let mask = (1u8 << bits_in_last_byte) - 1;
440 let old_byte = last_chunk[last_byte_index];
441 let new_byte = old_byte & mask;
442 if old_byte != new_byte {
443 flipped_any = true;
444 last_chunk[last_byte_index] = new_byte;
445 }
446 }
447
448 flipped_any
449 }
450
451 fn prune_chunks(&mut self, chunks: usize) {
459 assert!(
460 chunks <= self.chunks.len(),
461 "cannot prune {chunks} chunks, only {} available",
462 self.chunks.len()
463 );
464 self.chunks.drain(..chunks);
465 let bits_removed = (chunks as u64) * Self::CHUNK_SIZE_BITS;
467 self.len = self.len.saturating_sub(bits_removed);
468 }
469
470 pub(super) fn prepend_chunk(&mut self, chunk: &[u8; N]) {
472 self.chunks.push_front(*chunk);
473 self.len += Self::CHUNK_SIZE_BITS;
474 }
475
476 pub(super) fn set_chunk_by_index(&mut self, chunk_index: usize, chunk_data: &[u8; N]) {
486 assert!(
487 chunk_index < self.chunks.len(),
488 "chunk index {chunk_index} out of bounds (chunks_len: {})",
489 self.chunks.len()
490 );
491 self.chunks[chunk_index].copy_from_slice(chunk_data);
492 }
493
494 #[inline]
498 pub fn count_ones(&self) -> u64 {
499 let (front, back) = self.chunks.as_slices();
503 Self::count_ones_in_chunk_slice(front) + Self::count_ones_in_chunk_slice(back)
504 }
505
506 #[inline]
507 fn count_ones_in_chunk_slice(chunks: &[[u8; N]]) -> u64 {
508 let mut total = 0u64;
509 let mut words = chunks.as_flattened().chunks_exact(8);
510 for word in &mut words {
511 total += u64::from_le_bytes(word.try_into().unwrap()).count_ones() as u64;
512 }
513 for byte in words.remainder() {
514 total += byte.count_ones() as u64;
515 }
516 total
517 }
518
519 #[inline]
521 pub fn count_zeros(&self) -> u64 {
522 self.len() - self.count_ones()
523 }
524
525 #[inline]
529 pub(super) const fn chunk_byte_bitmask(bit: u64) -> u8 {
530 1 << (bit % 8)
531 }
532
533 #[inline]
535 pub(super) const fn chunk_byte_offset(bit: u64) -> usize {
536 ((bit / 8) % N as u64) as usize
537 }
538
539 #[inline]
545 pub(super) fn to_chunk_index(bit: u64) -> usize {
546 let chunk = bit / Self::CHUNK_SIZE_BITS;
547 assert!(
548 chunk <= usize::MAX as u64,
549 "chunk overflow: {chunk} exceeds usize::MAX",
550 );
551 chunk as usize
552 }
553
554 pub const fn iter(&self) -> Iterator<'_, N> {
558 Iterator {
559 bitmap: self,
560 pos: 0,
561 }
562 }
563
564 pub fn ones_iter(&self) -> OnesIter<'_, Self, N> {
566 Readable::ones_iter_from(self, 0)
567 }
568
569 #[inline]
573 fn binary_op<F: Fn(u8, u8) -> u8>(&mut self, other: &Self, op: F) {
574 self.assert_eq_len(other);
575 for (a_chunk, b_chunk) in self.chunks.iter_mut().zip(other.chunks.iter()) {
576 for (a_byte, b_byte) in a_chunk.iter_mut().zip(b_chunk.iter()) {
577 *a_byte = op(*a_byte, *b_byte);
578 }
579 }
580 self.clear_trailing_bits();
582 }
583
584 pub fn and(&mut self, other: &Self) {
590 self.binary_op(other, |a, b| a & b);
591 }
592
593 pub fn or(&mut self, other: &Self) {
599 self.binary_op(other, |a, b| a | b);
600 }
601
602 pub fn xor(&mut self, other: &Self) {
608 self.binary_op(other, |a, b| a ^ b);
609 }
610
611 #[inline(always)]
615 fn assert_bit(&self, bit: u64) {
616 assert!(
617 bit < self.len(),
618 "bit {} out of bounds (len: {})",
619 bit,
620 self.len()
621 );
622 }
623
624 #[inline(always)]
626 fn assert_eq_len(&self, other: &Self) {
627 assert_eq!(
628 self.len(),
629 other.len(),
630 "BitMap lengths don't match: {} vs {}",
631 self.len(),
632 other.len()
633 );
634 }
635
636 pub fn is_unset(&self, range: Range<u64>) -> bool {
659 assert!(
660 range.end <= self.len(),
661 "range end {} out of bounds (len: {})",
662 range.end,
663 self.len()
664 );
665 if range.start >= range.end {
666 return true;
667 }
668 let start = range.start;
669 let end = range.end;
670
671 let end = end - 1;
675
676 let first_chunk = Self::to_chunk_index(start);
678 let last_chunk = Self::to_chunk_index(end);
679
680 let zero = [0u8; N];
683 for full_chunk in (first_chunk + 1)..last_chunk {
684 if self.chunks[full_chunk] != zero {
685 return false;
686 }
687 }
688
689 let start_byte = Self::chunk_byte_offset(start);
691 let end_byte = Self::chunk_byte_offset(end);
692 let start_mask = (0xFFu16 << ((start & 0b111) as u32)) as u8;
693 let end_mask = (0xFFu16 >> (7 - ((end & 0b111) as u32))) as u8;
694 let first = &self.chunks[first_chunk];
695 let first_end_byte = if first_chunk == last_chunk {
696 end_byte
697 } else {
698 N - 1
699 };
700 for (i, &byte) in first
701 .iter()
702 .enumerate()
703 .take(first_end_byte + 1)
704 .skip(start_byte)
705 {
706 let mut mask = 0xFFu8;
707 if i == start_byte {
708 mask &= start_mask;
709 }
710 if first_chunk == last_chunk && i == end_byte {
711 mask &= end_mask;
712 }
713 if (byte & mask) != 0 {
714 return false;
715 }
716 }
717 if first_chunk == last_chunk {
718 return true;
719 }
720
721 let last = &self.chunks[last_chunk];
723 for (i, &byte) in last.iter().enumerate().take(end_byte + 1) {
724 let mask = if i == end_byte { end_mask } else { 0xFF };
725 if (byte & mask) != 0 {
726 return false;
727 }
728 }
729
730 true
731 }
732}
733
734impl<const N: usize> Default for BitMap<N> {
735 fn default() -> Self {
736 Self::new()
737 }
738}
739
740impl<T: AsRef<[bool]>, const N: usize> From<T> for BitMap<N> {
741 fn from(t: T) -> Self {
742 let bools = t.as_ref();
743 let mut bv = Self::with_capacity(bools.len() as u64);
744 for &b in bools {
745 bv.push(b);
746 }
747 bv
748 }
749}
750
751impl<const N: usize> From<BitMap<N>> for Vec<bool> {
752 fn from(bv: BitMap<N>) -> Self {
753 bv.iter().collect()
754 }
755}
756
757impl<const N: usize> fmt::Debug for BitMap<N> {
758 fn fmt(&self, f: &mut Formatter<'_>) -> core::fmt::Result {
759 const MAX_DISPLAY: u64 = 64;
761 const HALF_DISPLAY: u64 = MAX_DISPLAY / 2;
762
763 let write_bit = |formatter: &mut Formatter<'_>, bit: u64| -> core::fmt::Result {
765 formatter.write_char(if self.get(bit) { '1' } else { '0' })
766 };
767
768 f.write_str("BitMap[")?;
769 let len = self.len();
770 if len <= MAX_DISPLAY {
771 for i in 0..len {
773 write_bit(f, i)?;
774 }
775 } else {
776 for i in 0..HALF_DISPLAY {
778 write_bit(f, i)?;
779 }
780
781 f.write_str("...")?;
782
783 for i in (len - HALF_DISPLAY)..len {
784 write_bit(f, i)?;
785 }
786 }
787 f.write_str("]")
788 }
789}
790
791impl<const N: usize> Index<u64> for BitMap<N> {
792 type Output = bool;
793
794 #[inline]
798 fn index(&self, bit: u64) -> &Self::Output {
799 self.assert_bit(bit);
800 let value = self.get(bit);
801 if value {
802 &true
803 } else {
804 &false
805 }
806 }
807}
808
809impl<const N: usize> BitAnd for &BitMap<N> {
810 type Output = BitMap<N>;
811
812 fn bitand(self, rhs: Self) -> Self::Output {
813 self.assert_eq_len(rhs);
814 let mut result = self.clone();
815 result.and(rhs);
816 result
817 }
818}
819
820impl<const N: usize> BitOr for &BitMap<N> {
821 type Output = BitMap<N>;
822
823 fn bitor(self, rhs: Self) -> Self::Output {
824 self.assert_eq_len(rhs);
825 let mut result = self.clone();
826 result.or(rhs);
827 result
828 }
829}
830
831impl<const N: usize> BitXor for &BitMap<N> {
832 type Output = BitMap<N>;
833
834 fn bitxor(self, rhs: Self) -> Self::Output {
835 self.assert_eq_len(rhs);
836 let mut result = self.clone();
837 result.xor(rhs);
838 result
839 }
840}
841
842impl<const N: usize> Write for BitMap<N> {
843 fn write(&self, buf: &mut impl BufMut) {
844 self.len().write(buf);
846
847 let (front, back) = self.chunks.as_slices();
849 buf.put_slice(front.as_flattened());
850 buf.put_slice(back.as_flattened());
851 }
852}
853
854impl<const N: usize> Read for BitMap<N> {
855 type Cfg = u64; fn read_cfg(buf: &mut impl Buf, max_len: &Self::Cfg) -> Result<Self, CodecError> {
858 let len = u64::read(buf)?;
860 if len > *max_len {
861 return Err(CodecError::InvalidLength(len as usize));
862 }
863
864 let num_chunks = len.div_ceil(Self::CHUNK_SIZE_BITS) as usize;
866
867 let mut chunks = VecDeque::with_capacity(num_chunks);
869 for _ in 0..num_chunks {
870 at_least(buf, N)?;
871 let mut chunk = [0u8; N];
872 buf.copy_to_slice(&mut chunk);
873 chunks.push_back(chunk);
874 }
875
876 let mut result = Self { chunks, len };
877
878 if result.clear_trailing_bits() {
880 return Err(CodecError::Invalid(
881 "BitMap",
882 "Invalid trailing bits in encoded data",
883 ));
884 }
885
886 Ok(result)
887 }
888}
889
890impl<const N: usize> EncodeSize for BitMap<N> {
891 fn encode_size(&self) -> usize {
892 self.len().encode_size() + (self.chunks.len() * N)
894 }
895}
896
897pub struct Iterator<'a, const N: usize> {
899 bitmap: &'a BitMap<N>,
901
902 pos: u64,
904}
905
906impl<const N: usize> iter::Iterator for Iterator<'_, N> {
907 type Item = bool;
908
909 fn next(&mut self) -> Option<Self::Item> {
910 if self.pos >= self.bitmap.len() {
911 return None;
912 }
913
914 let bit = self.bitmap.get(self.pos);
915 self.pos += 1;
916 Some(bit)
917 }
918
919 fn size_hint(&self) -> (usize, Option<usize>) {
920 let remaining = self.bitmap.len().saturating_sub(self.pos);
921 let capped = remaining.min(usize::MAX as u64) as usize;
922 (capped, Some(capped))
923 }
924}
925
926impl<const N: usize> ExactSizeIterator for Iterator<'_, N> {}
927
928pub trait Readable<const N: usize> {
930 fn complete_chunks(&self) -> usize;
932
933 fn get_chunk(&self, chunk: usize) -> [u8; N];
935
936 fn last_chunk(&self) -> ([u8; N], u64);
938
939 fn pruned_chunks(&self) -> usize;
941
942 fn len(&self) -> u64;
944
945 fn is_empty(&self) -> bool {
947 self.len() == 0
948 }
949
950 fn pruned_bits(&self) -> u64 {
952 (self.pruned_chunks() as u64) * BitMap::<N>::CHUNK_SIZE_BITS
953 }
954
955 fn get_bit(&self, bit: u64) -> bool {
957 let chunk = self.get_chunk(BitMap::<N>::to_chunk_index(bit));
958 BitMap::<N>::get_bit_from_chunk(&chunk, bit % BitMap::<N>::CHUNK_SIZE_BITS)
959 }
960
961 fn ones_iter_from(&self, pos: u64) -> OnesIter<'_, Self, N>
966 where
967 Self: Sized,
968 {
969 let len = self.len();
970 let pruned_start = (self.pruned_chunks() as u64) * BitMap::<N>::CHUNK_SIZE_BITS;
971 OnesIter {
972 bitmap: self,
973 pos: pos.max(pruned_start),
974 len,
975 }
976 }
977}
978
979impl<const N: usize> Readable<N> for BitMap<N> {
980 fn complete_chunks(&self) -> usize {
981 self.chunks_len()
982 .saturating_sub(if self.is_chunk_aligned() { 0 } else { 1 })
983 }
984
985 fn get_chunk(&self, chunk: usize) -> [u8; N] {
986 *Self::get_chunk(self, chunk)
987 }
988
989 fn last_chunk(&self) -> ([u8; N], u64) {
990 let (c, n) = Self::last_chunk(self);
991 (*c, n)
992 }
993
994 fn pruned_chunks(&self) -> usize {
995 0
996 }
997
998 fn len(&self) -> u64 {
999 self.len
1000 }
1001}
1002
1003pub struct OnesIter<'a, B, const N: usize> {
1008 bitmap: &'a B,
1009 pos: u64,
1010 len: u64,
1015}
1016
1017impl<B: Readable<N>, const N: usize> iter::Iterator for OnesIter<'_, B, N> {
1018 type Item = u64;
1019
1020 fn next(&mut self) -> Option<u64> {
1021 let chunk_bits = BitMap::<N>::CHUNK_SIZE_BITS;
1022 while self.pos < self.len {
1023 let chunk_idx = BitMap::<N>::to_chunk_index(self.pos);
1024 let chunk = self.bitmap.get_chunk(chunk_idx);
1025 let chunk_start = chunk_idx as u64 * chunk_bits;
1026 let rel = (self.pos - chunk_start) as usize;
1027 let mut byte_idx = rel / 8;
1028 let mut bit_in_byte = rel % 8;
1029 while byte_idx < N {
1030 let masked = chunk[byte_idx] >> bit_in_byte;
1031 if masked != 0 {
1032 let found = chunk_start
1033 + (byte_idx * 8 + bit_in_byte) as u64
1034 + masked.trailing_zeros() as u64;
1035 if found >= self.len {
1036 return None;
1037 }
1038 self.pos = found + 1;
1039 return Some(found);
1040 }
1041 byte_idx += 1;
1042 bit_in_byte = 0;
1043 }
1044 self.pos = chunk_start + chunk_bits;
1045 }
1046 None
1047 }
1048}
1049
1050#[cfg(feature = "arbitrary")]
1051impl<const N: usize> arbitrary::Arbitrary<'_> for BitMap<N> {
1052 fn arbitrary(u: &mut arbitrary::Unstructured<'_>) -> arbitrary::Result<Self> {
1053 let size = u.int_in_range(0..=1024)?;
1054 let mut bits = Self::with_capacity(size);
1055 for _ in 0..size {
1056 bits.push(u.arbitrary::<bool>()?);
1057 }
1058 Ok(bits)
1059 }
1060}
1061
1062#[cfg(test)]
1063mod tests {
1064 use super::*;
1065 use bytes::BytesMut;
1066 use commonware_codec::{Decode, Encode};
1067 use commonware_formatting::hex;
1068
1069 #[test]
1070 fn test_constructors() {
1071 let bv: BitMap<4> = BitMap::new();
1073 assert_eq!(bv.len(), 0);
1074 assert!(bv.is_empty());
1075
1076 let bv: BitMap<4> = Default::default();
1078 assert_eq!(bv.len(), 0);
1079 assert!(bv.is_empty());
1080
1081 let bv: BitMap<4> = BitMap::with_capacity(0);
1083 assert_eq!(bv.len(), 0);
1084 assert!(bv.is_empty());
1085
1086 let bv: BitMap<4> = BitMap::with_capacity(10);
1087 assert_eq!(bv.len(), 0);
1088 assert!(bv.is_empty());
1089 }
1090
1091 #[test]
1092 fn test_zeroes() {
1093 let bv: BitMap<1> = BitMap::zeroes(0);
1094 assert_eq!(bv.len(), 0);
1095 assert!(bv.is_empty());
1096 assert_eq!(bv.count_ones(), 0);
1097 assert_eq!(bv.count_zeros(), 0);
1098
1099 let bv: BitMap<1> = BitMap::zeroes(1);
1100 assert_eq!(bv.len(), 1);
1101 assert!(!bv.is_empty());
1102 assert_eq!(bv.len(), 1);
1103 assert!(!bv.get(0));
1104 assert_eq!(bv.count_ones(), 0);
1105 assert_eq!(bv.count_zeros(), 1);
1106
1107 let bv: BitMap<1> = BitMap::zeroes(10);
1108 assert_eq!(bv.len(), 10);
1109 assert!(!bv.is_empty());
1110 assert_eq!(bv.len(), 10);
1111 for i in 0..10 {
1112 assert!(!bv.get(i as u64));
1113 }
1114 assert_eq!(bv.count_ones(), 0);
1115 assert_eq!(bv.count_zeros(), 10);
1116 }
1117
1118 #[test]
1119 fn test_ones() {
1120 let bv: BitMap<1> = BitMap::ones(0);
1121 assert_eq!(bv.len(), 0);
1122 assert!(bv.is_empty());
1123 assert_eq!(bv.count_ones(), 0);
1124 assert_eq!(bv.count_zeros(), 0);
1125
1126 let bv: BitMap<1> = BitMap::ones(1);
1127 assert_eq!(bv.len(), 1);
1128 assert!(!bv.is_empty());
1129 assert_eq!(bv.len(), 1);
1130 assert!(bv.get(0));
1131 assert_eq!(bv.count_ones(), 1);
1132 assert_eq!(bv.count_zeros(), 0);
1133
1134 let bv: BitMap<1> = BitMap::ones(10);
1135 assert_eq!(bv.len(), 10);
1136 assert!(!bv.is_empty());
1137 assert_eq!(bv.len(), 10);
1138 for i in 0..10 {
1139 assert!(bv.get(i as u64));
1140 }
1141 assert_eq!(bv.count_ones(), 10);
1142 assert_eq!(bv.count_zeros(), 0);
1143 }
1144
1145 #[test]
1146 fn test_invariant_trailing_bits_are_zero() {
1147 fn check_trailing_bits_zero<const N: usize>(bitmap: &BitMap<N>) {
1149 let (last_chunk, next_bit) = bitmap.last_chunk();
1150
1151 for bit_idx in next_bit..((N * 8) as u64) {
1153 let byte_idx = (bit_idx / 8) as usize;
1154 let bit_in_byte = bit_idx % 8;
1155 let mask = 1u8 << bit_in_byte;
1156 assert_eq!(last_chunk[byte_idx] & mask, 0);
1157 }
1158 }
1159
1160 let bv: BitMap<4> = BitMap::ones(15);
1162 check_trailing_bits_zero(&bv);
1163
1164 let bv: BitMap<4> = BitMap::ones(33);
1165 check_trailing_bits_zero(&bv);
1166
1167 let mut bv: BitMap<4> = BitMap::new();
1169 for i in 0..37 {
1170 bv.push(i % 2 == 0);
1171 check_trailing_bits_zero(&bv);
1172 }
1173
1174 let mut bv: BitMap<4> = BitMap::ones(40);
1176 check_trailing_bits_zero(&bv);
1177 for _ in 0..15 {
1178 bv.pop();
1179 check_trailing_bits_zero(&bv);
1180 }
1181
1182 let mut bv: BitMap<4> = BitMap::ones(25);
1184 bv.flip_all();
1185 check_trailing_bits_zero(&bv);
1186
1187 let bv1: BitMap<4> = BitMap::ones(20);
1189 let bv2: BitMap<4> = BitMap::zeroes(20);
1190
1191 let mut bv_and = bv1.clone();
1192 bv_and.and(&bv2);
1193 check_trailing_bits_zero(&bv_and);
1194
1195 let mut bv_or = bv1.clone();
1196 bv_or.or(&bv2);
1197 check_trailing_bits_zero(&bv_or);
1198
1199 let mut bv_xor = bv1;
1200 bv_xor.xor(&bv2);
1201 check_trailing_bits_zero(&bv_xor);
1202
1203 let original: BitMap<4> = BitMap::ones(27);
1205 let encoded = original.encode();
1206 let decoded: BitMap<4> =
1207 BitMap::decode_cfg(&mut encoded.as_ref(), &(usize::MAX as u64)).unwrap();
1208 check_trailing_bits_zero(&decoded);
1209
1210 let mut bv_clean: BitMap<4> = BitMap::ones(20);
1212 assert!(!bv_clean.clear_trailing_bits());
1214
1215 let mut bv_dirty: BitMap<4> = BitMap::ones(20);
1217 let last_chunk = bv_dirty.chunks.back_mut().unwrap();
1219 last_chunk[3] |= 0xF0; assert!(bv_dirty.clear_trailing_bits());
1222 assert!(!bv_dirty.clear_trailing_bits());
1224 check_trailing_bits_zero(&bv_dirty);
1225 }
1226
1227 #[test]
1228 fn test_get_set() {
1229 let mut bv: BitMap<4> = BitMap::new();
1230
1231 assert_eq!(bv.len(), 0);
1233 assert!(bv.is_empty());
1234
1235 bv.push(true);
1237 bv.push(false);
1238 bv.push(true);
1239 assert_eq!(bv.len(), 3);
1240 assert!(!bv.is_empty());
1241
1242 assert!(bv.get(0));
1244 assert!(!bv.get(1));
1245 assert!(bv.get(2));
1246
1247 bv.set(1, true);
1248 assert!(bv.get(1));
1249 bv.set(2, false);
1250 assert!(!bv.get(2));
1251
1252 bv.flip(0); assert!(!bv.get(0));
1255 bv.flip(0); assert!(bv.get(0));
1257 }
1258
1259 #[test]
1260 fn test_chunk_operations() {
1261 let mut bv: BitMap<4> = BitMap::new();
1262 let test_chunk = hex!("0xABCDEF12");
1263
1264 bv.push_chunk(&test_chunk);
1266 assert_eq!(bv.len(), 32); let chunk = bv.get_chunk(0);
1270 assert_eq!(chunk, &test_chunk);
1271
1272 let chunk = bv.get_chunk_containing(0);
1274 assert_eq!(chunk, &test_chunk);
1275
1276 let (last_chunk, next_bit) = bv.last_chunk();
1278 assert_eq!(next_bit, BitMap::<4>::CHUNK_SIZE_BITS); assert_eq!(last_chunk, &test_chunk); }
1281
1282 #[test]
1283 fn test_pop() {
1284 let mut bv: BitMap<3> = BitMap::new();
1285 bv.push(true);
1286 assert!(bv.pop());
1287 assert_eq!(bv.len(), 0);
1288
1289 bv.push(false);
1290 assert!(!bv.pop());
1291 assert_eq!(bv.len(), 0);
1292
1293 bv.push(true);
1294 bv.push(false);
1295 bv.push(true);
1296 assert!(bv.pop());
1297 assert_eq!(bv.len(), 2);
1298 assert!(!bv.pop());
1299 assert_eq!(bv.len(), 1);
1300 assert!(bv.pop());
1301 assert_eq!(bv.len(), 0);
1302
1303 for i in 0..100 {
1304 bv.push(i % 2 == 0);
1305 }
1306 assert_eq!(bv.len(), 100);
1307 for i in (0..100).rev() {
1308 assert_eq!(bv.pop(), i % 2 == 0);
1309 }
1310 assert_eq!(bv.len(), 0);
1311 assert!(bv.is_empty());
1312 }
1313
1314 #[test]
1315 fn test_truncate() {
1316 let mut bv: BitMap<4> = BitMap::new();
1317 let expected: Vec<bool> = (0..70).map(|i| i % 3 == 0).collect();
1318 for &bit in &expected {
1319 bv.push(bit);
1320 }
1321
1322 bv.truncate(65);
1323 assert_eq!(bv.len(), 65);
1324 for i in 0..65 {
1325 assert_eq!(bv.get(i), expected[i as usize]);
1326 }
1327
1328 bv.truncate(32);
1329 assert_eq!(bv.len(), 32);
1330 for i in 0..32 {
1331 assert_eq!(bv.get(i), expected[i as usize]);
1332 }
1333
1334 bv.truncate(0);
1335 assert_eq!(bv.len(), 0);
1336 assert!(bv.is_empty());
1337 }
1338
1339 #[test]
1340 #[should_panic(expected = "cannot truncate to a larger size")]
1341 fn test_truncate_larger_size_panics() {
1342 let mut bv: BitMap<4> = BitMap::new();
1343 bv.push(true);
1344 bv.truncate(2);
1345 }
1346
1347 #[test]
1348 fn test_pop_chunk() {
1349 let mut bv: BitMap<3> = BitMap::new();
1350 const CHUNK_SIZE: u64 = BitMap::<3>::CHUNK_SIZE_BITS;
1351
1352 let chunk1 = hex!("0xAABBCC");
1354 bv.push_chunk(&chunk1);
1355 assert_eq!(bv.len(), CHUNK_SIZE);
1356 let popped = bv.pop_chunk();
1357 assert_eq!(popped, chunk1);
1358 assert_eq!(bv.len(), 0);
1359 assert!(bv.is_empty());
1360
1361 let chunk2 = hex!("0x112233");
1363 let chunk3 = hex!("0x445566");
1364 let chunk4 = hex!("0x778899");
1365
1366 bv.push_chunk(&chunk2);
1367 bv.push_chunk(&chunk3);
1368 bv.push_chunk(&chunk4);
1369 assert_eq!(bv.len(), CHUNK_SIZE * 3);
1370
1371 assert_eq!(bv.pop_chunk(), chunk4);
1372 assert_eq!(bv.len(), CHUNK_SIZE * 2);
1373
1374 assert_eq!(bv.pop_chunk(), chunk3);
1375 assert_eq!(bv.len(), CHUNK_SIZE);
1376
1377 assert_eq!(bv.pop_chunk(), chunk2);
1378 assert_eq!(bv.len(), 0);
1379
1380 let first_chunk = hex!("0xAABBCC");
1382 let second_chunk = hex!("0x112233");
1383 bv.push_chunk(&first_chunk);
1384 bv.push_chunk(&second_chunk);
1385
1386 assert_eq!(bv.pop_chunk(), second_chunk);
1388 assert_eq!(bv.len(), CHUNK_SIZE);
1389
1390 for i in 0..CHUNK_SIZE {
1391 let byte_idx = (i / 8) as usize;
1392 let bit_idx = i % 8;
1393 let expected = (first_chunk[byte_idx] >> bit_idx) & 1 == 1;
1394 assert_eq!(bv.get(i), expected);
1395 }
1396
1397 assert_eq!(bv.pop_chunk(), first_chunk);
1398 assert_eq!(bv.len(), 0);
1399 }
1400
1401 #[test]
1402 #[should_panic(expected = "cannot pop chunk when not chunk aligned")]
1403 fn test_pop_chunk_not_aligned() {
1404 let mut bv: BitMap<3> = BitMap::new();
1405
1406 bv.push_chunk(&[0xFF; 3]);
1408 bv.push(true);
1409
1410 bv.pop_chunk();
1412 }
1413
1414 #[test]
1415 #[should_panic(expected = "cannot pop chunk: bitmap has fewer than CHUNK_SIZE_BITS bits")]
1416 fn test_pop_chunk_insufficient_bits() {
1417 let mut bv: BitMap<3> = BitMap::new();
1418
1419 bv.push(true);
1421 bv.push(false);
1422
1423 bv.pop_chunk();
1425 }
1426
1427 #[test]
1428 fn test_byte_operations() {
1429 let mut bv: BitMap<4> = BitMap::new();
1430
1431 bv.push_byte(0xFF);
1433 assert_eq!(bv.len(), 8);
1434
1435 for i in 0..8 {
1437 assert!(bv.get(i as u64));
1438 }
1439
1440 bv.push_byte(0x00);
1441 assert_eq!(bv.len(), 16);
1442
1443 for i in 8..16 {
1445 assert!(!bv.get(i as u64));
1446 }
1447 }
1448
1449 #[test]
1450 fn test_count_operations() {
1451 let mut bv: BitMap<4> = BitMap::new();
1452
1453 assert_eq!(bv.count_ones(), 0);
1455 assert_eq!(bv.count_zeros(), 0);
1456
1457 bv.push(true);
1459 bv.push(false);
1460 bv.push(true);
1461 bv.push(true);
1462 bv.push(false);
1463
1464 assert_eq!(bv.count_ones(), 3);
1465 assert_eq!(bv.count_zeros(), 2);
1466 assert_eq!(bv.len(), 5);
1467
1468 let mut bv2: BitMap<4> = BitMap::new();
1470 bv2.push_byte(0xFF); bv2.push_byte(0x00); bv2.push_byte(0xAA); assert_eq!(bv2.count_ones(), 12);
1475 assert_eq!(bv2.count_zeros(), 12);
1476 assert_eq!(bv2.len(), 24);
1477 }
1478
1479 #[test]
1480 fn test_set_all() {
1481 let mut bv: BitMap<1> = BitMap::new();
1482
1483 bv.push(true);
1485 bv.push(false);
1486 bv.push(true);
1487 bv.push(false);
1488 bv.push(true);
1489 bv.push(false);
1490 bv.push(true);
1491 bv.push(false);
1492 bv.push(true);
1493 bv.push(false);
1494
1495 assert_eq!(bv.len(), 10);
1496 assert_eq!(bv.count_ones(), 5);
1497 assert_eq!(bv.count_zeros(), 5);
1498
1499 bv.set_all(true);
1501 assert_eq!(bv.len(), 10);
1502 assert_eq!(bv.count_ones(), 10);
1503 assert_eq!(bv.count_zeros(), 0);
1504
1505 bv.set_all(false);
1507 assert_eq!(bv.len(), 10);
1508 assert_eq!(bv.count_ones(), 0);
1509 assert_eq!(bv.count_zeros(), 10);
1510 }
1511
1512 #[test]
1513 fn test_flip_all() {
1514 let mut bv: BitMap<4> = BitMap::new();
1515
1516 bv.push(true);
1517 bv.push(false);
1518 bv.push(true);
1519 bv.push(false);
1520 bv.push(true);
1521
1522 let original_ones = bv.count_ones();
1523 let original_zeros = bv.count_zeros();
1524 let original_len = bv.len();
1525
1526 bv.flip_all();
1527
1528 assert_eq!(bv.len(), original_len);
1530
1531 assert_eq!(bv.count_ones(), original_zeros);
1533 assert_eq!(bv.count_zeros(), original_ones);
1534
1535 assert!(!bv.get(0));
1537 assert!(bv.get(1));
1538 assert!(!bv.get(2));
1539 assert!(bv.get(3));
1540 assert!(!bv.get(4));
1541 }
1542
1543 #[test]
1544 fn test_bitwise_and() {
1545 let mut bv1: BitMap<4> = BitMap::new();
1546 let mut bv2: BitMap<4> = BitMap::new();
1547
1548 let pattern1 = [true, false, true, true, false];
1550 let pattern2 = [true, true, false, true, false];
1551 let expected = [true, false, false, true, false];
1552
1553 for &bit in &pattern1 {
1554 bv1.push(bit);
1555 }
1556 for &bit in &pattern2 {
1557 bv2.push(bit);
1558 }
1559
1560 bv1.and(&bv2);
1561
1562 assert_eq!(bv1.len(), 5);
1563 for (i, &expected_bit) in expected.iter().enumerate() {
1564 assert_eq!(bv1.get(i as u64), expected_bit);
1565 }
1566 }
1567
1568 #[test]
1569 fn test_bitwise_or() {
1570 let mut bv1: BitMap<4> = BitMap::new();
1571 let mut bv2: BitMap<4> = BitMap::new();
1572
1573 let pattern1 = [true, false, true, true, false];
1575 let pattern2 = [true, true, false, true, false];
1576 let expected = [true, true, true, true, false];
1577
1578 for &bit in &pattern1 {
1579 bv1.push(bit);
1580 }
1581 for &bit in &pattern2 {
1582 bv2.push(bit);
1583 }
1584
1585 bv1.or(&bv2);
1586
1587 assert_eq!(bv1.len(), 5);
1588 for (i, &expected_bit) in expected.iter().enumerate() {
1589 assert_eq!(bv1.get(i as u64), expected_bit);
1590 }
1591 }
1592
1593 #[test]
1594 fn test_bitwise_xor() {
1595 let mut bv1: BitMap<4> = BitMap::new();
1596 let mut bv2: BitMap<4> = BitMap::new();
1597
1598 let pattern1 = [true, false, true, true, false];
1600 let pattern2 = [true, true, false, true, false];
1601 let expected = [false, true, true, false, false];
1602
1603 for &bit in &pattern1 {
1604 bv1.push(bit);
1605 }
1606 for &bit in &pattern2 {
1607 bv2.push(bit);
1608 }
1609
1610 bv1.xor(&bv2);
1611
1612 assert_eq!(bv1.len(), 5);
1613 for (i, &expected_bit) in expected.iter().enumerate() {
1614 assert_eq!(bv1.get(i as u64), expected_bit);
1615 }
1616 }
1617
1618 #[test]
1619 fn test_multi_chunk_operations() {
1620 let mut bv1: BitMap<4> = BitMap::new();
1621 let mut bv2: BitMap<4> = BitMap::new();
1622
1623 let chunk1 = hex!("0xAABBCCDD"); let chunk2 = hex!("0x55667788"); bv1.push_chunk(&chunk1);
1628 bv1.push_chunk(&chunk1);
1629 bv2.push_chunk(&chunk2);
1630 bv2.push_chunk(&chunk2);
1631
1632 assert_eq!(bv1.len(), 64);
1633 assert_eq!(bv2.len(), 64);
1634
1635 let mut bv_and = bv1.clone();
1637 bv_and.and(&bv2);
1638
1639 let mut bv_or = bv1.clone();
1641 bv_or.or(&bv2);
1642
1643 let mut bv_xor = bv1.clone();
1645 bv_xor.xor(&bv2);
1646
1647 assert_eq!(bv_and.len(), 64);
1649 assert_eq!(bv_or.len(), 64);
1650 assert_eq!(bv_xor.len(), 64);
1651
1652 assert!(bv_and.count_ones() <= bv1.count_ones());
1654 assert!(bv_and.count_ones() <= bv2.count_ones());
1655
1656 assert!(bv_or.count_ones() >= bv1.count_ones());
1658 assert!(bv_or.count_ones() >= bv2.count_ones());
1659 }
1660
1661 #[test]
1662 fn test_partial_chunk_operations() {
1663 let mut bv1: BitMap<4> = BitMap::new();
1664 let mut bv2: BitMap<4> = BitMap::new();
1665
1666 for i in 0..35 {
1668 bv1.push(i % 2 == 0);
1670 bv2.push(i % 3 == 0);
1671 }
1672
1673 assert_eq!(bv1.len(), 35);
1674 assert_eq!(bv2.len(), 35);
1675
1676 let mut bv_and = bv1.clone();
1678 bv_and.and(&bv2);
1679
1680 let mut bv_or = bv1.clone();
1681 bv_or.or(&bv2);
1682
1683 let mut bv_xor = bv1.clone();
1684 bv_xor.xor(&bv2);
1685
1686 assert_eq!(bv_and.len(), 35);
1688 assert_eq!(bv_or.len(), 35);
1689 assert_eq!(bv_xor.len(), 35);
1690
1691 let mut bv_inv = bv1.clone();
1693 let original_ones = bv_inv.count_ones();
1694 let original_zeros = bv_inv.count_zeros();
1695 bv_inv.flip_all();
1696 assert_eq!(bv_inv.count_ones(), original_zeros);
1697 assert_eq!(bv_inv.count_zeros(), original_ones);
1698 }
1699
1700 #[test]
1701 #[should_panic(expected = "bit 1 out of bounds (len: 1)")]
1702 fn test_flip_out_of_bounds() {
1703 let mut bv: BitMap<4> = BitMap::new();
1704 bv.push(true);
1705 bv.flip(1); }
1707
1708 #[test]
1709 #[should_panic(expected = "BitMap lengths don't match: 2 vs 1")]
1710 fn test_and_length_mismatch() {
1711 let mut bv1: BitMap<4> = BitMap::new();
1712 let mut bv2: BitMap<4> = BitMap::new();
1713
1714 bv1.push(true);
1715 bv1.push(false);
1716 bv2.push(true); bv1.and(&bv2);
1719 }
1720
1721 #[test]
1722 #[should_panic(expected = "BitMap lengths don't match: 1 vs 2")]
1723 fn test_or_length_mismatch() {
1724 let mut bv1: BitMap<4> = BitMap::new();
1725 let mut bv2: BitMap<4> = BitMap::new();
1726
1727 bv1.push(true);
1728 bv2.push(true);
1729 bv2.push(false); bv1.or(&bv2);
1732 }
1733
1734 #[test]
1735 #[should_panic(expected = "BitMap lengths don't match: 3 vs 2")]
1736 fn test_xor_length_mismatch() {
1737 let mut bv1: BitMap<4> = BitMap::new();
1738 let mut bv2: BitMap<4> = BitMap::new();
1739
1740 bv1.push(true);
1741 bv1.push(false);
1742 bv1.push(true);
1743 bv2.push(true);
1744 bv2.push(false); bv1.xor(&bv2);
1747 }
1748
1749 #[test]
1750 fn test_equality() {
1751 assert_eq!(BitMap::<4>::new(), BitMap::<4>::new());
1753 assert_eq!(BitMap::<8>::new(), BitMap::<8>::new());
1754
1755 let pattern = [true, false, true, true, false, false, true, false, true];
1757 let bv4: BitMap<4> = pattern.as_ref().into();
1758 assert_eq!(bv4, BitMap::<4>::from(pattern.as_ref()));
1759 let bv8: BitMap<8> = pattern.as_ref().into();
1760 assert_eq!(bv8, BitMap::<8>::from(pattern.as_ref()));
1761
1762 let mut bv1: BitMap<4> = BitMap::new();
1764 let mut bv2: BitMap<4> = BitMap::new();
1765 for i in 0..33 {
1766 let bit = i % 3 == 0;
1767 bv1.push(bit);
1768 bv2.push(bit);
1769 }
1770 assert_eq!(bv1, bv2);
1771
1772 bv1.push(true);
1774 assert_ne!(bv1, bv2);
1775 bv1.pop(); assert_eq!(bv1, bv2);
1777
1778 bv1.flip(15);
1780 assert_ne!(bv1, bv2);
1781 bv1.flip(15); assert_eq!(bv1, bv2);
1783
1784 let mut bv_ops1 = BitMap::<16>::ones(25);
1786 let mut bv_ops2 = BitMap::<16>::ones(25);
1787 bv_ops1.flip_all();
1788 bv_ops2.flip_all();
1789 assert_eq!(bv_ops1, bv_ops2);
1790
1791 let mask_bits: Vec<bool> = (0..33).map(|i| i % 3 == 0).collect();
1792 let mask = BitMap::<4>::from(mask_bits);
1793 bv1.and(&mask);
1794 bv2.and(&mask);
1795 assert_eq!(bv1, bv2);
1796 }
1797
1798 #[test]
1799 fn test_different_chunk_sizes() {
1800 let mut bv8: BitMap<8> = BitMap::new();
1802 let mut bv16: BitMap<16> = BitMap::new();
1803 let mut bv32: BitMap<32> = BitMap::new();
1804
1805 let chunk8 = [0xFF; 8];
1807 let chunk16 = [0xAA; 16];
1808 let chunk32 = [0x55; 32];
1809
1810 bv8.push_chunk(&chunk8);
1811 bv16.push_chunk(&chunk16);
1812 bv32.push_chunk(&chunk32);
1813
1814 bv8.push(true);
1816 bv8.push(false);
1817 assert_eq!(bv8.len(), 64 + 2);
1818 assert_eq!(bv8.count_ones(), 64 + 1); assert_eq!(bv8.count_zeros(), 1);
1820
1821 bv16.push(true);
1822 bv16.push(false);
1823 assert_eq!(bv16.len(), 128 + 2);
1824 assert_eq!(bv16.count_ones(), 64 + 1); assert_eq!(bv16.count_zeros(), 64 + 1);
1826
1827 bv32.push(true);
1828 bv32.push(false);
1829 assert_eq!(bv32.len(), 256 + 2);
1830 assert_eq!(bv32.count_ones(), 128 + 1); assert_eq!(bv32.count_zeros(), 128 + 1);
1832 }
1833
1834 #[test]
1835 fn test_iterator() {
1836 let bv: BitMap<4> = BitMap::new();
1838 let mut iter = bv.iter();
1839 assert_eq!(iter.next(), None);
1840 assert_eq!(iter.size_hint(), (0, Some(0)));
1841
1842 let pattern = [true, false, true, false, true];
1844 let bv: BitMap<4> = pattern.as_ref().into();
1845
1846 let collected: Vec<bool> = bv.iter().collect();
1848 assert_eq!(collected, pattern);
1849
1850 let mut iter = bv.iter();
1852 assert_eq!(iter.size_hint(), (5, Some(5)));
1853
1854 assert_eq!(iter.next(), Some(true));
1856 assert_eq!(iter.size_hint(), (4, Some(4)));
1857
1858 let iter = bv.iter();
1860 assert_eq!(iter.len(), 5);
1861
1862 let mut large_bv: BitMap<8> = BitMap::new();
1864 for i in 0..100 {
1865 large_bv.push(i % 3 == 0);
1866 }
1867
1868 let collected: Vec<bool> = large_bv.iter().collect();
1869 assert_eq!(collected.len(), 100);
1870 for (i, &bit) in collected.iter().enumerate() {
1871 assert_eq!(bit, i % 3 == 0);
1872 }
1873 }
1874
1875 #[test]
1876 fn test_iterator_edge_cases() {
1877 let mut bv: BitMap<4> = BitMap::new();
1879 bv.push(true);
1880
1881 let collected: Vec<bool> = bv.iter().collect();
1882 assert_eq!(collected, vec![true]);
1883
1884 let mut bv: BitMap<4> = BitMap::new();
1886 for i in 0..32 {
1888 bv.push(i % 2 == 0);
1889 }
1890 bv.push(true);
1892 bv.push(false);
1893 bv.push(true);
1894
1895 let collected: Vec<bool> = bv.iter().collect();
1896 assert_eq!(collected.len(), 35);
1897
1898 for (i, &bit) in collected.iter().enumerate().take(32) {
1900 assert_eq!(bit, i % 2 == 0);
1901 }
1902 assert!(collected[32]);
1903 assert!(!collected[33]);
1904 assert!(collected[34]);
1905 }
1906
1907 #[test]
1908 fn test_ones_iter_empty() {
1909 let bv: BitMap<4> = BitMap::new();
1910 let ones: Vec<u64> = bv.ones_iter().collect();
1911 assert!(ones.is_empty());
1912 }
1913
1914 #[test]
1915 fn test_ones_iter_all_zeros() {
1916 let bv = BitMap::<4>::zeroes(100);
1917 let ones: Vec<u64> = bv.ones_iter().collect();
1918 assert!(ones.is_empty());
1919 }
1920
1921 #[test]
1922 fn test_ones_iter_all_ones() {
1923 let bv = BitMap::<4>::ones(100);
1924 let ones: Vec<u64> = bv.ones_iter().collect();
1925 let expected: Vec<u64> = (0..100).collect();
1926 assert_eq!(ones, expected);
1927 }
1928
1929 #[test]
1930 fn test_ones_iter_sparse() {
1931 let mut bv = BitMap::<4>::zeroes(64);
1932 bv.set(0, true);
1933 bv.set(31, true);
1934 bv.set(32, true);
1935 bv.set(63, true);
1936
1937 let ones: Vec<u64> = bv.ones_iter().collect();
1938 assert_eq!(ones, vec![0, 31, 32, 63]);
1939 }
1940
1941 #[test]
1942 fn test_ones_iter_single_bit() {
1943 let mut bv: BitMap<4> = BitMap::new();
1944 bv.push(true);
1945 assert_eq!(bv.ones_iter().collect::<Vec<_>>(), vec![0]);
1946
1947 let mut bv: BitMap<4> = BitMap::new();
1948 bv.push(false);
1949 assert!(bv.ones_iter().collect::<Vec<_>>().is_empty());
1950 }
1951
1952 #[test]
1953 fn test_ones_iter_multi_chunk() {
1954 let mut bv = BitMap::<4>::zeroes(96);
1956 bv.set(7, true); bv.set(40, true); bv.set(95, true); let ones: Vec<u64> = bv.ones_iter().collect();
1962 assert_eq!(ones, vec![7, 40, 95]);
1963 }
1964
1965 #[test]
1966 fn test_ones_iter_partial_chunk() {
1967 let mut bv = BitMap::<4>::zeroes(35);
1969 bv.set(31, true); bv.set(32, true); bv.set(34, true); let ones: Vec<u64> = bv.ones_iter().collect();
1974 assert_eq!(ones, vec![31, 32, 34]);
1975 }
1976
1977 #[test]
1978 fn test_ones_iter_from_midway() {
1979 let mut bv = BitMap::<4>::zeroes(64);
1980 bv.set(5, true);
1981 bv.set(20, true);
1982 bv.set(40, true);
1983 bv.set(60, true);
1984
1985 let ones: Vec<u64> = Readable::ones_iter_from(&bv, 20).collect();
1987 assert_eq!(ones, vec![20, 40, 60]);
1988
1989 let ones: Vec<u64> = Readable::ones_iter_from(&bv, 21).collect();
1991 assert_eq!(ones, vec![40, 60]);
1992
1993 let ones: Vec<u64> = Readable::ones_iter_from(&bv, 61).collect();
1995 assert!(ones.is_empty());
1996 }
1997
1998 #[test]
1999 fn test_ones_iter_matches_count_ones() {
2000 let mut bv: BitMap<8> = BitMap::new();
2001 for i in 0..200 {
2002 bv.push(i % 7 == 0);
2003 }
2004 assert_eq!(bv.ones_iter().count() as u64, bv.count_ones());
2005 }
2006
2007 #[test]
2008 fn test_ones_iter_different_chunk_sizes() {
2009 let pattern: Vec<bool> = (0..100).map(|i| i % 5 == 0).collect();
2010 let expected: Vec<u64> = (0..100).filter(|i| i % 5 == 0).collect();
2011
2012 let bv4: BitMap<4> = pattern.as_slice().into();
2013 let bv8: BitMap<8> = pattern.as_slice().into();
2014 let bv16: BitMap<16> = pattern.as_slice().into();
2015
2016 assert_eq!(bv4.ones_iter().collect::<Vec<_>>(), expected);
2017 assert_eq!(bv8.ones_iter().collect::<Vec<_>>(), expected);
2018 assert_eq!(bv16.ones_iter().collect::<Vec<_>>(), expected);
2019 }
2020
2021 #[test]
2022 fn test_codec_roundtrip() {
2023 let original: BitMap<4> = BitMap::new();
2025 let encoded = original.encode();
2026 let decoded = BitMap::decode_cfg(&mut encoded.as_ref(), &(usize::MAX as u64)).unwrap();
2027 assert_eq!(original, decoded);
2028
2029 let pattern = [true, false, true, false, true];
2031 let original: BitMap<4> = pattern.as_ref().into();
2032 let encoded = original.encode();
2033 let decoded = BitMap::decode_cfg(&mut encoded.as_ref(), &(usize::MAX as u64)).unwrap();
2034 assert_eq!(original, decoded);
2035
2036 for (i, &expected) in pattern.iter().enumerate() {
2038 assert_eq!(decoded.get(i as u64), expected);
2039 }
2040
2041 let mut large_original: BitMap<8> = BitMap::new();
2043 for i in 0..100 {
2044 large_original.push(i % 7 == 0);
2045 }
2046
2047 let encoded = large_original.encode();
2048 let decoded = BitMap::decode_cfg(&mut encoded.as_ref(), &(usize::MAX as u64)).unwrap();
2049 assert_eq!(large_original, decoded);
2050
2051 assert_eq!(decoded.len(), 100);
2053 for i in 0..100 {
2054 assert_eq!(decoded.get(i as u64), i % 7 == 0);
2055 }
2056 }
2057
2058 #[test]
2059 fn test_codec_different_chunk_sizes() {
2060 let pattern = [true, false, true, true, false, false, true];
2061
2062 let bv4: BitMap<4> = pattern.as_ref().into();
2064 let bv8: BitMap<8> = pattern.as_ref().into();
2065 let bv16: BitMap<16> = pattern.as_ref().into();
2066
2067 let encoded4 = bv4.encode();
2069 let decoded4 = BitMap::decode_cfg(&mut encoded4.as_ref(), &(usize::MAX as u64)).unwrap();
2070 assert_eq!(bv4, decoded4);
2071
2072 let encoded8 = bv8.encode();
2073 let decoded8 = BitMap::decode_cfg(&mut encoded8.as_ref(), &(usize::MAX as u64)).unwrap();
2074 assert_eq!(bv8, decoded8);
2075
2076 let encoded16 = bv16.encode();
2077 let decoded16 = BitMap::decode_cfg(&mut encoded16.as_ref(), &(usize::MAX as u64)).unwrap();
2078 assert_eq!(bv16, decoded16);
2079
2080 for (i, &expected) in pattern.iter().enumerate() {
2082 let i = i as u64;
2083 assert_eq!(decoded4.get(i), expected);
2084 assert_eq!(decoded8.get(i), expected);
2085 assert_eq!(decoded16.get(i), expected);
2086 }
2087 }
2088
2089 #[test]
2090 fn test_codec_edge_cases() {
2091 let mut bv: BitMap<4> = BitMap::new();
2093 for i in 0..32 {
2094 bv.push(i % 2 == 0);
2095 }
2096
2097 let encoded = bv.encode();
2098 let decoded = BitMap::decode_cfg(&mut encoded.as_ref(), &(usize::MAX as u64)).unwrap();
2099 assert_eq!(bv, decoded);
2100 assert_eq!(decoded.len(), 32);
2101
2102 let mut bv2: BitMap<4> = BitMap::new();
2104 for i in 0..35 {
2105 bv2.push(i % 3 == 0);
2107 }
2108
2109 let encoded2 = bv2.encode();
2110 let decoded2 = BitMap::decode_cfg(&mut encoded2.as_ref(), &(usize::MAX as u64)).unwrap();
2111 assert_eq!(bv2, decoded2);
2112 assert_eq!(decoded2.len(), 35);
2113 }
2114
2115 #[test]
2116 fn test_encode_size() {
2117 let bv: BitMap<4> = BitMap::new();
2119 let encoded = bv.encode();
2120 assert_eq!(bv.encode_size(), encoded.len());
2121
2122 let pattern = [true, false, true, false, true];
2124 let bv: BitMap<4> = pattern.as_ref().into();
2125 let encoded = bv.encode();
2126 assert_eq!(bv.encode_size(), encoded.len());
2127
2128 let mut large_bv: BitMap<8> = BitMap::new();
2130 for i in 0..100 {
2131 large_bv.push(i % 2 == 0);
2132 }
2133 let encoded = large_bv.encode();
2134 assert_eq!(large_bv.encode_size(), encoded.len());
2135 }
2136
2137 #[test]
2138 fn test_codec_empty_chunk_optimization() {
2139 let bv_empty: BitMap<4> = BitMap::new();
2143 let encoded_empty = bv_empty.encode();
2144 let decoded_empty: BitMap<4> =
2145 BitMap::decode_cfg(&mut encoded_empty.as_ref(), &(usize::MAX as u64)).unwrap();
2146 assert_eq!(bv_empty, decoded_empty);
2147 assert_eq!(bv_empty.len(), decoded_empty.len());
2148 assert_eq!(encoded_empty.len(), bv_empty.len().encode_size());
2150
2151 let mut bv_exact: BitMap<4> = BitMap::new();
2153 for _ in 0..32 {
2154 bv_exact.push(true);
2155 }
2156 let encoded_exact = bv_exact.encode();
2157 let decoded_exact: BitMap<4> =
2158 BitMap::decode_cfg(&mut encoded_exact.as_ref(), &(usize::MAX as u64)).unwrap();
2159 assert_eq!(bv_exact, decoded_exact);
2160
2161 let mut bv_partial: BitMap<4> = BitMap::new();
2163 for _ in 0..35 {
2164 bv_partial.push(true);
2165 }
2166 let encoded_partial = bv_partial.encode();
2167 let decoded_partial: BitMap<4> =
2168 BitMap::decode_cfg(&mut encoded_partial.as_ref(), &(usize::MAX as u64)).unwrap();
2169 assert_eq!(bv_partial, decoded_partial);
2170 assert_eq!(bv_partial.len(), decoded_partial.len());
2171
2172 assert!(encoded_exact.len() < encoded_partial.len());
2174 assert_eq!(encoded_exact.len(), bv_exact.len().encode_size() + 4); assert_eq!(encoded_partial.len(), bv_partial.len().encode_size() + 8); }
2177
2178 #[test]
2179 fn test_codec_error_cases() {
2180 let mut buf = BytesMut::new();
2182 100u64.write(&mut buf); for _ in 0..4 {
2186 [0u8; 4].write(&mut buf);
2187 }
2188
2189 let result = BitMap::<4>::decode_cfg(&mut buf, &99);
2191 assert!(matches!(result, Err(CodecError::InvalidLength(100))));
2192
2193 let mut buf = BytesMut::new();
2195 100u64.write(&mut buf); [0u8; 4].write(&mut buf);
2198 [0u8; 4].write(&mut buf);
2199 [0u8; 4].write(&mut buf);
2200
2201 let result = BitMap::<4>::decode_cfg(&mut buf, &(usize::MAX as u64));
2202 assert!(result.is_err());
2204
2205 let original: BitMap<4> = BitMap::ones(20);
2209 let mut buf = BytesMut::new();
2210 original.write(&mut buf);
2211
2212 let corrupted_data = buf.freeze();
2214 let mut corrupted_bytes = corrupted_data.to_vec();
2215
2216 let last_byte_idx = corrupted_bytes.len() - 1;
2220 corrupted_bytes[last_byte_idx] |= 0xF0;
2221
2222 let result = BitMap::<4>::read_cfg(&mut corrupted_bytes.as_slice(), &(usize::MAX as u64));
2224 assert!(matches!(
2225 result,
2226 Err(CodecError::Invalid(
2227 "BitMap",
2228 "Invalid trailing bits in encoded data"
2229 ))
2230 ));
2231 }
2232
2233 #[test]
2234 fn test_codec_range_config() {
2235 let mut original: BitMap<4> = BitMap::new();
2239 for i in 0..100 {
2240 original.push(i % 3 == 0);
2241 }
2242
2243 let mut buf = BytesMut::new();
2245 original.write(&mut buf);
2246
2247 let result = BitMap::<4>::decode_cfg(&mut buf.as_ref(), &50);
2249 assert!(matches!(result, Err(CodecError::InvalidLength(100))));
2250
2251 let decoded = BitMap::<4>::decode_cfg(&mut buf.as_ref(), &100).unwrap();
2253 assert_eq!(decoded.len(), 100);
2254 assert_eq!(decoded, original);
2255
2256 let decoded = BitMap::<4>::decode_cfg(&mut buf.as_ref(), &101).unwrap();
2258 assert_eq!(decoded.len(), 100);
2259 assert_eq!(decoded, original);
2260
2261 let empty = BitMap::<4>::new();
2263 let mut buf = BytesMut::new();
2264 empty.write(&mut buf);
2265
2266 let decoded = BitMap::<4>::decode_cfg(&mut buf.as_ref(), &0).unwrap();
2268 assert_eq!(decoded.len(), 0);
2269 assert!(decoded.is_empty());
2270
2271 let decoded = BitMap::<4>::decode_cfg(&mut buf.as_ref(), &1).unwrap();
2273 assert_eq!(decoded.len(), 0);
2274 assert!(decoded.is_empty());
2275 }
2276
2277 #[test]
2278 fn test_from() {
2279 let vec_bool = vec![true, false, true, false, true];
2283 let bv: BitMap<4> = vec_bool.into();
2284 assert_eq!(bv.len(), 5);
2285 assert_eq!(bv.count_ones(), 3);
2286 assert_eq!(bv.count_zeros(), 2);
2287 for (i, &expected) in [true, false, true, false, true].iter().enumerate() {
2288 assert_eq!(bv.get(i as u64), expected);
2289 }
2290
2291 let array = [false, true, true, false];
2293 let bv: BitMap<4> = (&array).into();
2294 assert_eq!(bv.len(), 4);
2295 assert_eq!(bv.count_ones(), 2);
2296 assert_eq!(bv.count_zeros(), 2);
2297 for (i, &expected) in array.iter().enumerate() {
2298 assert_eq!(bv.get(i as u64), expected);
2299 }
2300
2301 let empty: Vec<bool> = vec![];
2303 let bv: BitMap<4> = empty.into();
2304 assert_eq!(bv.len(), 0);
2305 assert!(bv.is_empty());
2306
2307 let large: Vec<bool> = (0..100).map(|i| i % 3 == 0).collect();
2309 let bv: BitMap<8> = large.clone().into();
2310 assert_eq!(bv.len(), 100);
2311 for (i, &expected) in large.iter().enumerate() {
2312 assert_eq!(bv.get(i as u64), expected);
2313 }
2314 }
2315
2316 #[test]
2317 fn test_debug_formatting() {
2318 let bv: BitMap<4> = BitMap::new();
2322 let debug_str = format!("{bv:?}");
2323 assert_eq!(debug_str, "BitMap[]");
2324
2325 let bv: BitMap<4> = [true, false, true, false, true].as_ref().into();
2327 let debug_str = format!("{bv:?}");
2328 assert_eq!(debug_str, "BitMap[10101]");
2329
2330 let pattern: Vec<bool> = (0..64).map(|i| i % 2 == 0).collect();
2332 let bv: BitMap<8> = pattern.into();
2333 let debug_str = format!("{bv:?}");
2334 let expected_pattern = "1010".repeat(16); assert_eq!(debug_str, format!("BitMap[{expected_pattern}]"));
2336
2337 let large_pattern: Vec<bool> = (0..100).map(|i| i % 2 == 0).collect();
2339 let bv: BitMap<16> = large_pattern.into();
2340 let debug_str = format!("{bv:?}");
2341
2342 let first_32 = "10".repeat(16); let last_32 = "10".repeat(16); let expected = format!("BitMap[{first_32}...{last_32}]");
2346 assert_eq!(debug_str, expected);
2347
2348 let bv: BitMap<4> = [true].as_ref().into();
2350 assert_eq!(format!("{bv:?}"), "BitMap[1]");
2351
2352 let bv: BitMap<4> = [false].as_ref().into();
2353 assert_eq!(format!("{bv:?}"), "BitMap[0]");
2354
2355 let pattern: Vec<bool> = (0..65).map(|i| i == 0 || i == 64).collect(); let bv: BitMap<16> = pattern.into();
2358 let debug_str = format!("{bv:?}");
2359
2360 let first_32 = "1".to_string() + &"0".repeat(31);
2362 let last_32 = "0".repeat(31) + "1";
2363 let expected = format!("BitMap[{first_32}...{last_32}]");
2364 assert_eq!(debug_str, expected);
2365 }
2366
2367 #[test]
2368 fn test_from_different_chunk_sizes() {
2369 let pattern = [true, false, true, true, false, false, true];
2371
2372 let bv4: BitMap<4> = pattern.as_ref().into();
2373 let bv8: BitMap<8> = pattern.as_ref().into();
2374 let bv16: BitMap<16> = pattern.as_ref().into();
2375
2376 for bv in [&bv4] {
2379 assert_eq!(bv.len(), 7);
2380 assert_eq!(bv.count_ones(), 4);
2381 assert_eq!(bv.count_zeros(), 3);
2382 for (i, &expected) in pattern.iter().enumerate() {
2383 assert_eq!(bv.get(i as u64), expected);
2384 }
2385 }
2386
2387 assert_eq!(bv8.len(), 7);
2388 assert_eq!(bv8.count_ones(), 4);
2389 assert_eq!(bv8.count_zeros(), 3);
2390 for (i, &expected) in pattern.iter().enumerate() {
2391 assert_eq!(bv8.get(i as u64), expected);
2392 }
2393
2394 assert_eq!(bv16.len(), 7);
2395 assert_eq!(bv16.count_ones(), 4);
2396 assert_eq!(bv16.count_zeros(), 3);
2397 for (i, &expected) in pattern.iter().enumerate() {
2398 assert_eq!(bv16.get(i as u64), expected);
2399 }
2400 }
2401
2402 #[test]
2403 fn test_prune_chunks() {
2404 let mut bv: BitMap<4> = BitMap::new();
2405 bv.push_chunk(&[1, 2, 3, 4]);
2406 bv.push_chunk(&[5, 6, 7, 8]);
2407 bv.push_chunk(&[9, 10, 11, 12]);
2408
2409 assert_eq!(bv.len(), 96);
2410 assert_eq!(bv.get_chunk(0), &[1, 2, 3, 4]);
2411
2412 bv.prune_chunks(1);
2414 assert_eq!(bv.len(), 64);
2415 assert_eq!(bv.get_chunk(0), &[5, 6, 7, 8]);
2416 assert_eq!(bv.get_chunk(1), &[9, 10, 11, 12]);
2417
2418 bv.prune_chunks(1);
2420 assert_eq!(bv.len(), 32);
2421 assert_eq!(bv.get_chunk(0), &[9, 10, 11, 12]);
2422 }
2423
2424 #[test]
2425 #[should_panic(expected = "cannot prune")]
2426 fn test_prune_too_many_chunks() {
2427 let mut bv: BitMap<4> = BitMap::new();
2428 bv.push_chunk(&[1, 2, 3, 4]);
2429 bv.push_chunk(&[5, 6, 7, 8]);
2430 bv.push(true);
2431
2432 bv.prune_chunks(4);
2434 }
2435
2436 #[test]
2437 fn test_prune_with_partial_last_chunk() {
2438 let mut bv: BitMap<4> = BitMap::new();
2439 bv.push_chunk(&[1, 2, 3, 4]);
2440 bv.push_chunk(&[5, 6, 7, 8]);
2441 bv.push(true);
2442 bv.push(false);
2443
2444 assert_eq!(bv.len(), 66);
2445
2446 bv.prune_chunks(1);
2448 assert_eq!(bv.len(), 34);
2449 assert_eq!(bv.get_chunk(0), &[5, 6, 7, 8]);
2450
2451 assert!(bv.get(32));
2453 assert!(!bv.get(33));
2454 }
2455
2456 #[test]
2457 fn test_prune_all_chunks_resets_next_bit() {
2458 let mut bv: BitMap<4> = BitMap::new();
2459 bv.push_chunk(&[1, 2, 3, 4]);
2460 bv.push_chunk(&[5, 6, 7, 8]);
2461 bv.push(true);
2462 bv.push(false);
2463 bv.push(true);
2464
2465 assert_eq!(bv.len(), 67);
2467
2468 bv.prune_chunks(3);
2470
2471 assert_eq!(bv.len(), 0);
2473 assert!(bv.is_empty());
2474
2475 bv.push(true);
2477 assert_eq!(bv.len(), 1);
2478 assert!(bv.get(0));
2479 }
2480
2481 #[test]
2482 fn test_is_chunk_aligned() {
2483 let bv: BitMap<4> = BitMap::new();
2485 assert!(bv.is_chunk_aligned());
2486
2487 let mut bv4: BitMap<4> = BitMap::new();
2489 assert!(bv4.is_chunk_aligned());
2490
2491 for i in 1..=32 {
2493 bv4.push(i % 2 == 0);
2494 if i == 32 {
2495 assert!(bv4.is_chunk_aligned()); } else {
2497 assert!(!bv4.is_chunk_aligned()); }
2499 }
2500
2501 for i in 33..=64 {
2503 bv4.push(i % 2 == 0);
2504 if i == 64 {
2505 assert!(bv4.is_chunk_aligned()); } else {
2507 assert!(!bv4.is_chunk_aligned()); }
2509 }
2510
2511 let mut bv: BitMap<8> = BitMap::new();
2513 assert!(bv.is_chunk_aligned());
2514 bv.push_chunk(&[0xFF; 8]);
2515 assert!(bv.is_chunk_aligned()); bv.push_chunk(&[0xAA; 8]);
2517 assert!(bv.is_chunk_aligned()); bv.push(true);
2519 assert!(!bv.is_chunk_aligned()); let mut bv: BitMap<4> = BitMap::new();
2523 for _ in 0..4 {
2524 bv.push_byte(0xFF);
2525 }
2526 assert!(bv.is_chunk_aligned()); bv.pop();
2530 assert!(!bv.is_chunk_aligned()); let bv_zeroes: BitMap<4> = BitMap::zeroes(64);
2534 assert!(bv_zeroes.is_chunk_aligned());
2535
2536 let bv_ones: BitMap<4> = BitMap::ones(96);
2537 assert!(bv_ones.is_chunk_aligned());
2538
2539 let bv_partial: BitMap<4> = BitMap::zeroes(65);
2540 assert!(!bv_partial.is_chunk_aligned());
2541 }
2542
2543 #[test]
2544 fn test_unprune_restores_length() {
2545 let mut prunable: Prunable<4> = Prunable::new_with_pruned_chunks(1).unwrap();
2546 assert_eq!(prunable.len(), Prunable::<4>::CHUNK_SIZE_BITS);
2547 assert_eq!(prunable.pruned_chunks(), 1);
2548 let chunk = [0xDE, 0xAD, 0xBE, 0xEF];
2549
2550 prunable.unprune_chunks(&[chunk]);
2551
2552 assert_eq!(prunable.pruned_chunks(), 0);
2553 assert_eq!(prunable.len(), Prunable::<4>::CHUNK_SIZE_BITS);
2554 assert_eq!(prunable.get_chunk_containing(0), &chunk);
2555 }
2556
2557 mod proptests {
2558 use super::*;
2559 use proptest::prelude::*;
2560
2561 proptest! {
2562 #[test]
2563 fn is_unset_matches_naive(
2564 bits in prop::collection::vec(any::<bool>(), 1..=512usize),
2565 start in 0u64..=512,
2566 end in 0u64..=512,
2567 ) {
2568 let bitmap: BitMap = BitMap::from(bits.as_slice());
2569 let len = bitmap.len();
2570 let start = start.min(len);
2571 let end = end.max(start).min(len);
2572 let range = start..end;
2573
2574 let expected = range.clone().all(|i| !bitmap.get(i));
2575
2576 prop_assert_eq!(bitmap.is_unset(range), expected);
2577 }
2578 }
2579 }
2580
2581 #[test]
2582 fn is_unset_all_zeros() {
2583 let bitmap = BitMap::<8>::zeroes(256);
2584 assert!(bitmap.is_unset(0..256));
2585 }
2586
2587 #[test]
2588 fn is_unset_all_ones() {
2589 let bitmap = BitMap::<8>::ones(256);
2590 assert!(!bitmap.is_unset(0..256));
2591 }
2592
2593 #[test]
2594 fn is_unset_single_bit() {
2595 let mut bitmap = BitMap::<8>::zeroes(64);
2596 bitmap.set(31, true);
2597 assert!(bitmap.is_unset(0..31));
2598 assert!(!bitmap.is_unset(0..32));
2599 assert!(!bitmap.is_unset(31..32));
2600 assert!(bitmap.is_unset(32..64));
2601 }
2602
2603 #[test]
2604 fn is_unset_empty_range() {
2605 let bitmap = BitMap::<8>::ones(64);
2606 assert!(bitmap.is_unset(0..0));
2607 assert!(bitmap.is_unset(32..32));
2608 assert!(bitmap.is_unset(64..64));
2609 }
2610
2611 #[test]
2612 fn is_unset_chunk_boundaries() {
2613 let mut bitmap = BitMap::<1>::zeroes(32);
2615 bitmap.set(7, true);
2616 assert!(bitmap.is_unset(0..7));
2617 assert!(!bitmap.is_unset(0..8));
2618 assert!(bitmap.is_unset(8..32));
2619 }
2620
2621 #[test]
2622 fn is_unset_small_chunk_multi_span() {
2623 let mut bitmap = BitMap::<4>::zeroes(128);
2625 bitmap.set(96, true);
2626 assert!(bitmap.is_unset(0..96));
2627 assert!(!bitmap.is_unset(0..97));
2628 assert!(bitmap.is_unset(97..128));
2629 }
2630
2631 #[test]
2632 #[should_panic(expected = "out of bounds")]
2633 fn is_unset_out_of_bounds() {
2634 let bitmap = BitMap::<8>::zeroes(64);
2635 bitmap.is_unset(0..65);
2636 }
2637
2638 #[cfg(feature = "arbitrary")]
2639 mod conformance {
2640 use super::*;
2641 use commonware_codec::conformance::CodecConformance;
2642
2643 commonware_conformance::conformance_tests! {
2644 CodecConformance<BitMap>
2645 }
2646 }
2647}