1#[cfg(not(feature = "std"))]
7use alloc::{collections::VecDeque, vec::Vec};
8use bytes::BufMut;
9use commonware_codec::{
10 Buf, EncodeSize, Error as CodecError, FixedSize, RangeCfg, Read, ReadExt, Write,
11 util::at_least_items,
12};
13use core::{
14 fmt::{self, Formatter, Write as _},
15 iter,
16 ops::{BitAnd, BitOr, BitXor, Index, Range},
17};
18#[cfg(feature = "std")]
19use std::collections::VecDeque;
20
21#[cfg(feature = "std")]
22mod atomic;
23#[cfg(feature = "std")]
24pub use atomic::Atomic;
25mod prunable;
26pub use prunable::Prunable;
27
28pub mod historical;
29commonware_macros::stability_mod!(ALPHA, pub mod roaring);
30
31pub const DEFAULT_CHUNK_SIZE: usize = 8;
33
34#[derive(Clone, PartialEq, Eq, Hash)]
41pub struct BitMap<const N: usize = DEFAULT_CHUNK_SIZE> {
42 chunks: VecDeque<[u8; N]>,
48
49 len: u64,
51}
52
53impl<const N: usize> BitMap<N> {
54 const _CHUNK_SIZE_NON_ZERO_ASSERT: () = assert!(N > 0, "chunk size must be > 0");
55
56 pub const CHUNK_SIZE_BITS: u64 = (N * 8) as u64;
58
59 pub const EMPTY_CHUNK: [u8; N] = [0u8; N];
61
62 pub const FULL_CHUNK: [u8; N] = [u8::MAX; N];
64
65 pub const fn new() -> Self {
69 #[allow(path_statements)]
70 Self::_CHUNK_SIZE_NON_ZERO_ASSERT; Self {
73 chunks: VecDeque::new(),
74 len: 0,
75 }
76 }
77
78 pub fn with_capacity(size: u64) -> Self {
80 #[allow(path_statements)]
81 Self::_CHUNK_SIZE_NON_ZERO_ASSERT; Self {
84 chunks: VecDeque::with_capacity(size.div_ceil(Self::CHUNK_SIZE_BITS) as usize),
85 len: 0,
86 }
87 }
88
89 pub fn zeroes(size: u64) -> Self {
91 #[allow(path_statements)]
92 Self::_CHUNK_SIZE_NON_ZERO_ASSERT; let num_chunks = size.div_ceil(Self::CHUNK_SIZE_BITS) as usize;
95 let mut chunks = VecDeque::with_capacity(num_chunks);
96 for _ in 0..num_chunks {
97 chunks.push_back(Self::EMPTY_CHUNK);
98 }
99 Self { chunks, len: size }
100 }
101
102 pub fn ones(size: u64) -> Self {
104 #[allow(path_statements)]
105 Self::_CHUNK_SIZE_NON_ZERO_ASSERT; let num_chunks = size.div_ceil(Self::CHUNK_SIZE_BITS) as usize;
108 let mut chunks = VecDeque::with_capacity(num_chunks);
109 for _ in 0..num_chunks {
110 chunks.push_back(Self::FULL_CHUNK);
111 }
112 let mut result = Self { chunks, len: size };
113 result.clear_trailing_bits();
115 result
116 }
117
118 #[cfg(feature = "std")]
124 fn from_chunks(chunks: VecDeque<[u8; N]>, len: u64) -> Self {
125 assert_eq!(
126 chunks.len() as u64,
127 len.div_ceil(Self::CHUNK_SIZE_BITS),
128 "chunk count does not match len"
129 );
130 let mut bitmap = Self { chunks, len };
131 assert!(!bitmap.clear_trailing_bits(), "bit past len set");
132 bitmap
133 }
134
135 #[inline]
139 pub const fn len(&self) -> u64 {
140 self.len
141 }
142
143 #[inline]
145 pub const fn is_empty(&self) -> bool {
146 self.len() == 0
147 }
148
149 #[inline]
151 pub const fn is_chunk_aligned(&self) -> bool {
152 self.len.is_multiple_of(Self::CHUNK_SIZE_BITS)
153 }
154
155 fn chunks_len(&self) -> usize {
157 self.chunks.len()
158 }
159
160 pub fn max_encode_size(bits: u64) -> usize {
166 #[allow(path_statements)]
167 Self::_CHUNK_SIZE_NON_ZERO_ASSERT; let chunks = usize::try_from(bits.div_ceil(Self::CHUNK_SIZE_BITS))
170 .expect("chunk count must fit in usize");
171 chunks * N + u64::SIZE
172 }
173
174 #[inline]
182 pub fn get(&self, bit: u64) -> bool {
183 let chunk = self.get_chunk_containing(bit);
184 Self::get_bit_from_chunk(chunk, bit)
185 }
186
187 #[inline]
193 fn get_chunk_containing(&self, bit: u64) -> &[u8; N] {
194 assert!(
195 bit < self.len(),
196 "bit {} out of bounds (len: {})",
197 bit,
198 self.len()
199 );
200 &self.chunks[Self::to_chunk_index(bit)]
201 }
202
203 #[inline]
210 pub(super) fn get_chunk(&self, chunk: usize) -> &[u8; N] {
211 assert!(
212 chunk < self.chunks.len(),
213 "chunk {} out of bounds (chunks: {})",
214 chunk,
215 self.chunks.len()
216 );
217 &self.chunks[chunk]
218 }
219
220 #[inline]
223 pub const fn get_bit_from_chunk(chunk: &[u8; N], bit: u64) -> bool {
224 let byte = Self::chunk_byte_offset(bit);
225 let byte = chunk[byte];
226 let mask = Self::chunk_byte_bitmask(bit);
227 (byte & mask) != 0
228 }
229
230 #[inline]
236 fn last_chunk(&self) -> (&[u8; N], u64) {
237 let rem = self.len % Self::CHUNK_SIZE_BITS;
238 let bits_in_last_chunk = if rem == 0 { Self::CHUNK_SIZE_BITS } else { rem };
239 (self.chunks.back().unwrap(), bits_in_last_chunk)
240 }
241
242 pub fn extend_to(&mut self, new_len: u64) {
247 if new_len <= self.len {
248 return;
249 }
250 let new_chunks_needed = new_len.div_ceil(Self::CHUNK_SIZE_BITS) as usize;
252 let current_chunks = self.chunks.len();
253 for _ in current_chunks..new_chunks_needed {
254 self.chunks.push_back(Self::EMPTY_CHUNK);
255 }
256 self.len = new_len;
257 }
258
259 pub fn push(&mut self, bit: bool) {
261 if self.is_chunk_aligned() {
263 self.chunks.push_back(Self::EMPTY_CHUNK);
264 }
265
266 if bit {
268 let last_chunk = self.chunks.back_mut().unwrap();
269 let chunk_byte = Self::chunk_byte_offset(self.len);
270 last_chunk[chunk_byte] |= Self::chunk_byte_bitmask(self.len);
271 }
272
273 self.len += 1;
275 }
276
277 pub fn pop(&mut self) -> bool {
283 assert!(!self.is_empty(), "Cannot pop from empty bitmap");
284
285 let last_bit_pos = self.len - 1;
287 let bit = Self::get_bit_from_chunk(self.chunks.back().unwrap(), last_bit_pos);
288
289 self.len -= 1;
291
292 if bit {
294 let chunk_byte = Self::chunk_byte_offset(last_bit_pos);
295 let mask = Self::chunk_byte_bitmask(last_bit_pos);
296 self.chunks.back_mut().unwrap()[chunk_byte] &= !mask;
297 }
298
299 if self.is_chunk_aligned() {
301 self.chunks.pop_back();
302 }
303
304 bit
305 }
306
307 pub fn truncate(&mut self, new_len: u64) {
313 assert!(new_len <= self.len(), "cannot truncate to a larger size");
314
315 while self.len > new_len && !self.is_chunk_aligned() {
317 self.pop();
318 }
319
320 while self.len - new_len >= Self::CHUNK_SIZE_BITS {
322 self.pop_chunk();
323 }
324
325 while self.len > new_len {
327 self.pop();
328 }
329 }
330
331 pub(super) fn pop_chunk(&mut self) -> [u8; N] {
337 assert!(
338 self.len() >= Self::CHUNK_SIZE_BITS,
339 "cannot pop chunk: bitmap has fewer than CHUNK_SIZE_BITS bits"
340 );
341 assert!(
342 self.is_chunk_aligned(),
343 "cannot pop chunk when not chunk aligned"
344 );
345
346 let chunk = self.chunks.pop_back().expect("chunk must exist");
348 self.len -= Self::CHUNK_SIZE_BITS;
349 chunk
350 }
351
352 #[inline]
358 pub fn flip(&mut self, bit: u64) {
359 self.assert_bit(bit);
360 let chunk = Self::to_chunk_index(bit);
361 let byte = Self::chunk_byte_offset(bit);
362 let mask = Self::chunk_byte_bitmask(bit);
363 self.chunks[chunk][byte] ^= mask;
364 }
365
366 pub fn flip_all(&mut self) {
368 for chunk in &mut self.chunks {
369 for byte in chunk {
370 *byte = !*byte;
371 }
372 }
373 self.clear_trailing_bits();
375 }
376
377 pub fn set(&mut self, bit: u64, value: bool) {
383 assert!(
384 bit < self.len(),
385 "bit {} out of bounds (len: {})",
386 bit,
387 self.len()
388 );
389
390 let chunk = &mut self.chunks[Self::to_chunk_index(bit)];
391 let byte = Self::chunk_byte_offset(bit);
392 let mask = Self::chunk_byte_bitmask(bit);
393 if value {
394 chunk[byte] |= mask;
395 } else {
396 chunk[byte] &= !mask;
397 }
398 }
399
400 #[inline]
402 pub fn set_all(&mut self, bit: bool) {
403 let value = if bit { u8::MAX } else { 0 };
404 for chunk in &mut self.chunks {
405 chunk.fill(value);
406 }
407 if bit {
409 self.clear_trailing_bits();
410 }
411 }
412
413 fn push_byte(&mut self, byte: u8) {
419 assert!(
420 self.len.is_multiple_of(8),
421 "cannot add byte when not byte aligned"
422 );
423
424 if self.is_chunk_aligned() {
426 self.chunks.push_back(Self::EMPTY_CHUNK);
427 }
428
429 let chunk_byte = Self::chunk_byte_offset(self.len);
430 self.chunks.back_mut().unwrap()[chunk_byte] = byte;
431 self.len += 8;
432 }
433
434 pub fn push_chunk(&mut self, chunk: &[u8; N]) {
440 assert!(
441 self.is_chunk_aligned(),
442 "cannot add chunk when not chunk aligned"
443 );
444 self.chunks.push_back(*chunk);
445 self.len += Self::CHUNK_SIZE_BITS;
446 }
447
448 pub fn extend_from_bitmap<const M: usize>(&mut self, other: &BitMap<M>) {
450 let mut next = 0;
452 while next < other.len() && !self.is_chunk_aligned() {
453 self.push(other.get(next));
454 next += 1;
455 }
456
457 let remaining = other.len() - next;
462 let new_chunks = remaining.div_ceil(Self::CHUNK_SIZE_BITS) as usize;
463 self.chunks.reserve(new_chunks);
464 let (front, back) = other.chunks.as_slices();
465 let mut bytes = front
466 .as_flattened()
467 .iter()
468 .chain(back.as_flattened())
469 .copied()
470 .skip((next / 8) as usize);
471 let shift = next % 8;
472 let mut current = bytes.next().unwrap_or(0);
473 for _ in 0..new_chunks {
474 self.chunks.push_back(Self::EMPTY_CHUNK);
475 for out in self.chunks.back_mut().unwrap() {
476 let following = bytes.next().unwrap_or(0);
477 *out = if shift == 0 {
478 current
479 } else {
480 (u16::from_le_bytes([current, following]) >> shift) as u8
481 };
482 current = following;
483 }
484 }
485 self.len += remaining;
486 }
487
488 fn clear_trailing_bits(&mut self) -> bool {
493 if self.chunks.is_empty() {
494 return false;
495 }
496
497 let pos_in_chunk = self.len % Self::CHUNK_SIZE_BITS;
498 if pos_in_chunk == 0 {
499 return false;
501 }
502
503 let mut flipped_any = false;
504 let last_chunk = self.chunks.back_mut().unwrap();
505
506 let last_byte_index = ((pos_in_chunk - 1) / 8) as usize;
508 for byte in last_chunk.iter_mut().skip(last_byte_index + 1) {
509 if *byte != 0 {
510 flipped_any = true;
511 *byte = 0;
512 }
513 }
514
515 let bits_in_last_byte = pos_in_chunk % 8;
517 if bits_in_last_byte != 0 {
518 let mask = (1u8 << bits_in_last_byte) - 1;
519 let old_byte = last_chunk[last_byte_index];
520 let new_byte = old_byte & mask;
521 if old_byte != new_byte {
522 flipped_any = true;
523 last_chunk[last_byte_index] = new_byte;
524 }
525 }
526
527 flipped_any
528 }
529
530 fn prune_chunks(&mut self, chunks: usize) {
538 assert!(
539 chunks <= self.chunks.len(),
540 "cannot prune {chunks} chunks, only {} available",
541 self.chunks.len()
542 );
543 self.chunks.drain(..chunks);
544 let bits_removed = (chunks as u64) * Self::CHUNK_SIZE_BITS;
546 self.len = self.len.saturating_sub(bits_removed);
547 }
548
549 pub(super) fn prepend_chunk(&mut self, chunk: &[u8; N]) {
551 self.chunks.push_front(*chunk);
552 self.len += Self::CHUNK_SIZE_BITS;
553 }
554
555 pub(super) fn set_chunk_by_index(&mut self, chunk_index: usize, chunk_data: &[u8; N]) {
565 assert!(
566 chunk_index < self.chunks.len(),
567 "chunk index {chunk_index} out of bounds (chunks_len: {})",
568 self.chunks.len()
569 );
570 self.chunks[chunk_index].copy_from_slice(chunk_data);
571 }
572
573 #[inline]
577 pub fn count_ones(&self) -> u64 {
578 let (front, back) = self.chunks.as_slices();
582 Self::count_ones_in_chunk_slice(front) + Self::count_ones_in_chunk_slice(back)
583 }
584
585 #[inline]
586 fn count_ones_in_chunk_slice(chunks: &[[u8; N]]) -> u64 {
587 let mut total = 0u64;
588 let (words, remainder) = chunks.as_flattened().as_chunks::<8>();
589 for word in words {
590 total += u64::from_le_bytes(*word).count_ones() as u64;
591 }
592 for byte in remainder {
593 total += byte.count_ones() as u64;
594 }
595 total
596 }
597
598 #[inline]
600 pub fn count_zeros(&self) -> u64 {
601 self.len() - self.count_ones()
602 }
603
604 #[inline]
608 pub(super) const fn chunk_byte_bitmask(bit: u64) -> u8 {
609 1 << (bit % 8)
610 }
611
612 #[inline]
614 pub(super) const fn chunk_byte_offset(bit: u64) -> usize {
615 ((bit / 8) % N as u64) as usize
616 }
617
618 #[inline]
624 pub(super) fn to_chunk_index(bit: u64) -> usize {
625 let chunk = bit / Self::CHUNK_SIZE_BITS;
626 assert!(
627 chunk <= usize::MAX as u64,
628 "chunk overflow: {chunk} exceeds usize::MAX",
629 );
630 chunk as usize
631 }
632
633 pub const fn iter(&self) -> Iterator<'_, N> {
637 Iterator {
638 bitmap: self,
639 pos: 0,
640 }
641 }
642
643 pub fn ones_iter(&self) -> OnesIter<'_, Self, N> {
645 Readable::ones_iter_from(self, 0)
646 }
647
648 #[inline]
652 fn binary_op<F: Fn(u8, u8) -> u8>(&mut self, other: &Self, op: F) {
653 self.assert_eq_len(other);
654 for (a_chunk, b_chunk) in self.chunks.iter_mut().zip(other.chunks.iter()) {
655 for (a_byte, b_byte) in a_chunk.iter_mut().zip(b_chunk.iter()) {
656 *a_byte = op(*a_byte, *b_byte);
657 }
658 }
659 self.clear_trailing_bits();
661 }
662
663 pub fn and(&mut self, other: &Self) {
669 self.binary_op(other, |a, b| a & b);
670 }
671
672 pub fn or(&mut self, other: &Self) {
678 self.binary_op(other, |a, b| a | b);
679 }
680
681 pub fn xor(&mut self, other: &Self) {
687 self.binary_op(other, |a, b| a ^ b);
688 }
689
690 #[inline(always)]
694 fn assert_bit(&self, bit: u64) {
695 assert!(
696 bit < self.len(),
697 "bit {} out of bounds (len: {})",
698 bit,
699 self.len()
700 );
701 }
702
703 #[inline(always)]
705 fn assert_eq_len(&self, other: &Self) {
706 assert_eq!(
707 self.len(),
708 other.len(),
709 "BitMap lengths don't match: {} vs {}",
710 self.len(),
711 other.len()
712 );
713 }
714
715 pub fn is_unset(&self, range: Range<u64>) -> bool {
738 assert!(
739 range.end <= self.len(),
740 "range end {} out of bounds (len: {})",
741 range.end,
742 self.len()
743 );
744 if range.start >= range.end {
745 return true;
746 }
747 let start = range.start;
748 let end = range.end;
749
750 let end = end - 1;
754
755 let first_chunk = Self::to_chunk_index(start);
757 let last_chunk = Self::to_chunk_index(end);
758
759 for full_chunk in (first_chunk + 1)..last_chunk {
762 if self.chunks[full_chunk] != Self::EMPTY_CHUNK {
763 return false;
764 }
765 }
766
767 let start_byte = Self::chunk_byte_offset(start);
769 let end_byte = Self::chunk_byte_offset(end);
770 let start_mask = (0xFFu16 << ((start & 0b111) as u32)) as u8;
771 let end_mask = (0xFFu16 >> (7 - ((end & 0b111) as u32))) as u8;
772 let first = &self.chunks[first_chunk];
773 let first_end_byte = if first_chunk == last_chunk {
774 end_byte
775 } else {
776 N - 1
777 };
778 for (i, &byte) in first
779 .iter()
780 .enumerate()
781 .take(first_end_byte + 1)
782 .skip(start_byte)
783 {
784 let mut mask = 0xFFu8;
785 if i == start_byte {
786 mask &= start_mask;
787 }
788 if first_chunk == last_chunk && i == end_byte {
789 mask &= end_mask;
790 }
791 if (byte & mask) != 0 {
792 return false;
793 }
794 }
795 if first_chunk == last_chunk {
796 return true;
797 }
798
799 let last = &self.chunks[last_chunk];
801 for (i, &byte) in last.iter().enumerate().take(end_byte + 1) {
802 let mask = if i == end_byte { end_mask } else { 0xFF };
803 if (byte & mask) != 0 {
804 return false;
805 }
806 }
807
808 true
809 }
810}
811
812impl<const N: usize> Default for BitMap<N> {
813 fn default() -> Self {
814 Self::new()
815 }
816}
817
818impl<T: AsRef<[bool]>, const N: usize> From<T> for BitMap<N> {
819 fn from(t: T) -> Self {
820 let bools = t.as_ref();
821 let mut bv = Self::with_capacity(bools.len() as u64);
822 for &b in bools {
823 bv.push(b);
824 }
825 bv
826 }
827}
828
829impl<const N: usize> From<BitMap<N>> for Vec<bool> {
830 fn from(bv: BitMap<N>) -> Self {
831 bv.iter().collect()
832 }
833}
834
835impl<const N: usize> fmt::Debug for BitMap<N> {
836 fn fmt(&self, f: &mut Formatter<'_>) -> core::fmt::Result {
837 const MAX_DISPLAY: u64 = 64;
839 const HALF_DISPLAY: u64 = MAX_DISPLAY / 2;
840
841 let write_bit = |formatter: &mut Formatter<'_>, bit: u64| -> core::fmt::Result {
843 formatter.write_char(if self.get(bit) { '1' } else { '0' })
844 };
845
846 f.write_str("BitMap[")?;
847 let len = self.len();
848 if len <= MAX_DISPLAY {
849 for i in 0..len {
851 write_bit(f, i)?;
852 }
853 } else {
854 for i in 0..HALF_DISPLAY {
856 write_bit(f, i)?;
857 }
858
859 f.write_str("...")?;
860
861 for i in (len - HALF_DISPLAY)..len {
862 write_bit(f, i)?;
863 }
864 }
865 f.write_str("]")
866 }
867}
868
869impl<const N: usize> Index<u64> for BitMap<N> {
870 type Output = bool;
871
872 #[inline]
876 fn index(&self, bit: u64) -> &Self::Output {
877 self.assert_bit(bit);
878 let value = self.get(bit);
879 if value { &true } else { &false }
880 }
881}
882
883impl<const N: usize> BitAnd for &BitMap<N> {
884 type Output = BitMap<N>;
885
886 fn bitand(self, rhs: Self) -> Self::Output {
887 self.assert_eq_len(rhs);
888 let mut result = self.clone();
889 result.and(rhs);
890 result
891 }
892}
893
894impl<const N: usize> BitOr for &BitMap<N> {
895 type Output = BitMap<N>;
896
897 fn bitor(self, rhs: Self) -> Self::Output {
898 self.assert_eq_len(rhs);
899 let mut result = self.clone();
900 result.or(rhs);
901 result
902 }
903}
904
905impl<const N: usize> BitXor for &BitMap<N> {
906 type Output = BitMap<N>;
907
908 fn bitxor(self, rhs: Self) -> Self::Output {
909 self.assert_eq_len(rhs);
910 let mut result = self.clone();
911 result.xor(rhs);
912 result
913 }
914}
915
916impl<const N: usize> Write for BitMap<N> {
917 fn write(&self, buf: &mut impl BufMut) {
918 self.len().write(buf);
920
921 let (front, back) = self.chunks.as_slices();
923 buf.put_slice(front.as_flattened());
924 buf.put_slice(back.as_flattened());
925 }
926}
927
928impl<const N: usize> Read for BitMap<N> {
929 type Cfg = RangeCfg<u64>;
931
932 fn read_cfg(buf: &mut impl Buf, range: &Self::Cfg) -> Result<Self, CodecError> {
933 let len = u64::read(buf)?;
935 if !range.contains(&len) {
936 return Err(CodecError::InvalidLength(len as usize));
937 }
938
939 let num_chunks = usize::try_from(len.div_ceil(Self::CHUNK_SIZE_BITS))
941 .map_err(|_| CodecError::EndOfBuffer)?;
942
943 at_least_items(buf, num_chunks, N)?;
945
946 let mut chunks = VecDeque::with_capacity(num_chunks);
948 for _ in 0..num_chunks {
949 let mut chunk = [0u8; N];
950 buf.copy_to_slice(&mut chunk);
951 chunks.push_back(chunk);
952 }
953
954 let mut result = Self { chunks, len };
955
956 if result.clear_trailing_bits() {
958 return Err(CodecError::Invalid(
959 "BitMap",
960 "Invalid trailing bits in encoded data",
961 ));
962 }
963
964 Ok(result)
965 }
966}
967
968impl<const N: usize> EncodeSize for BitMap<N> {
969 fn encode_size(&self) -> usize {
970 self.len().encode_size() + (self.chunks.len() * N)
972 }
973}
974
975pub struct Iterator<'a, const N: usize> {
977 bitmap: &'a BitMap<N>,
979
980 pos: u64,
982}
983
984impl<const N: usize> iter::Iterator for Iterator<'_, N> {
985 type Item = bool;
986
987 fn next(&mut self) -> Option<Self::Item> {
988 if self.pos >= self.bitmap.len() {
989 return None;
990 }
991
992 let bit = self.bitmap.get(self.pos);
993 self.pos += 1;
994 Some(bit)
995 }
996
997 fn size_hint(&self) -> (usize, Option<usize>) {
998 let remaining = self.bitmap.len().saturating_sub(self.pos);
999 let capped = remaining.min(usize::MAX as u64) as usize;
1000 (capped, Some(capped))
1001 }
1002}
1003
1004impl<const N: usize> ExactSizeIterator for Iterator<'_, N> {}
1005
1006pub trait Readable<const N: usize> {
1008 fn complete_chunks(&self) -> usize;
1010
1011 fn get_chunk(&self, chunk: usize) -> [u8; N];
1013
1014 fn last_chunk(&self) -> ([u8; N], u64);
1016
1017 fn pruned_chunks(&self) -> usize;
1019
1020 fn len(&self) -> u64;
1022
1023 fn is_empty(&self) -> bool {
1025 self.len() == 0
1026 }
1027
1028 fn pruned_bits(&self) -> u64 {
1030 (self.pruned_chunks() as u64) * BitMap::<N>::CHUNK_SIZE_BITS
1031 }
1032
1033 fn get_bit(&self, bit: u64) -> bool {
1035 let chunk = self.get_chunk(BitMap::<N>::to_chunk_index(bit));
1036 BitMap::<N>::get_bit_from_chunk(&chunk, bit % BitMap::<N>::CHUNK_SIZE_BITS)
1037 }
1038
1039 fn ones_iter_from(&self, pos: u64) -> OnesIter<'_, Self, N>
1044 where
1045 Self: Sized,
1046 {
1047 self.ones_iter_range(pos..u64::MAX)
1048 }
1049
1050 fn ones_iter_range(&self, range: Range<u64>) -> OnesIter<'_, Self, N>
1055 where
1056 Self: Sized,
1057 {
1058 let end = range.end.min(self.len());
1059 let pos = range.start.max(self.pruned_bits());
1060 let mut iter = OnesIter {
1061 bitmap: self,
1062 end,
1063 base: end,
1064 word: 0,
1065 chunk: [0; N],
1066 };
1067 if pos < end {
1068 let chunk_idx = BitMap::<N>::to_chunk_index(pos);
1069 let chunk_start = chunk_idx as u64 * BitMap::<N>::CHUNK_SIZE_BITS;
1070 iter.chunk = self.get_chunk(chunk_idx);
1071 iter.base = chunk_start + (pos - chunk_start) / 64 * 64;
1072 iter.word = iter.load_word() & (u64::MAX << (pos - iter.base));
1073 }
1074 iter
1075 }
1076}
1077
1078impl<const N: usize> Readable<N> for BitMap<N> {
1079 fn complete_chunks(&self) -> usize {
1080 self.chunks_len()
1081 .saturating_sub(if self.is_chunk_aligned() { 0 } else { 1 })
1082 }
1083
1084 fn get_chunk(&self, chunk: usize) -> [u8; N] {
1085 *Self::get_chunk(self, chunk)
1086 }
1087
1088 fn last_chunk(&self) -> ([u8; N], u64) {
1089 let (c, n) = Self::last_chunk(self);
1090 (*c, n)
1091 }
1092
1093 fn pruned_chunks(&self) -> usize {
1094 0
1095 }
1096
1097 fn len(&self) -> u64 {
1098 self.len
1099 }
1100}
1101
1102pub struct OnesIter<'a, B, const N: usize> {
1114 bitmap: &'a B,
1115 end: u64,
1118 base: u64,
1121 word: u64,
1123 chunk: [u8; N],
1127}
1128
1129impl<B: Readable<N>, const N: usize> OnesIter<'_, B, N> {
1130 fn load_word(&self) -> u64 {
1136 let off = ((self.base % BitMap::<N>::CHUNK_SIZE_BITS) / 8) as usize;
1137 let take = (N - off).min(8);
1138 let mut buf = [0u8; 8];
1139 buf[..take].copy_from_slice(&self.chunk[off..off + take]);
1140 let mut word = u64::from_le_bytes(buf);
1141 let rem = self.end - self.base;
1142 if rem < 64 {
1143 word &= (1 << rem) - 1;
1144 }
1145 word
1146 }
1147}
1148
1149impl<B: Readable<N>, const N: usize> iter::Iterator for OnesIter<'_, B, N> {
1150 type Item = u64;
1151
1152 fn next(&mut self) -> Option<u64> {
1153 let chunk_bits = BitMap::<N>::CHUNK_SIZE_BITS;
1154 while self.word == 0 {
1155 let rel = self.base % chunk_bits;
1159 let same_chunk = rel + 64 < chunk_bits;
1160 let stride = if same_chunk { 64 } else { chunk_bits - rel };
1161 let next = self.base.checked_add(stride)?;
1162 if next >= self.end {
1163 return None;
1164 }
1165 self.base = next;
1166 if !same_chunk {
1167 self.chunk = self.bitmap.get_chunk(BitMap::<N>::to_chunk_index(next));
1168 }
1169 self.word = self.load_word();
1170 }
1171 let bit = self.word.trailing_zeros() as u64;
1172 self.word &= self.word - 1;
1173 Some(self.base + bit)
1174 }
1175}
1176
1177#[cfg(feature = "arbitrary")]
1178impl<const N: usize> arbitrary::Arbitrary<'_> for BitMap<N> {
1179 fn arbitrary(u: &mut arbitrary::Unstructured<'_>) -> arbitrary::Result<Self> {
1180 let size = u.int_in_range(0..=1024)?;
1181 let mut bits = Self::with_capacity(size);
1182 for _ in 0..size {
1183 bits.push(u.arbitrary::<bool>()?);
1184 }
1185 Ok(bits)
1186 }
1187}
1188
1189#[cfg(test)]
1190mod tests {
1191 use super::*;
1192 use crate::test_rng;
1193 use bytes::BytesMut;
1194 use commonware_codec::{Decode, Encode};
1195 use commonware_formatting::hex;
1196 use rand::RngExt as _;
1197
1198 #[test]
1199 fn test_constructors() {
1200 let bv: BitMap<4> = BitMap::new();
1202 assert_eq!(bv.len(), 0);
1203 assert!(bv.is_empty());
1204
1205 let bv: BitMap<4> = Default::default();
1207 assert_eq!(bv.len(), 0);
1208 assert!(bv.is_empty());
1209
1210 let bv: BitMap<4> = BitMap::with_capacity(0);
1212 assert_eq!(bv.len(), 0);
1213 assert!(bv.is_empty());
1214
1215 let bv: BitMap<4> = BitMap::with_capacity(10);
1216 assert_eq!(bv.len(), 0);
1217 assert!(bv.is_empty());
1218 }
1219
1220 #[test]
1221 fn test_zeroes() {
1222 let bv: BitMap<1> = BitMap::zeroes(0);
1223 assert_eq!(bv.len(), 0);
1224 assert!(bv.is_empty());
1225 assert_eq!(bv.count_ones(), 0);
1226 assert_eq!(bv.count_zeros(), 0);
1227
1228 let bv: BitMap<1> = BitMap::zeroes(1);
1229 assert_eq!(bv.len(), 1);
1230 assert!(!bv.is_empty());
1231 assert_eq!(bv.len(), 1);
1232 assert!(!bv.get(0));
1233 assert_eq!(bv.count_ones(), 0);
1234 assert_eq!(bv.count_zeros(), 1);
1235
1236 let bv: BitMap<1> = BitMap::zeroes(10);
1237 assert_eq!(bv.len(), 10);
1238 assert!(!bv.is_empty());
1239 assert_eq!(bv.len(), 10);
1240 for i in 0..10 {
1241 assert!(!bv.get(i as u64));
1242 }
1243 assert_eq!(bv.count_ones(), 0);
1244 assert_eq!(bv.count_zeros(), 10);
1245 }
1246
1247 #[test]
1248 fn test_ones() {
1249 let bv: BitMap<1> = BitMap::ones(0);
1250 assert_eq!(bv.len(), 0);
1251 assert!(bv.is_empty());
1252 assert_eq!(bv.count_ones(), 0);
1253 assert_eq!(bv.count_zeros(), 0);
1254
1255 let bv: BitMap<1> = BitMap::ones(1);
1256 assert_eq!(bv.len(), 1);
1257 assert!(!bv.is_empty());
1258 assert_eq!(bv.len(), 1);
1259 assert!(bv.get(0));
1260 assert_eq!(bv.count_ones(), 1);
1261 assert_eq!(bv.count_zeros(), 0);
1262
1263 let bv: BitMap<1> = BitMap::ones(10);
1264 assert_eq!(bv.len(), 10);
1265 assert!(!bv.is_empty());
1266 assert_eq!(bv.len(), 10);
1267 for i in 0..10 {
1268 assert!(bv.get(i as u64));
1269 }
1270 assert_eq!(bv.count_ones(), 10);
1271 assert_eq!(bv.count_zeros(), 0);
1272 }
1273
1274 #[test]
1275 fn test_invariant_trailing_bits_are_zero() {
1276 fn check_trailing_bits_zero<const N: usize>(bitmap: &BitMap<N>) {
1278 let (last_chunk, next_bit) = bitmap.last_chunk();
1279
1280 for bit_idx in next_bit..((N * 8) as u64) {
1282 let byte_idx = (bit_idx / 8) as usize;
1283 let bit_in_byte = bit_idx % 8;
1284 let mask = 1u8 << bit_in_byte;
1285 assert_eq!(last_chunk[byte_idx] & mask, 0);
1286 }
1287 }
1288
1289 let bv: BitMap<4> = BitMap::ones(15);
1291 check_trailing_bits_zero(&bv);
1292
1293 let bv: BitMap<4> = BitMap::ones(33);
1294 check_trailing_bits_zero(&bv);
1295
1296 let mut bv: BitMap<4> = BitMap::new();
1298 for i in 0..37 {
1299 bv.push(i % 2 == 0);
1300 check_trailing_bits_zero(&bv);
1301 }
1302
1303 let mut bv: BitMap<4> = BitMap::ones(40);
1305 check_trailing_bits_zero(&bv);
1306 for _ in 0..15 {
1307 bv.pop();
1308 check_trailing_bits_zero(&bv);
1309 }
1310
1311 let mut bv: BitMap<4> = BitMap::ones(25);
1313 bv.flip_all();
1314 check_trailing_bits_zero(&bv);
1315
1316 let bv1: BitMap<4> = BitMap::ones(20);
1318 let bv2: BitMap<4> = BitMap::zeroes(20);
1319
1320 let mut bv_and = bv1.clone();
1321 bv_and.and(&bv2);
1322 check_trailing_bits_zero(&bv_and);
1323
1324 let mut bv_or = bv1.clone();
1325 bv_or.or(&bv2);
1326 check_trailing_bits_zero(&bv_or);
1327
1328 let mut bv_xor = bv1;
1329 bv_xor.xor(&bv2);
1330 check_trailing_bits_zero(&bv_xor);
1331
1332 let original: BitMap<4> = BitMap::ones(27);
1334 let encoded = original.encode();
1335 let decoded: BitMap<4> = BitMap::decode_cfg(encoded, &(..).into()).unwrap();
1336 check_trailing_bits_zero(&decoded);
1337
1338 let mut bv_clean: BitMap<4> = BitMap::ones(20);
1340 assert!(!bv_clean.clear_trailing_bits());
1342
1343 let mut bv_dirty: BitMap<4> = BitMap::ones(20);
1345 let last_chunk = bv_dirty.chunks.back_mut().unwrap();
1347 last_chunk[3] |= 0xF0; assert!(bv_dirty.clear_trailing_bits());
1350 assert!(!bv_dirty.clear_trailing_bits());
1352 check_trailing_bits_zero(&bv_dirty);
1353 }
1354
1355 #[test]
1356 fn test_get_set() {
1357 let mut bv: BitMap<4> = BitMap::new();
1358
1359 assert_eq!(bv.len(), 0);
1361 assert!(bv.is_empty());
1362
1363 bv.push(true);
1365 bv.push(false);
1366 bv.push(true);
1367 assert_eq!(bv.len(), 3);
1368 assert!(!bv.is_empty());
1369
1370 assert!(bv.get(0));
1372 assert!(!bv.get(1));
1373 assert!(bv.get(2));
1374
1375 bv.set(1, true);
1376 assert!(bv.get(1));
1377 bv.set(2, false);
1378 assert!(!bv.get(2));
1379
1380 bv.flip(0); assert!(!bv.get(0));
1383 bv.flip(0); assert!(bv.get(0));
1385 }
1386
1387 #[test]
1388 fn test_chunk_operations() {
1389 let mut bv: BitMap<4> = BitMap::new();
1390 let test_chunk = hex!("0xABCDEF12");
1391
1392 bv.push_chunk(&test_chunk);
1394 assert_eq!(bv.len(), 32); let chunk = bv.get_chunk(0);
1398 assert_eq!(chunk, &test_chunk);
1399
1400 let chunk = bv.get_chunk_containing(0);
1402 assert_eq!(chunk, &test_chunk);
1403
1404 let (last_chunk, next_bit) = bv.last_chunk();
1406 assert_eq!(next_bit, BitMap::<4>::CHUNK_SIZE_BITS); assert_eq!(last_chunk, &test_chunk); }
1409
1410 #[test]
1411 fn test_pop() {
1412 let mut bv: BitMap<3> = BitMap::new();
1413 bv.push(true);
1414 assert!(bv.pop());
1415 assert_eq!(bv.len(), 0);
1416
1417 bv.push(false);
1418 assert!(!bv.pop());
1419 assert_eq!(bv.len(), 0);
1420
1421 bv.push(true);
1422 bv.push(false);
1423 bv.push(true);
1424 assert!(bv.pop());
1425 assert_eq!(bv.len(), 2);
1426 assert!(!bv.pop());
1427 assert_eq!(bv.len(), 1);
1428 assert!(bv.pop());
1429 assert_eq!(bv.len(), 0);
1430
1431 for i in 0..100 {
1432 bv.push(i % 2 == 0);
1433 }
1434 assert_eq!(bv.len(), 100);
1435 for i in (0..100).rev() {
1436 assert_eq!(bv.pop(), i % 2 == 0);
1437 }
1438 assert_eq!(bv.len(), 0);
1439 assert!(bv.is_empty());
1440 }
1441
1442 #[test]
1443 fn test_truncate() {
1444 let mut bv: BitMap<4> = BitMap::new();
1445 let expected: Vec<bool> = (0..70).map(|i| i % 3 == 0).collect();
1446 for &bit in &expected {
1447 bv.push(bit);
1448 }
1449
1450 bv.truncate(65);
1451 assert_eq!(bv.len(), 65);
1452 for i in 0..65 {
1453 assert_eq!(bv.get(i), expected[i as usize]);
1454 }
1455
1456 bv.truncate(32);
1457 assert_eq!(bv.len(), 32);
1458 for i in 0..32 {
1459 assert_eq!(bv.get(i), expected[i as usize]);
1460 }
1461
1462 bv.truncate(0);
1463 assert_eq!(bv.len(), 0);
1464 assert!(bv.is_empty());
1465 }
1466
1467 #[test]
1468 #[should_panic(expected = "cannot truncate to a larger size")]
1469 fn test_truncate_larger_size_panics() {
1470 let mut bv: BitMap<4> = BitMap::new();
1471 bv.push(true);
1472 bv.truncate(2);
1473 }
1474
1475 #[test]
1476 fn test_pop_chunk() {
1477 let mut bv: BitMap<3> = BitMap::new();
1478 const CHUNK_SIZE: u64 = BitMap::<3>::CHUNK_SIZE_BITS;
1479
1480 let chunk1 = hex!("0xAABBCC");
1482 bv.push_chunk(&chunk1);
1483 assert_eq!(bv.len(), CHUNK_SIZE);
1484 let popped = bv.pop_chunk();
1485 assert_eq!(popped, chunk1);
1486 assert_eq!(bv.len(), 0);
1487 assert!(bv.is_empty());
1488
1489 let chunk2 = hex!("0x112233");
1491 let chunk3 = hex!("0x445566");
1492 let chunk4 = hex!("0x778899");
1493
1494 bv.push_chunk(&chunk2);
1495 bv.push_chunk(&chunk3);
1496 bv.push_chunk(&chunk4);
1497 assert_eq!(bv.len(), CHUNK_SIZE * 3);
1498
1499 assert_eq!(bv.pop_chunk(), chunk4);
1500 assert_eq!(bv.len(), CHUNK_SIZE * 2);
1501
1502 assert_eq!(bv.pop_chunk(), chunk3);
1503 assert_eq!(bv.len(), CHUNK_SIZE);
1504
1505 assert_eq!(bv.pop_chunk(), chunk2);
1506 assert_eq!(bv.len(), 0);
1507
1508 let first_chunk = hex!("0xAABBCC");
1510 let second_chunk = hex!("0x112233");
1511 bv.push_chunk(&first_chunk);
1512 bv.push_chunk(&second_chunk);
1513
1514 assert_eq!(bv.pop_chunk(), second_chunk);
1516 assert_eq!(bv.len(), CHUNK_SIZE);
1517
1518 for i in 0..CHUNK_SIZE {
1519 let byte_idx = (i / 8) as usize;
1520 let bit_idx = i % 8;
1521 let expected = (first_chunk[byte_idx] >> bit_idx) & 1 == 1;
1522 assert_eq!(bv.get(i), expected);
1523 }
1524
1525 assert_eq!(bv.pop_chunk(), first_chunk);
1526 assert_eq!(bv.len(), 0);
1527 }
1528
1529 #[test]
1530 #[should_panic(expected = "cannot pop chunk when not chunk aligned")]
1531 fn test_pop_chunk_not_aligned() {
1532 let mut bv: BitMap<3> = BitMap::new();
1533
1534 bv.push_chunk(&[0xFF; 3]);
1536 bv.push(true);
1537
1538 bv.pop_chunk();
1540 }
1541
1542 #[test]
1543 #[should_panic(expected = "cannot pop chunk: bitmap has fewer than CHUNK_SIZE_BITS bits")]
1544 fn test_pop_chunk_insufficient_bits() {
1545 let mut bv: BitMap<3> = BitMap::new();
1546
1547 bv.push(true);
1549 bv.push(false);
1550
1551 bv.pop_chunk();
1553 }
1554
1555 #[test]
1556 fn test_byte_operations() {
1557 let mut bv: BitMap<4> = BitMap::new();
1558
1559 bv.push_byte(0xFF);
1561 assert_eq!(bv.len(), 8);
1562
1563 for i in 0..8 {
1565 assert!(bv.get(i as u64));
1566 }
1567
1568 bv.push_byte(0x00);
1569 assert_eq!(bv.len(), 16);
1570
1571 for i in 8..16 {
1573 assert!(!bv.get(i as u64));
1574 }
1575 }
1576
1577 #[test]
1578 fn test_extend_from_bitmap_matches_push() {
1579 fn check<const N: usize, const M: usize>() {
1583 let mut rng = test_rng();
1584 let chunk_bits = BitMap::<N>::CHUNK_SIZE_BITS;
1585 let (short, long) = (chunk_bits - 1, 3 * chunk_bits + 11);
1586 let lens = [0, 1, 7, 8, 9, short, chunk_bits, long];
1587 for prefix in 0..=chunk_bits + 1 {
1588 for len in lens {
1589 let mut src: BitMap<M> = BitMap::new();
1590 for _ in 0..len {
1591 src.push(rng.random_bool(0.5));
1592 }
1593
1594 let half = src.chunks.len() / 2;
1597 let mut chunks: VecDeque<_> = src.chunks.range(half..).copied().collect();
1598 for chunk in src.chunks.range(..half).rev() {
1599 chunks.push_front(*chunk);
1600 }
1601 assert_eq!(chunks.as_slices().1.is_empty(), half == 0);
1602 let wrapped = BitMap { chunks, len };
1603
1604 let mut dst: BitMap<N> = BitMap::new();
1605 for _ in 0..prefix {
1606 dst.push(rng.random_bool(0.5));
1607 }
1608 let mut expected = dst.clone();
1609 for bit in src.iter() {
1610 expected.push(bit);
1611 }
1612 for source in [&src, &wrapped] {
1613 let mut actual = dst.clone();
1614 actual.extend_from_bitmap(source);
1615 assert_eq!(actual, expected, "N={N} M={M} prefix={prefix} len={len}");
1616 }
1617 }
1618 }
1619 }
1620 check::<1, 1>();
1621 check::<1, 8>();
1622 check::<3, 8>();
1623 check::<8, 8>();
1624 check::<8, 3>();
1625 check::<12, 5>();
1626 check::<32, 1>();
1627 check::<32, 8>();
1628 }
1629
1630 #[test]
1631 fn test_count_operations() {
1632 let mut bv: BitMap<4> = BitMap::new();
1633
1634 assert_eq!(bv.count_ones(), 0);
1636 assert_eq!(bv.count_zeros(), 0);
1637
1638 bv.push(true);
1640 bv.push(false);
1641 bv.push(true);
1642 bv.push(true);
1643 bv.push(false);
1644
1645 assert_eq!(bv.count_ones(), 3);
1646 assert_eq!(bv.count_zeros(), 2);
1647 assert_eq!(bv.len(), 5);
1648
1649 let mut bv2: BitMap<4> = BitMap::new();
1651 bv2.push_byte(0xFF); bv2.push_byte(0x00); bv2.push_byte(0xAA); assert_eq!(bv2.count_ones(), 12);
1656 assert_eq!(bv2.count_zeros(), 12);
1657 assert_eq!(bv2.len(), 24);
1658 }
1659
1660 #[test]
1661 fn test_set_all() {
1662 let mut bv: BitMap<1> = BitMap::new();
1663
1664 bv.push(true);
1666 bv.push(false);
1667 bv.push(true);
1668 bv.push(false);
1669 bv.push(true);
1670 bv.push(false);
1671 bv.push(true);
1672 bv.push(false);
1673 bv.push(true);
1674 bv.push(false);
1675
1676 assert_eq!(bv.len(), 10);
1677 assert_eq!(bv.count_ones(), 5);
1678 assert_eq!(bv.count_zeros(), 5);
1679
1680 bv.set_all(true);
1682 assert_eq!(bv.len(), 10);
1683 assert_eq!(bv.count_ones(), 10);
1684 assert_eq!(bv.count_zeros(), 0);
1685
1686 bv.set_all(false);
1688 assert_eq!(bv.len(), 10);
1689 assert_eq!(bv.count_ones(), 0);
1690 assert_eq!(bv.count_zeros(), 10);
1691 }
1692
1693 #[test]
1694 fn test_flip_all() {
1695 let mut bv: BitMap<4> = BitMap::new();
1696
1697 bv.push(true);
1698 bv.push(false);
1699 bv.push(true);
1700 bv.push(false);
1701 bv.push(true);
1702
1703 let original_ones = bv.count_ones();
1704 let original_zeros = bv.count_zeros();
1705 let original_len = bv.len();
1706
1707 bv.flip_all();
1708
1709 assert_eq!(bv.len(), original_len);
1711
1712 assert_eq!(bv.count_ones(), original_zeros);
1714 assert_eq!(bv.count_zeros(), original_ones);
1715
1716 assert!(!bv.get(0));
1718 assert!(bv.get(1));
1719 assert!(!bv.get(2));
1720 assert!(bv.get(3));
1721 assert!(!bv.get(4));
1722 }
1723
1724 #[test]
1725 fn test_bitwise_and() {
1726 let mut bv1: BitMap<4> = BitMap::new();
1727 let mut bv2: BitMap<4> = BitMap::new();
1728
1729 let pattern1 = [true, false, true, true, false];
1731 let pattern2 = [true, true, false, true, false];
1732 let expected = [true, false, false, true, false];
1733
1734 for &bit in &pattern1 {
1735 bv1.push(bit);
1736 }
1737 for &bit in &pattern2 {
1738 bv2.push(bit);
1739 }
1740
1741 bv1.and(&bv2);
1742
1743 assert_eq!(bv1.len(), 5);
1744 for (i, &expected_bit) in expected.iter().enumerate() {
1745 assert_eq!(bv1.get(i as u64), expected_bit);
1746 }
1747 }
1748
1749 #[test]
1750 fn test_bitwise_or() {
1751 let mut bv1: BitMap<4> = BitMap::new();
1752 let mut bv2: BitMap<4> = BitMap::new();
1753
1754 let pattern1 = [true, false, true, true, false];
1756 let pattern2 = [true, true, false, true, false];
1757 let expected = [true, true, true, true, false];
1758
1759 for &bit in &pattern1 {
1760 bv1.push(bit);
1761 }
1762 for &bit in &pattern2 {
1763 bv2.push(bit);
1764 }
1765
1766 bv1.or(&bv2);
1767
1768 assert_eq!(bv1.len(), 5);
1769 for (i, &expected_bit) in expected.iter().enumerate() {
1770 assert_eq!(bv1.get(i as u64), expected_bit);
1771 }
1772 }
1773
1774 #[test]
1775 fn test_bitwise_xor() {
1776 let mut bv1: BitMap<4> = BitMap::new();
1777 let mut bv2: BitMap<4> = BitMap::new();
1778
1779 let pattern1 = [true, false, true, true, false];
1781 let pattern2 = [true, true, false, true, false];
1782 let expected = [false, true, true, false, false];
1783
1784 for &bit in &pattern1 {
1785 bv1.push(bit);
1786 }
1787 for &bit in &pattern2 {
1788 bv2.push(bit);
1789 }
1790
1791 bv1.xor(&bv2);
1792
1793 assert_eq!(bv1.len(), 5);
1794 for (i, &expected_bit) in expected.iter().enumerate() {
1795 assert_eq!(bv1.get(i as u64), expected_bit);
1796 }
1797 }
1798
1799 #[test]
1800 fn test_multi_chunk_operations() {
1801 let mut bv1: BitMap<4> = BitMap::new();
1802 let mut bv2: BitMap<4> = BitMap::new();
1803
1804 let chunk1 = hex!("0xAABBCCDD"); let chunk2 = hex!("0x55667788"); bv1.push_chunk(&chunk1);
1809 bv1.push_chunk(&chunk1);
1810 bv2.push_chunk(&chunk2);
1811 bv2.push_chunk(&chunk2);
1812
1813 assert_eq!(bv1.len(), 64);
1814 assert_eq!(bv2.len(), 64);
1815
1816 let mut bv_and = bv1.clone();
1818 bv_and.and(&bv2);
1819
1820 let mut bv_or = bv1.clone();
1822 bv_or.or(&bv2);
1823
1824 let mut bv_xor = bv1.clone();
1826 bv_xor.xor(&bv2);
1827
1828 assert_eq!(bv_and.len(), 64);
1830 assert_eq!(bv_or.len(), 64);
1831 assert_eq!(bv_xor.len(), 64);
1832
1833 assert!(bv_and.count_ones() <= bv1.count_ones());
1835 assert!(bv_and.count_ones() <= bv2.count_ones());
1836
1837 assert!(bv_or.count_ones() >= bv1.count_ones());
1839 assert!(bv_or.count_ones() >= bv2.count_ones());
1840 }
1841
1842 #[test]
1843 fn test_partial_chunk_operations() {
1844 let mut bv1: BitMap<4> = BitMap::new();
1845 let mut bv2: BitMap<4> = BitMap::new();
1846
1847 for i in 0..35 {
1849 bv1.push(i % 2 == 0);
1851 bv2.push(i % 3 == 0);
1852 }
1853
1854 assert_eq!(bv1.len(), 35);
1855 assert_eq!(bv2.len(), 35);
1856
1857 let mut bv_and = bv1.clone();
1859 bv_and.and(&bv2);
1860
1861 let mut bv_or = bv1.clone();
1862 bv_or.or(&bv2);
1863
1864 let mut bv_xor = bv1.clone();
1865 bv_xor.xor(&bv2);
1866
1867 assert_eq!(bv_and.len(), 35);
1869 assert_eq!(bv_or.len(), 35);
1870 assert_eq!(bv_xor.len(), 35);
1871
1872 let mut bv_inv = bv1.clone();
1874 let original_ones = bv_inv.count_ones();
1875 let original_zeros = bv_inv.count_zeros();
1876 bv_inv.flip_all();
1877 assert_eq!(bv_inv.count_ones(), original_zeros);
1878 assert_eq!(bv_inv.count_zeros(), original_ones);
1879 }
1880
1881 #[test]
1882 #[should_panic(expected = "bit 1 out of bounds (len: 1)")]
1883 fn test_flip_out_of_bounds() {
1884 let mut bv: BitMap<4> = BitMap::new();
1885 bv.push(true);
1886 bv.flip(1); }
1888
1889 #[test]
1890 #[should_panic(expected = "BitMap lengths don't match: 2 vs 1")]
1891 fn test_and_length_mismatch() {
1892 let mut bv1: BitMap<4> = BitMap::new();
1893 let mut bv2: BitMap<4> = BitMap::new();
1894
1895 bv1.push(true);
1896 bv1.push(false);
1897 bv2.push(true); bv1.and(&bv2);
1900 }
1901
1902 #[test]
1903 #[should_panic(expected = "BitMap lengths don't match: 1 vs 2")]
1904 fn test_or_length_mismatch() {
1905 let mut bv1: BitMap<4> = BitMap::new();
1906 let mut bv2: BitMap<4> = BitMap::new();
1907
1908 bv1.push(true);
1909 bv2.push(true);
1910 bv2.push(false); bv1.or(&bv2);
1913 }
1914
1915 #[test]
1916 #[should_panic(expected = "BitMap lengths don't match: 3 vs 2")]
1917 fn test_xor_length_mismatch() {
1918 let mut bv1: BitMap<4> = BitMap::new();
1919 let mut bv2: BitMap<4> = BitMap::new();
1920
1921 bv1.push(true);
1922 bv1.push(false);
1923 bv1.push(true);
1924 bv2.push(true);
1925 bv2.push(false); bv1.xor(&bv2);
1928 }
1929
1930 #[test]
1931 fn test_equality() {
1932 assert_eq!(BitMap::<4>::new(), BitMap::<4>::new());
1934 assert_eq!(BitMap::<8>::new(), BitMap::<8>::new());
1935
1936 let pattern = [true, false, true, true, false, false, true, false, true];
1938 let bv4: BitMap<4> = pattern.as_ref().into();
1939 assert_eq!(bv4, BitMap::<4>::from(pattern.as_ref()));
1940 let bv8: BitMap<8> = pattern.as_ref().into();
1941 assert_eq!(bv8, BitMap::<8>::from(pattern.as_ref()));
1942
1943 let mut bv1: BitMap<4> = BitMap::new();
1945 let mut bv2: BitMap<4> = BitMap::new();
1946 for i in 0..33 {
1947 let bit = i % 3 == 0;
1948 bv1.push(bit);
1949 bv2.push(bit);
1950 }
1951 assert_eq!(bv1, bv2);
1952
1953 bv1.push(true);
1955 assert_ne!(bv1, bv2);
1956 bv1.pop(); assert_eq!(bv1, bv2);
1958
1959 bv1.flip(15);
1961 assert_ne!(bv1, bv2);
1962 bv1.flip(15); assert_eq!(bv1, bv2);
1964
1965 let mut bv_ops1 = BitMap::<16>::ones(25);
1967 let mut bv_ops2 = BitMap::<16>::ones(25);
1968 bv_ops1.flip_all();
1969 bv_ops2.flip_all();
1970 assert_eq!(bv_ops1, bv_ops2);
1971
1972 let mask_bits: Vec<bool> = (0..33).map(|i| i % 3 == 0).collect();
1973 let mask = BitMap::<4>::from(mask_bits);
1974 bv1.and(&mask);
1975 bv2.and(&mask);
1976 assert_eq!(bv1, bv2);
1977 }
1978
1979 #[test]
1980 fn test_different_chunk_sizes() {
1981 let mut bv8: BitMap<8> = BitMap::new();
1983 let mut bv16: BitMap<16> = BitMap::new();
1984 let mut bv32: BitMap<32> = BitMap::new();
1985
1986 let chunk8 = [0xFF; 8];
1988 let chunk16 = [0xAA; 16];
1989 let chunk32 = [0x55; 32];
1990
1991 bv8.push_chunk(&chunk8);
1992 bv16.push_chunk(&chunk16);
1993 bv32.push_chunk(&chunk32);
1994
1995 bv8.push(true);
1997 bv8.push(false);
1998 assert_eq!(bv8.len(), 64 + 2);
1999 assert_eq!(bv8.count_ones(), 64 + 1); assert_eq!(bv8.count_zeros(), 1);
2001
2002 bv16.push(true);
2003 bv16.push(false);
2004 assert_eq!(bv16.len(), 128 + 2);
2005 assert_eq!(bv16.count_ones(), 64 + 1); assert_eq!(bv16.count_zeros(), 64 + 1);
2007
2008 bv32.push(true);
2009 bv32.push(false);
2010 assert_eq!(bv32.len(), 256 + 2);
2011 assert_eq!(bv32.count_ones(), 128 + 1); assert_eq!(bv32.count_zeros(), 128 + 1);
2013 }
2014
2015 #[test]
2016 fn test_iterator() {
2017 let bv: BitMap<4> = BitMap::new();
2019 let mut iter = bv.iter();
2020 assert_eq!(iter.next(), None);
2021 assert_eq!(iter.size_hint(), (0, Some(0)));
2022
2023 let pattern = [true, false, true, false, true];
2025 let bv: BitMap<4> = pattern.as_ref().into();
2026
2027 let collected: Vec<bool> = bv.iter().collect();
2029 assert_eq!(collected, pattern);
2030
2031 let mut iter = bv.iter();
2033 assert_eq!(iter.size_hint(), (5, Some(5)));
2034
2035 assert_eq!(iter.next(), Some(true));
2037 assert_eq!(iter.size_hint(), (4, Some(4)));
2038
2039 let iter = bv.iter();
2041 assert_eq!(iter.len(), 5);
2042
2043 let mut large_bv: BitMap<8> = BitMap::new();
2045 for i in 0..100 {
2046 large_bv.push(i % 3 == 0);
2047 }
2048
2049 let collected: Vec<bool> = large_bv.iter().collect();
2050 assert_eq!(collected.len(), 100);
2051 for (i, &bit) in collected.iter().enumerate() {
2052 assert_eq!(bit, i % 3 == 0);
2053 }
2054 }
2055
2056 #[test]
2057 fn test_iterator_edge_cases() {
2058 let mut bv: BitMap<4> = BitMap::new();
2060 bv.push(true);
2061
2062 let collected: Vec<bool> = bv.iter().collect();
2063 assert_eq!(collected, vec![true]);
2064
2065 let mut bv: BitMap<4> = BitMap::new();
2067 for i in 0..32 {
2069 bv.push(i % 2 == 0);
2070 }
2071 bv.push(true);
2073 bv.push(false);
2074 bv.push(true);
2075
2076 let collected: Vec<bool> = bv.iter().collect();
2077 assert_eq!(collected.len(), 35);
2078
2079 for (i, &bit) in collected.iter().enumerate().take(32) {
2081 assert_eq!(bit, i % 2 == 0);
2082 }
2083 assert!(collected[32]);
2084 assert!(!collected[33]);
2085 assert!(collected[34]);
2086 }
2087
2088 fn check_ones_iter_range<const N: usize>(
2092 len: u64,
2093 bounds: impl iter::Iterator<Item = u64> + Clone,
2094 ) {
2095 let mut bitmap = BitMap::<N>::new();
2096 for bit in 0..len {
2097 bitmap.push(bit % 3 == 0);
2098 }
2099 for start in bounds.clone() {
2100 for end in bounds.clone() {
2101 let expected: Vec<_> = (start..end.min(len))
2102 .filter(|&bit| bitmap.get(bit))
2103 .collect();
2104 let mut ones = bitmap.ones_iter_range(start..end);
2105 assert_eq!(
2106 ones.by_ref().collect::<Vec<_>>(),
2107 expected,
2108 "N={N}, {start}..{end}"
2109 );
2110 assert_eq!(ones.next(), None);
2111 }
2112 }
2113 }
2114
2115 #[test]
2116 fn test_ones_iter_range() {
2117 check_ones_iter_range::<9>(150, 0..=151);
2119
2120 check_ones_iter_range::<64>(
2122 1100,
2123 (0..=1101).filter(|bit| matches!(bit % 64, 0 | 1 | 32 | 63)),
2124 );
2125 }
2126
2127 #[test]
2128 fn test_ones_iter_empty() {
2129 let bv: BitMap<4> = BitMap::new();
2130 let ones: Vec<u64> = bv.ones_iter().collect();
2131 assert!(ones.is_empty());
2132 }
2133
2134 #[test]
2135 fn test_ones_iter_all_zeros() {
2136 let bv = BitMap::<4>::zeroes(100);
2137 let ones: Vec<u64> = bv.ones_iter().collect();
2138 assert!(ones.is_empty());
2139 }
2140
2141 #[test]
2142 fn test_ones_iter_all_ones() {
2143 let bv = BitMap::<4>::ones(100);
2144 let ones: Vec<u64> = bv.ones_iter().collect();
2145 let expected: Vec<u64> = (0..100).collect();
2146 assert_eq!(ones, expected);
2147 }
2148
2149 #[test]
2150 fn test_ones_iter_sparse() {
2151 let mut bv = BitMap::<4>::zeroes(64);
2152 bv.set(0, true);
2153 bv.set(31, true);
2154 bv.set(32, true);
2155 bv.set(63, true);
2156
2157 let ones: Vec<u64> = bv.ones_iter().collect();
2158 assert_eq!(ones, vec![0, 31, 32, 63]);
2159 }
2160
2161 #[test]
2162 fn test_ones_iter_single_bit() {
2163 let mut bv: BitMap<4> = BitMap::new();
2164 bv.push(true);
2165 assert_eq!(bv.ones_iter().collect::<Vec<_>>(), vec![0]);
2166
2167 let mut bv: BitMap<4> = BitMap::new();
2168 bv.push(false);
2169 assert!(bv.ones_iter().collect::<Vec<_>>().is_empty());
2170 }
2171
2172 #[test]
2173 fn test_ones_iter_multi_chunk() {
2174 let mut bv = BitMap::<4>::zeroes(96);
2176 bv.set(7, true); bv.set(40, true); bv.set(95, true); let ones: Vec<u64> = bv.ones_iter().collect();
2182 assert_eq!(ones, vec![7, 40, 95]);
2183 }
2184
2185 #[test]
2186 fn test_ones_iter_partial_chunk() {
2187 let mut bv = BitMap::<4>::zeroes(35);
2189 bv.set(31, true); bv.set(32, true); bv.set(34, true); let ones: Vec<u64> = bv.ones_iter().collect();
2194 assert_eq!(ones, vec![31, 32, 34]);
2195 }
2196
2197 #[test]
2198 fn test_ones_iter_from_midway() {
2199 let mut bv = BitMap::<4>::zeroes(64);
2200 bv.set(5, true);
2201 bv.set(20, true);
2202 bv.set(40, true);
2203 bv.set(60, true);
2204
2205 let ones: Vec<u64> = Readable::ones_iter_from(&bv, 20).collect();
2207 assert_eq!(ones, vec![20, 40, 60]);
2208
2209 let ones: Vec<u64> = Readable::ones_iter_from(&bv, 21).collect();
2211 assert_eq!(ones, vec![40, 60]);
2212
2213 let ones: Vec<u64> = Readable::ones_iter_from(&bv, 61).collect();
2215 assert!(ones.is_empty());
2216 }
2217
2218 #[test]
2219 fn test_ones_iter_matches_count_ones() {
2220 let mut bv: BitMap<8> = BitMap::new();
2221 for i in 0..200 {
2222 bv.push(i % 7 == 0);
2223 }
2224 assert_eq!(bv.ones_iter().count() as u64, bv.count_ones());
2225 }
2226
2227 #[test]
2228 fn test_ones_iter_different_chunk_sizes() {
2229 let pattern: Vec<bool> = (0..100).map(|i| i % 5 == 0).collect();
2230 let expected: Vec<u64> = (0..100).filter(|i| i % 5 == 0).collect();
2231
2232 let bv4: BitMap<4> = pattern.as_slice().into();
2233 let bv8: BitMap<8> = pattern.as_slice().into();
2234 let bv16: BitMap<16> = pattern.as_slice().into();
2235
2236 assert_eq!(bv4.ones_iter().collect::<Vec<_>>(), expected);
2237 assert_eq!(bv8.ones_iter().collect::<Vec<_>>(), expected);
2238 assert_eq!(bv16.ones_iter().collect::<Vec<_>>(), expected);
2239 }
2240
2241 #[test]
2242 fn test_ones_iter_multi_word_chunk() {
2243 let expected = vec![0, 63, 64, 127, 128, 255, 256, 511, 512, 599];
2246 let mut bv = BitMap::<32>::zeroes(600);
2247 for &bit in &expected {
2248 bv.set(bit, true);
2249 }
2250 assert_eq!(bv.ones_iter().collect::<Vec<_>>(), expected);
2251 }
2252
2253 #[test]
2254 fn test_ones_iter_from_mid_word() {
2255 let bv = BitMap::<32>::ones(300);
2258 for pos in [0, 1, 63, 64, 65, 191, 192, 255, 256, 299] {
2259 let ones: Vec<u64> = Readable::ones_iter_from(&bv, pos).collect();
2260 let expected: Vec<u64> = (pos..300).collect();
2261 assert_eq!(ones, expected);
2262 }
2263 }
2264
2265 #[test]
2266 fn test_ones_iter_word_aligned_len() {
2267 let bv = BitMap::<8>::ones(64);
2269 assert_eq!(
2270 bv.ones_iter().collect::<Vec<_>>(),
2271 (0..64).collect::<Vec<_>>()
2272 );
2273 let bv = BitMap::<32>::ones(256);
2274 assert_eq!(
2275 bv.ones_iter().collect::<Vec<_>>(),
2276 (0..256).collect::<Vec<_>>()
2277 );
2278 }
2279
2280 #[test]
2281 fn test_ones_iter_matches_get_bit() {
2282 fn check<const N: usize>() {
2287 let mut rng = test_rng();
2288 let mut bv: BitMap<N> = BitMap::new();
2289 let len = 5 * BitMap::<N>::CHUNK_SIZE_BITS + 7;
2290 for _ in 0..len {
2291 bv.push(rng.random_bool(0.375));
2292 }
2293 let expected: Vec<u64> = (0..len).filter(|&i| bv.get_bit(i)).collect();
2294 assert_eq!(bv.ones_iter().collect::<Vec<_>>(), expected);
2295 for pos in 0..=len {
2296 let tail: Vec<u64> = expected.iter().copied().filter(|&b| b >= pos).collect();
2297 assert_eq!(Readable::ones_iter_from(&bv, pos).collect::<Vec<_>>(), tail);
2298 }
2299 }
2300 check::<1>();
2301 check::<3>();
2302 check::<4>();
2303 check::<8>();
2304 check::<12>();
2305 check::<16>();
2306 check::<23>();
2307 check::<32>();
2308 }
2309
2310 #[test]
2311 fn test_codec_roundtrip() {
2312 let original: BitMap<4> = BitMap::new();
2314 let encoded = original.encode();
2315 let decoded = BitMap::decode_cfg(encoded, &(..).into()).unwrap();
2316 assert_eq!(original, decoded);
2317
2318 let pattern = [true, false, true, false, true];
2320 let original: BitMap<4> = pattern.as_ref().into();
2321 let encoded = original.encode();
2322 let decoded = BitMap::decode_cfg(encoded, &(..).into()).unwrap();
2323 assert_eq!(original, decoded);
2324
2325 for (i, &expected) in pattern.iter().enumerate() {
2327 assert_eq!(decoded.get(i as u64), expected);
2328 }
2329
2330 let mut large_original: BitMap<8> = BitMap::new();
2332 for i in 0..100 {
2333 large_original.push(i % 7 == 0);
2334 }
2335
2336 let encoded = large_original.encode();
2337 let decoded = BitMap::decode_cfg(encoded, &(..).into()).unwrap();
2338 assert_eq!(large_original, decoded);
2339
2340 assert_eq!(decoded.len(), 100);
2342 for i in 0..100 {
2343 assert_eq!(decoded.get(i as u64), i % 7 == 0);
2344 }
2345 }
2346
2347 #[test]
2348 fn test_codec_different_chunk_sizes() {
2349 let pattern = [true, false, true, true, false, false, true];
2350
2351 let bv4: BitMap<4> = pattern.as_ref().into();
2353 let bv8: BitMap<8> = pattern.as_ref().into();
2354 let bv16: BitMap<16> = pattern.as_ref().into();
2355
2356 let encoded4 = bv4.encode();
2358 let decoded4 = BitMap::decode_cfg(encoded4, &(..).into()).unwrap();
2359 assert_eq!(bv4, decoded4);
2360
2361 let encoded8 = bv8.encode();
2362 let decoded8 = BitMap::decode_cfg(encoded8, &(..).into()).unwrap();
2363 assert_eq!(bv8, decoded8);
2364
2365 let encoded16 = bv16.encode();
2366 let decoded16 = BitMap::decode_cfg(encoded16, &(..).into()).unwrap();
2367 assert_eq!(bv16, decoded16);
2368
2369 for (i, &expected) in pattern.iter().enumerate() {
2371 let i = i as u64;
2372 assert_eq!(decoded4.get(i), expected);
2373 assert_eq!(decoded8.get(i), expected);
2374 assert_eq!(decoded16.get(i), expected);
2375 }
2376 }
2377
2378 #[test]
2379 fn test_codec_edge_cases() {
2380 let mut bv: BitMap<4> = BitMap::new();
2382 for i in 0..32 {
2383 bv.push(i % 2 == 0);
2384 }
2385
2386 let encoded = bv.encode();
2387 let decoded = BitMap::decode_cfg(encoded, &(..).into()).unwrap();
2388 assert_eq!(bv, decoded);
2389 assert_eq!(decoded.len(), 32);
2390
2391 let mut bv2: BitMap<4> = BitMap::new();
2393 for i in 0..35 {
2394 bv2.push(i % 3 == 0);
2396 }
2397
2398 let encoded2 = bv2.encode();
2399 let decoded2 = BitMap::decode_cfg(encoded2, &(..).into()).unwrap();
2400 assert_eq!(bv2, decoded2);
2401 assert_eq!(decoded2.len(), 35);
2402 }
2403
2404 #[test]
2405 fn test_encode_size() {
2406 let bv: BitMap<4> = BitMap::new();
2408 let encoded = bv.encode();
2409 assert_eq!(bv.encode_size(), encoded.len());
2410
2411 let pattern = [true, false, true, false, true];
2413 let bv: BitMap<4> = pattern.as_ref().into();
2414 let encoded = bv.encode();
2415 assert_eq!(bv.encode_size(), encoded.len());
2416
2417 let mut large_bv: BitMap<8> = BitMap::new();
2419 for i in 0..100 {
2420 large_bv.push(i % 2 == 0);
2421 }
2422 let encoded = large_bv.encode();
2423 assert_eq!(large_bv.encode_size(), encoded.len());
2424 }
2425
2426 #[test]
2427 fn test_max_encode_size() {
2428 fn check<const N: usize>() {
2429 for bits in [0, 1, 7, 8, 9, 64, 65] {
2431 assert_eq!(
2432 BitMap::<N>::max_encode_size(bits),
2433 BitMap::<N>::zeroes(bits).encode_size(),
2434 "N={N} bits={bits}"
2435 );
2436 }
2437 }
2438 check::<1>();
2439 check::<8>();
2440 }
2441
2442 #[test]
2443 fn test_codec_empty_chunk_optimization() {
2444 let bv_empty: BitMap<4> = BitMap::new();
2448 let encoded_empty = bv_empty.encode();
2449 let decoded_empty: BitMap<4> =
2450 BitMap::decode_cfg(encoded_empty.clone(), &(..).into()).unwrap();
2451 assert_eq!(bv_empty, decoded_empty);
2452 assert_eq!(bv_empty.len(), decoded_empty.len());
2453 assert_eq!(encoded_empty.len(), bv_empty.len().encode_size());
2455
2456 let mut bv_exact: BitMap<4> = BitMap::new();
2458 for _ in 0..32 {
2459 bv_exact.push(true);
2460 }
2461 let encoded_exact = bv_exact.encode();
2462 let decoded_exact: BitMap<4> =
2463 BitMap::decode_cfg(encoded_exact.clone(), &(..).into()).unwrap();
2464 assert_eq!(bv_exact, decoded_exact);
2465
2466 let mut bv_partial: BitMap<4> = BitMap::new();
2468 for _ in 0..35 {
2469 bv_partial.push(true);
2470 }
2471 let encoded_partial = bv_partial.encode();
2472 let decoded_partial: BitMap<4> =
2473 BitMap::decode_cfg(encoded_partial.clone(), &(..).into()).unwrap();
2474 assert_eq!(bv_partial, decoded_partial);
2475 assert_eq!(bv_partial.len(), decoded_partial.len());
2476
2477 assert!(encoded_exact.len() < encoded_partial.len());
2479 assert_eq!(encoded_exact.len(), bv_exact.len().encode_size() + 4); assert_eq!(encoded_partial.len(), bv_partial.len().encode_size() + 8); }
2482
2483 #[test]
2484 fn test_codec_error_cases() {
2485 let mut buf = BytesMut::new();
2487 100u64.write(&mut buf); for _ in 0..4 {
2491 [0u8; 4].write(&mut buf);
2492 }
2493
2494 let result = BitMap::<4>::decode_cfg(&mut buf, &(..=99).into());
2496 assert!(matches!(result, Err(CodecError::InvalidLength(100))));
2497
2498 let mut buf = BytesMut::new();
2500 100u64.write(&mut buf); [0u8; 4].write(&mut buf);
2503 [0u8; 4].write(&mut buf);
2504 [0u8; 4].write(&mut buf);
2505
2506 let result = BitMap::<4>::decode_cfg(&mut buf, &(..).into());
2507 assert!(matches!(result, Err(CodecError::EndOfBuffer)));
2508
2509 let original: BitMap<4> = BitMap::ones(20);
2513 let mut buf = BytesMut::new();
2514 original.write(&mut buf);
2515
2516 let corrupted_data = buf.freeze();
2518 let mut corrupted_bytes = corrupted_data.to_vec();
2519
2520 let last_byte_idx = corrupted_bytes.len() - 1;
2524 corrupted_bytes[last_byte_idx] |= 0xF0;
2525
2526 let result = BitMap::<4>::read_cfg(&mut bytes::Bytes::from(corrupted_bytes), &(..).into());
2528 assert!(matches!(
2529 result,
2530 Err(CodecError::Invalid(
2531 "BitMap",
2532 "Invalid trailing bits in encoded data"
2533 ))
2534 ));
2535 }
2536
2537 #[test]
2538 fn test_codec_large_length_without_payload() {
2539 let result = BitMap::<4>::decode_cfg(u64::MAX.encode(), &(..).into());
2540 assert!(matches!(result, Err(CodecError::EndOfBuffer)));
2541 }
2542
2543 #[test]
2544 fn test_codec_truncated_chunk() {
2545 let mut buf = BytesMut::new();
2546 33u64.write(&mut buf);
2547 buf.extend_from_slice(&[0; 7]);
2548 let mut buf = buf.freeze();
2549
2550 let result = BitMap::<4>::read_cfg(&mut buf, &(..).into());
2551 assert!(matches!(result, Err(CodecError::EndOfBuffer)));
2552 assert_eq!(buf.len(), 7);
2554 }
2555
2556 #[test]
2557 fn test_codec_invalid_length_without_payload() {
2558 let result = BitMap::<4>::decode_cfg(100u64.encode(), &(..=99).into());
2559 assert!(matches!(result, Err(CodecError::InvalidLength(100))));
2560 }
2561
2562 #[test]
2565 fn test_codec_huge_length_rejected_before_allocation() {
2566 let len = (u64::from(u32::MAX) + 1) * BitMap::<4>::CHUNK_SIZE_BITS;
2567 let result = BitMap::<4>::decode_cfg(len.encode(), &(..).into());
2568 assert!(matches!(result, Err(CodecError::EndOfBuffer)));
2569 }
2570
2571 #[test]
2572 fn test_codec_range_config() {
2573 let mut original: BitMap<4> = BitMap::new();
2577 for i in 0..100 {
2578 original.push(i % 3 == 0);
2579 }
2580
2581 let mut buf = BytesMut::new();
2583 original.write(&mut buf);
2584
2585 let result = BitMap::<4>::decode_cfg(buf.clone(), &(..=50).into());
2587 assert!(matches!(result, Err(CodecError::InvalidLength(100))));
2588
2589 let decoded = BitMap::<4>::decode_cfg(buf.clone(), &(..=100).into()).unwrap();
2591 assert_eq!(decoded.len(), 100);
2592 assert_eq!(decoded, original);
2593
2594 let decoded = BitMap::<4>::decode_cfg(buf.clone(), &(..=101).into()).unwrap();
2596 assert_eq!(decoded.len(), 100);
2597 assert_eq!(decoded, original);
2598
2599 let decoded = BitMap::<4>::decode_cfg(buf.clone(), &RangeCfg::exact(100)).unwrap();
2601 assert_eq!(decoded, original);
2602 let result = BitMap::<4>::decode_cfg(buf.clone(), &RangeCfg::exact(99));
2603 assert!(matches!(result, Err(CodecError::InvalidLength(100))));
2604
2605 let result = BitMap::<4>::decode_cfg(buf, &(101..).into());
2607 assert!(matches!(result, Err(CodecError::InvalidLength(100))));
2608
2609 let empty = BitMap::<4>::new();
2611 let mut buf = BytesMut::new();
2612 empty.write(&mut buf);
2613
2614 let decoded = BitMap::<4>::decode_cfg(buf.clone(), &(..=0).into()).unwrap();
2616 assert_eq!(decoded.len(), 0);
2617 assert!(decoded.is_empty());
2618
2619 let decoded = BitMap::<4>::decode_cfg(buf, &(..=1).into()).unwrap();
2621 assert_eq!(decoded.len(), 0);
2622 assert!(decoded.is_empty());
2623 }
2624
2625 #[test]
2626 fn test_from() {
2627 let vec_bool = vec![true, false, true, false, true];
2631 let bv: BitMap<4> = vec_bool.into();
2632 assert_eq!(bv.len(), 5);
2633 assert_eq!(bv.count_ones(), 3);
2634 assert_eq!(bv.count_zeros(), 2);
2635 for (i, &expected) in [true, false, true, false, true].iter().enumerate() {
2636 assert_eq!(bv.get(i as u64), expected);
2637 }
2638
2639 let array = [false, true, true, false];
2641 let bv: BitMap<4> = (&array).into();
2642 assert_eq!(bv.len(), 4);
2643 assert_eq!(bv.count_ones(), 2);
2644 assert_eq!(bv.count_zeros(), 2);
2645 for (i, &expected) in array.iter().enumerate() {
2646 assert_eq!(bv.get(i as u64), expected);
2647 }
2648
2649 let empty: Vec<bool> = vec![];
2651 let bv: BitMap<4> = empty.into();
2652 assert_eq!(bv.len(), 0);
2653 assert!(bv.is_empty());
2654
2655 let large: Vec<bool> = (0..100).map(|i| i % 3 == 0).collect();
2657 let bv: BitMap<8> = large.clone().into();
2658 assert_eq!(bv.len(), 100);
2659 for (i, &expected) in large.iter().enumerate() {
2660 assert_eq!(bv.get(i as u64), expected);
2661 }
2662 }
2663
2664 #[test]
2665 fn test_debug_formatting() {
2666 let bv: BitMap<4> = BitMap::new();
2670 let debug_str = format!("{bv:?}");
2671 assert_eq!(debug_str, "BitMap[]");
2672
2673 let bv: BitMap<4> = [true, false, true, false, true].as_ref().into();
2675 let debug_str = format!("{bv:?}");
2676 assert_eq!(debug_str, "BitMap[10101]");
2677
2678 let pattern: Vec<bool> = (0..64).map(|i| i % 2 == 0).collect();
2680 let bv: BitMap<8> = pattern.into();
2681 let debug_str = format!("{bv:?}");
2682 let expected_pattern = "1010".repeat(16); assert_eq!(debug_str, format!("BitMap[{expected_pattern}]"));
2684
2685 let large_pattern: Vec<bool> = (0..100).map(|i| i % 2 == 0).collect();
2687 let bv: BitMap<16> = large_pattern.into();
2688 let debug_str = format!("{bv:?}");
2689
2690 let first_32 = "10".repeat(16); let last_32 = "10".repeat(16); let expected = format!("BitMap[{first_32}...{last_32}]");
2694 assert_eq!(debug_str, expected);
2695
2696 let bv: BitMap<4> = [true].as_ref().into();
2698 assert_eq!(format!("{bv:?}"), "BitMap[1]");
2699
2700 let bv: BitMap<4> = [false].as_ref().into();
2701 assert_eq!(format!("{bv:?}"), "BitMap[0]");
2702
2703 let pattern: Vec<bool> = (0..65).map(|i| i == 0 || i == 64).collect(); let bv: BitMap<16> = pattern.into();
2706 let debug_str = format!("{bv:?}");
2707
2708 let first_32 = "1".to_string() + &"0".repeat(31);
2710 let last_32 = "0".repeat(31) + "1";
2711 let expected = format!("BitMap[{first_32}...{last_32}]");
2712 assert_eq!(debug_str, expected);
2713 }
2714
2715 #[test]
2716 fn test_from_different_chunk_sizes() {
2717 let pattern = [true, false, true, true, false, false, true];
2719
2720 let bv4: BitMap<4> = pattern.as_ref().into();
2721 let bv8: BitMap<8> = pattern.as_ref().into();
2722 let bv16: BitMap<16> = pattern.as_ref().into();
2723
2724 for bv in [&bv4] {
2727 assert_eq!(bv.len(), 7);
2728 assert_eq!(bv.count_ones(), 4);
2729 assert_eq!(bv.count_zeros(), 3);
2730 for (i, &expected) in pattern.iter().enumerate() {
2731 assert_eq!(bv.get(i as u64), expected);
2732 }
2733 }
2734
2735 assert_eq!(bv8.len(), 7);
2736 assert_eq!(bv8.count_ones(), 4);
2737 assert_eq!(bv8.count_zeros(), 3);
2738 for (i, &expected) in pattern.iter().enumerate() {
2739 assert_eq!(bv8.get(i as u64), expected);
2740 }
2741
2742 assert_eq!(bv16.len(), 7);
2743 assert_eq!(bv16.count_ones(), 4);
2744 assert_eq!(bv16.count_zeros(), 3);
2745 for (i, &expected) in pattern.iter().enumerate() {
2746 assert_eq!(bv16.get(i as u64), expected);
2747 }
2748 }
2749
2750 #[test]
2751 fn test_prune_chunks() {
2752 let mut bv: BitMap<4> = BitMap::new();
2753 bv.push_chunk(&[1, 2, 3, 4]);
2754 bv.push_chunk(&[5, 6, 7, 8]);
2755 bv.push_chunk(&[9, 10, 11, 12]);
2756
2757 assert_eq!(bv.len(), 96);
2758 assert_eq!(bv.get_chunk(0), &[1, 2, 3, 4]);
2759
2760 bv.prune_chunks(1);
2762 assert_eq!(bv.len(), 64);
2763 assert_eq!(bv.get_chunk(0), &[5, 6, 7, 8]);
2764 assert_eq!(bv.get_chunk(1), &[9, 10, 11, 12]);
2765
2766 bv.prune_chunks(1);
2768 assert_eq!(bv.len(), 32);
2769 assert_eq!(bv.get_chunk(0), &[9, 10, 11, 12]);
2770 }
2771
2772 #[test]
2773 #[should_panic(expected = "cannot prune")]
2774 fn test_prune_too_many_chunks() {
2775 let mut bv: BitMap<4> = BitMap::new();
2776 bv.push_chunk(&[1, 2, 3, 4]);
2777 bv.push_chunk(&[5, 6, 7, 8]);
2778 bv.push(true);
2779
2780 bv.prune_chunks(4);
2782 }
2783
2784 #[test]
2785 fn test_prune_with_partial_last_chunk() {
2786 let mut bv: BitMap<4> = BitMap::new();
2787 bv.push_chunk(&[1, 2, 3, 4]);
2788 bv.push_chunk(&[5, 6, 7, 8]);
2789 bv.push(true);
2790 bv.push(false);
2791
2792 assert_eq!(bv.len(), 66);
2793
2794 bv.prune_chunks(1);
2796 assert_eq!(bv.len(), 34);
2797 assert_eq!(bv.get_chunk(0), &[5, 6, 7, 8]);
2798
2799 assert!(bv.get(32));
2801 assert!(!bv.get(33));
2802 }
2803
2804 #[test]
2805 fn test_prune_all_chunks_resets_next_bit() {
2806 let mut bv: BitMap<4> = BitMap::new();
2807 bv.push_chunk(&[1, 2, 3, 4]);
2808 bv.push_chunk(&[5, 6, 7, 8]);
2809 bv.push(true);
2810 bv.push(false);
2811 bv.push(true);
2812
2813 assert_eq!(bv.len(), 67);
2815
2816 bv.prune_chunks(3);
2818
2819 assert_eq!(bv.len(), 0);
2821 assert!(bv.is_empty());
2822
2823 bv.push(true);
2825 assert_eq!(bv.len(), 1);
2826 assert!(bv.get(0));
2827 }
2828
2829 #[test]
2830 fn test_is_chunk_aligned() {
2831 let bv: BitMap<4> = BitMap::new();
2833 assert!(bv.is_chunk_aligned());
2834
2835 let mut bv4: BitMap<4> = BitMap::new();
2837 assert!(bv4.is_chunk_aligned());
2838
2839 for i in 1..=32 {
2841 bv4.push(i % 2 == 0);
2842 if i == 32 {
2843 assert!(bv4.is_chunk_aligned()); } else {
2845 assert!(!bv4.is_chunk_aligned()); }
2847 }
2848
2849 for i in 33..=64 {
2851 bv4.push(i % 2 == 0);
2852 if i == 64 {
2853 assert!(bv4.is_chunk_aligned()); } else {
2855 assert!(!bv4.is_chunk_aligned()); }
2857 }
2858
2859 let mut bv: BitMap<8> = BitMap::new();
2861 assert!(bv.is_chunk_aligned());
2862 bv.push_chunk(&[0xFF; 8]);
2863 assert!(bv.is_chunk_aligned()); bv.push_chunk(&[0xAA; 8]);
2865 assert!(bv.is_chunk_aligned()); bv.push(true);
2867 assert!(!bv.is_chunk_aligned()); let mut bv: BitMap<4> = BitMap::new();
2871 for _ in 0..4 {
2872 bv.push_byte(0xFF);
2873 }
2874 assert!(bv.is_chunk_aligned()); bv.pop();
2878 assert!(!bv.is_chunk_aligned()); let bv_zeroes: BitMap<4> = BitMap::zeroes(64);
2882 assert!(bv_zeroes.is_chunk_aligned());
2883
2884 let bv_ones: BitMap<4> = BitMap::ones(96);
2885 assert!(bv_ones.is_chunk_aligned());
2886
2887 let bv_partial: BitMap<4> = BitMap::zeroes(65);
2888 assert!(!bv_partial.is_chunk_aligned());
2889 }
2890
2891 #[test]
2892 fn test_unprune_restores_length() {
2893 let mut prunable: Prunable<4> = Prunable::new_with_pruned_chunks(1).unwrap();
2894 assert_eq!(prunable.len(), Prunable::<4>::CHUNK_SIZE_BITS);
2895 assert_eq!(prunable.pruned_chunks(), 1);
2896 let chunk = [0xDE, 0xAD, 0xBE, 0xEF];
2897
2898 prunable.unprune_chunks(&[chunk]);
2899
2900 assert_eq!(prunable.pruned_chunks(), 0);
2901 assert_eq!(prunable.len(), Prunable::<4>::CHUNK_SIZE_BITS);
2902 assert_eq!(prunable.get_chunk_containing(0), &chunk);
2903 }
2904
2905 mod proptests {
2906 use super::*;
2907 use proptest::prelude::*;
2908
2909 proptest! {
2910 #[test]
2911 fn is_unset_matches_naive(
2912 bits in prop::collection::vec(any::<bool>(), 1..=512usize),
2913 start in 0u64..=512,
2914 end in 0u64..=512,
2915 ) {
2916 let bitmap: BitMap = BitMap::from(bits.as_slice());
2917 let len = bitmap.len();
2918 let start = start.min(len);
2919 let end = end.max(start).min(len);
2920 let range = start..end;
2921
2922 let expected = range.clone().all(|i| !bitmap.get(i));
2923
2924 prop_assert_eq!(bitmap.is_unset(range), expected);
2925 }
2926 }
2927 }
2928
2929 #[test]
2930 fn is_unset_all_zeros() {
2931 let bitmap = BitMap::<8>::zeroes(256);
2932 assert!(bitmap.is_unset(0..256));
2933 }
2934
2935 #[test]
2936 fn is_unset_all_ones() {
2937 let bitmap = BitMap::<8>::ones(256);
2938 assert!(!bitmap.is_unset(0..256));
2939 }
2940
2941 #[test]
2942 fn is_unset_single_bit() {
2943 let mut bitmap = BitMap::<8>::zeroes(64);
2944 bitmap.set(31, true);
2945 assert!(bitmap.is_unset(0..31));
2946 assert!(!bitmap.is_unset(0..32));
2947 assert!(!bitmap.is_unset(31..32));
2948 assert!(bitmap.is_unset(32..64));
2949 }
2950
2951 #[test]
2952 fn is_unset_empty_range() {
2953 let bitmap = BitMap::<8>::ones(64);
2954 assert!(bitmap.is_unset(0..0));
2955 assert!(bitmap.is_unset(32..32));
2956 assert!(bitmap.is_unset(64..64));
2957 }
2958
2959 #[test]
2960 fn is_unset_chunk_boundaries() {
2961 let mut bitmap = BitMap::<1>::zeroes(32);
2963 bitmap.set(7, true);
2964 assert!(bitmap.is_unset(0..7));
2965 assert!(!bitmap.is_unset(0..8));
2966 assert!(bitmap.is_unset(8..32));
2967 }
2968
2969 #[test]
2970 fn is_unset_small_chunk_multi_span() {
2971 let mut bitmap = BitMap::<4>::zeroes(128);
2973 bitmap.set(96, true);
2974 assert!(bitmap.is_unset(0..96));
2975 assert!(!bitmap.is_unset(0..97));
2976 assert!(bitmap.is_unset(97..128));
2977 }
2978
2979 #[test]
2980 #[should_panic(expected = "out of bounds")]
2981 fn is_unset_out_of_bounds() {
2982 let bitmap = BitMap::<8>::zeroes(64);
2983 bitmap.is_unset(0..65);
2984 }
2985
2986 #[cfg(feature = "arbitrary")]
2987 mod conformance {
2988 use super::*;
2989 use commonware_codec::conformance::CodecConformance;
2990
2991 commonware_conformance::conformance_tests! {
2992 CodecConformance<BitMap>
2993 }
2994 }
2995}