1use crate::bit_chunk_iterator::{BitChunks, UnalignedBitChunk};
19use crate::bit_iterator::{BitIndexIterator, BitIndexU32Iterator, BitIterator, BitSliceIterator};
20use crate::bit_util::read_u64;
21use crate::{
22 BooleanBufferBuilder, Buffer, MutableBuffer, bit_util, buffer_bin_and, buffer_bin_or,
23 buffer_bin_xor,
24};
25
26use std::ops::{BitAnd, BitAndAssign, BitOr, BitOrAssign, BitXor, BitXorAssign, Not};
27
28#[derive(Debug, Clone, Eq)]
97pub struct BooleanBuffer {
98 buffer: Buffer,
100 bit_offset: usize,
102 bit_len: usize,
104}
105
106impl PartialEq for BooleanBuffer {
107 fn eq(&self, other: &Self) -> bool {
108 if self.bit_len != other.bit_len {
109 return false;
110 }
111
112 let lhs = self.bit_chunks().iter_padded();
113 let rhs = other.bit_chunks().iter_padded();
114 lhs.zip(rhs).all(|(a, b)| a == b)
115 }
116}
117
118impl BooleanBuffer {
119 pub fn new(buffer: Buffer, bit_offset: usize, bit_len: usize) -> Self {
125 let total_len = bit_offset.saturating_add(bit_len);
126 let buffer_len = buffer.len();
127 let buffer_bit_len = buffer_len.saturating_mul(8);
128 assert!(
129 total_len <= buffer_bit_len,
130 "buffer not large enough (bit_offset: {bit_offset}, bit_len: {bit_len}, buffer_len: {buffer_len})"
131 );
132 Self {
133 buffer,
134 bit_offset,
135 bit_len,
136 }
137 }
138
139 pub fn new_set(length: usize) -> Self {
141 let mut builder = BooleanBufferBuilder::new(length);
142 builder.append_n(length, true);
143 builder.finish()
144 }
145
146 pub fn new_unset(length: usize) -> Self {
148 let buffer = MutableBuffer::new_null(length).into_buffer();
149 Self {
150 buffer,
151 bit_offset: 0,
152 bit_len: length,
153 }
154 }
155
156 pub fn collect_bool<F: FnMut(usize) -> bool>(len: usize, f: F) -> Self {
158 let buffer = MutableBuffer::collect_bool(len, f);
159 Self::new(buffer.into(), 0, len)
160 }
161
162 pub fn from_bits(src: impl AsRef<[u8]>, offset_in_bits: usize, len_in_bits: usize) -> Self {
187 Self::from_bitwise_unary_op(src, offset_in_bits, len_in_bits, |a| a)
188 }
189
190 pub fn from_bitwise_unary_op<F>(
230 src: impl AsRef<[u8]>,
231 offset_in_bits: usize,
232 len_in_bits: usize,
233 mut op: F,
234 ) -> Self
235 where
236 F: FnMut(u64) -> u64,
237 {
238 let end = offset_in_bits + len_in_bits;
239 let aligned_offset = offset_in_bits & !63;
242 let aligned_end_bytes = bit_util::ceil(end, 64) * 8;
243 let src_len = src.as_ref().len();
244 let slice_end = aligned_end_bytes.min(src_len);
245
246 let aligned_start = &src.as_ref()[aligned_offset / 8..slice_end];
247
248 let (prefix, aligned_u64s, suffix) = unsafe { aligned_start.as_ref().align_to::<u64>() };
249 match (prefix, suffix) {
250 ([], []) => {
251 let result_u64s: Vec<u64> = aligned_u64s.iter().map(|l| op(*l)).collect();
253 return BooleanBuffer::new(result_u64s.into(), offset_in_bits % 64, len_in_bits);
254 }
255 ([], suffix) => {
256 let suffix = read_u64(suffix);
257 let result_u64s: Vec<u64> = aligned_u64s
258 .iter()
259 .copied()
260 .chain(std::iter::once(suffix))
261 .map(&mut op)
262 .collect();
263 return BooleanBuffer::new(result_u64s.into(), offset_in_bits % 64, len_in_bits);
264 }
265 _ => {}
266 }
267
268 let chunks = aligned_start.chunks_exact(8);
271 let remainder = chunks.remainder();
272 let iter = chunks.map(|c| u64::from_le_bytes(c.try_into().unwrap()));
273 let vec_u64s: Vec<u64> = if remainder.is_empty() {
274 iter.map(&mut op).collect()
275 } else {
276 iter.chain(Some(read_u64(remainder))).map(&mut op).collect()
277 };
278
279 BooleanBuffer::new(vec_u64s.into(), offset_in_bits % 64, len_in_bits)
280 }
281
282 pub fn from_bitwise_binary_op<F>(
334 left: impl AsRef<[u8]>,
335 left_offset_in_bits: usize,
336 right: impl AsRef<[u8]>,
337 right_offset_in_bits: usize,
338 len_in_bits: usize,
339 mut op: F,
340 ) -> Self
341 where
342 F: FnMut(u64, u64) -> u64,
343 {
344 let left = left.as_ref();
345 let right = right.as_ref();
346
347 if left_offset_in_bits % 64 == right_offset_in_bits % 64 {
351 let bit_offset = left_offset_in_bits % 64;
352 let left_end = left_offset_in_bits + len_in_bits;
353 let right_end = right_offset_in_bits + len_in_bits;
354
355 let left_aligned = left_offset_in_bits & !63;
356 let right_aligned = right_offset_in_bits & !63;
357
358 let left_end_bytes = (bit_util::ceil(left_end, 64) * 8).min(left.len());
359 let right_end_bytes = (bit_util::ceil(right_end, 64) * 8).min(right.len());
360
361 let left_slice = &left[left_aligned / 8..left_end_bytes];
362 let right_slice = &right[right_aligned / 8..right_end_bytes];
363
364 let (lp, left_u64s, ls) = unsafe { left_slice.align_to::<u64>() };
365 let (rp, right_u64s, rs) = unsafe { right_slice.align_to::<u64>() };
366
367 match (lp, ls, rp, rs) {
368 ([], [], [], []) => {
369 let result_u64s: Vec<u64> = left_u64s
370 .iter()
371 .zip(right_u64s.iter())
372 .map(|(l, r)| op(*l, *r))
373 .collect();
374 return BooleanBuffer::new(result_u64s.into(), bit_offset, len_in_bits);
375 }
376 ([], left_suf, [], right_suf) => {
377 let left_iter = left_u64s
378 .iter()
379 .copied()
380 .chain((!left_suf.is_empty()).then(|| read_u64(left_suf)));
381 let right_iter = right_u64s
382 .iter()
383 .copied()
384 .chain((!right_suf.is_empty()).then(|| read_u64(right_suf)));
385 let result_u64s: Vec<u64> =
386 left_iter.zip(right_iter).map(|(l, r)| op(l, r)).collect();
387 return BooleanBuffer::new(result_u64s.into(), bit_offset, len_in_bits);
388 }
389 _ => {}
390 }
391
392 let left_chunks = left_slice.chunks_exact(8);
394 let left_rem = left_chunks.remainder();
395 let right_chunks = right_slice.chunks_exact(8);
396 let right_rem = right_chunks.remainder();
397
398 let left_iter = left_chunks.map(|c| u64::from_le_bytes(c.try_into().unwrap()));
399 let right_iter = right_chunks.map(|c| u64::from_le_bytes(c.try_into().unwrap()));
400
401 let result_u64s: Vec<u64> = if left_rem.is_empty() && right_rem.is_empty() {
402 left_iter.zip(right_iter).map(|(l, r)| op(l, r)).collect()
403 } else {
404 left_iter
405 .chain(Some(read_u64(left_rem)))
406 .zip(right_iter.chain(Some(read_u64(right_rem))))
407 .map(|(l, r)| op(l, r))
408 .collect()
409 };
410 return BooleanBuffer::new(result_u64s.into(), bit_offset, len_in_bits);
411 }
412
413 let left_chunks = BitChunks::new(left, left_offset_in_bits, len_in_bits);
415 let right_chunks = BitChunks::new(right, right_offset_in_bits, len_in_bits);
416
417 let chunks = left_chunks
418 .iter()
419 .zip(right_chunks.iter())
420 .map(|(left, right)| op(left, right));
421 let mut buffer = unsafe { MutableBuffer::from_trusted_len_iter(chunks) };
424
425 let remainder_bytes = bit_util::ceil(left_chunks.remainder_len(), 8);
426 let rem = op(left_chunks.remainder_bits(), right_chunks.remainder_bits());
427 let rem = &rem.to_le_bytes()[0..remainder_bytes];
429 buffer.extend_from_slice(rem);
430
431 BooleanBuffer {
432 buffer: Buffer::from(buffer),
433 bit_offset: 0,
434 bit_len: len_in_bits,
435 }
436 }
437
438 pub fn count_set_bits(&self) -> usize {
440 self.buffer
441 .count_set_bits_offset(self.bit_offset, self.bit_len)
442 }
443
444 pub fn find_nth_set_bit_position(&self, start: usize, n: usize) -> usize {
447 if n == 0 {
448 return start;
449 }
450
451 self.slice(start, self.bit_len - start)
452 .set_indices()
453 .nth(n - 1)
454 .map(|idx| start + idx + 1)
455 .unwrap_or(self.bit_len)
456 }
457
458 #[inline]
461 pub fn bit_chunks(&self) -> BitChunks<'_> {
462 BitChunks::new(self.values(), self.bit_offset, self.bit_len)
463 }
464
465 #[inline]
467 pub fn offset(&self) -> usize {
468 self.bit_offset
469 }
470
471 #[inline]
473 pub fn len(&self) -> usize {
474 self.bit_len
475 }
476
477 #[inline]
479 pub fn is_empty(&self) -> bool {
480 self.bit_len == 0
481 }
482
483 pub fn shrink_to_fit(&mut self) {
485 self.buffer.shrink_to_fit();
487 }
488
489 #[inline]
495 pub fn value(&self, idx: usize) -> bool {
496 assert!(idx < self.bit_len);
497 unsafe { self.value_unchecked(idx) }
498 }
499
500 #[inline]
505 pub unsafe fn value_unchecked(&self, i: usize) -> bool {
506 unsafe { bit_util::get_bit_raw(self.buffer.as_ptr(), i + self.bit_offset) }
507 }
508
509 #[inline]
511 pub fn values(&self) -> &[u8] {
512 &self.buffer
513 }
514
515 pub fn slice(&self, offset: usize, len: usize) -> Self {
521 assert!(
522 offset.saturating_add(len) <= self.bit_len,
523 "the length + offset of the sliced BooleanBuffer cannot exceed the existing length"
524 );
525 Self {
526 buffer: self.buffer.clone(),
527 bit_offset: self.bit_offset + offset,
528 bit_len: len,
529 }
530 }
531
532 pub fn sliced(&self) -> Buffer {
536 self.buffer.bit_slice(self.bit_offset, self.bit_len)
537 }
538
539 pub fn ptr_eq(&self, other: &Self) -> bool {
543 self.buffer.as_ptr() == other.buffer.as_ptr()
544 && self.bit_offset == other.bit_offset
545 && self.bit_len == other.bit_len
546 }
547
548 #[inline]
552 pub fn inner(&self) -> &Buffer {
553 &self.buffer
554 }
555
556 pub fn into_inner(self) -> Buffer {
560 self.buffer
561 }
562
563 #[cfg(feature = "pool")]
567 pub fn claim(&self, pool: &dyn crate::MemoryPool) {
568 self.buffer.claim(pool);
569 }
570
571 fn bitwise_bin_op_assign<F>(&mut self, rhs: &BooleanBuffer, op: F)
582 where
583 F: FnMut(u64, u64) -> u64,
584 {
585 assert_eq!(self.bit_len, rhs.bit_len);
586 let buffer = std::mem::take(&mut self.buffer);
588 match buffer.into_mutable() {
589 Ok(mut buf) => {
590 bit_util::apply_bitwise_binary_op(
591 &mut buf,
592 self.bit_offset,
593 &rhs.buffer,
594 rhs.bit_offset,
595 self.bit_len,
596 op,
597 );
598 self.buffer = buf.into();
599 }
600 Err(buf) => {
601 self.buffer = buf;
602 *self = BooleanBuffer::from_bitwise_binary_op(
603 self.values(),
604 self.bit_offset,
605 rhs.values(),
606 rhs.bit_offset,
607 self.bit_len,
608 op,
609 );
610 }
611 }
612 }
613
614 pub fn iter(&self) -> BitIterator<'_> {
616 self.into_iter()
617 }
618
619 fn unaligned_bit_chunks(&self) -> UnalignedBitChunk<'_> {
621 UnalignedBitChunk::new(self.values(), self.offset(), self.len())
622 }
623
624 pub fn set_indices(&self) -> BitIndexIterator<'_> {
626 BitIndexIterator::new(self.values(), self.bit_offset, self.bit_len)
627 }
628
629 pub fn set_indices_u32(&self) -> BitIndexU32Iterator<'_> {
631 BitIndexU32Iterator::new(self.values(), self.bit_offset, self.bit_len)
632 }
633
634 pub fn set_slices(&self) -> BitSliceIterator<'_> {
636 BitSliceIterator::new(self.values(), self.bit_offset, self.bit_len)
637 }
638
639 const CHUNK_FOLD_BLOCK_SIZE: usize = 16;
643
644 pub fn has_true(&self) -> bool {
651 let bit_chunks = self.unaligned_bit_chunks();
652 let chunks = bit_chunks.chunks();
653 let mut exact = chunks.chunks_exact(Self::CHUNK_FOLD_BLOCK_SIZE);
654 let found = bit_chunks.prefix().unwrap_or(0) != 0
655 || exact.any(|block| block.iter().fold(0u64, |acc, &c| acc | c) != 0);
656 found || exact.remainder().iter().any(|&c| c != 0) || bit_chunks.suffix().unwrap_or(0) != 0
657 }
658
659 pub fn has_false(&self) -> bool {
666 let bit_chunks = self.unaligned_bit_chunks();
667 let lead_mask = !((1u64 << bit_chunks.lead_padding()) - 1);
670 let trail_mask = if bit_chunks.trailing_padding() == 0 {
671 u64::MAX
672 } else {
673 (1u64 << (64 - bit_chunks.trailing_padding())) - 1
674 };
675 let (prefix_fill, suffix_fill) = match (bit_chunks.prefix(), bit_chunks.suffix()) {
676 (Some(_), Some(_)) => (!lead_mask, !trail_mask),
677 (Some(_), None) => (!lead_mask | !trail_mask, 0),
678 (None, Some(_)) => (0, !trail_mask),
679 (None, None) => (0, 0),
680 };
681 let chunks = bit_chunks.chunks();
682 let mut exact = chunks.chunks_exact(Self::CHUNK_FOLD_BLOCK_SIZE);
683 let found = bit_chunks
684 .prefix()
685 .is_some_and(|v| (v | prefix_fill) != u64::MAX)
686 || exact.any(|block| block.iter().fold(u64::MAX, |acc, &c| acc & c) != u64::MAX);
687 found
688 || exact.remainder().iter().any(|&c| c != u64::MAX)
689 || bit_chunks
690 .suffix()
691 .is_some_and(|v| (v | suffix_fill) != u64::MAX)
692 }
693}
694
695impl Not for &BooleanBuffer {
696 type Output = BooleanBuffer;
697
698 fn not(self) -> Self::Output {
699 BooleanBuffer::from_bitwise_unary_op(&self.buffer, self.bit_offset, self.bit_len, |a| !a)
700 }
701}
702
703impl BitAnd<&BooleanBuffer> for &BooleanBuffer {
704 type Output = BooleanBuffer;
705
706 fn bitand(self, rhs: &BooleanBuffer) -> Self::Output {
707 assert_eq!(self.bit_len, rhs.bit_len);
708 BooleanBuffer {
709 buffer: buffer_bin_and(
710 &self.buffer,
711 self.bit_offset,
712 &rhs.buffer,
713 rhs.bit_offset,
714 self.bit_len,
715 ),
716 bit_offset: 0,
717 bit_len: self.bit_len,
718 }
719 }
720}
721
722impl BitOr<&BooleanBuffer> for &BooleanBuffer {
723 type Output = BooleanBuffer;
724
725 fn bitor(self, rhs: &BooleanBuffer) -> Self::Output {
726 assert_eq!(self.bit_len, rhs.bit_len);
727 BooleanBuffer {
728 buffer: buffer_bin_or(
729 &self.buffer,
730 self.bit_offset,
731 &rhs.buffer,
732 rhs.bit_offset,
733 self.bit_len,
734 ),
735 bit_offset: 0,
736 bit_len: self.bit_len,
737 }
738 }
739}
740
741impl BitXor<&BooleanBuffer> for &BooleanBuffer {
742 type Output = BooleanBuffer;
743
744 fn bitxor(self, rhs: &BooleanBuffer) -> Self::Output {
745 assert_eq!(self.bit_len, rhs.bit_len);
746 BooleanBuffer {
747 buffer: buffer_bin_xor(
748 &self.buffer,
749 self.bit_offset,
750 &rhs.buffer,
751 rhs.bit_offset,
752 self.bit_len,
753 ),
754 bit_offset: 0,
755 bit_len: self.bit_len,
756 }
757 }
758}
759
760impl BitAndAssign<&BooleanBuffer> for BooleanBuffer {
761 fn bitand_assign(&mut self, rhs: &BooleanBuffer) {
762 self.bitwise_bin_op_assign(rhs, |a, b| a & b);
763 }
764}
765
766impl BitOrAssign<&BooleanBuffer> for BooleanBuffer {
767 fn bitor_assign(&mut self, rhs: &BooleanBuffer) {
768 self.bitwise_bin_op_assign(rhs, |a, b| a | b);
769 }
770}
771
772impl BitXorAssign<&BooleanBuffer> for BooleanBuffer {
773 fn bitxor_assign(&mut self, rhs: &BooleanBuffer) {
774 self.bitwise_bin_op_assign(rhs, |a, b| a ^ b);
775 }
776}
777
778impl<'a> IntoIterator for &'a BooleanBuffer {
779 type Item = bool;
780 type IntoIter = BitIterator<'a>;
781
782 fn into_iter(self) -> Self::IntoIter {
783 BitIterator::new(self.values(), self.bit_offset, self.bit_len)
784 }
785}
786
787impl From<&[bool]> for BooleanBuffer {
788 fn from(value: &[bool]) -> Self {
789 let mut builder = BooleanBufferBuilder::new(value.len());
790 builder.append_slice(value);
791 builder.finish()
792 }
793}
794
795impl From<Vec<bool>> for BooleanBuffer {
796 fn from(value: Vec<bool>) -> Self {
797 value.as_slice().into()
798 }
799}
800
801impl FromIterator<bool> for BooleanBuffer {
802 fn from_iter<T: IntoIterator<Item = bool>>(iter: T) -> Self {
803 let iter = iter.into_iter();
804 let (hint, _) = iter.size_hint();
805 let mut builder = BooleanBufferBuilder::new(hint);
806 iter.for_each(|b| builder.append(b));
807 builder.finish()
808 }
809}
810
811#[cfg(test)]
812mod tests {
813 use super::*;
814
815 #[test]
816 fn test_boolean_new() {
817 let bytes = &[0, 1, 2, 3, 4];
818 let buf = Buffer::from(bytes);
819 let offset = 0;
820 let len = 24;
821
822 let boolean_buf = BooleanBuffer::new(buf.clone(), offset, len);
823 assert_eq!(bytes, boolean_buf.values());
824 assert_eq!(offset, boolean_buf.offset());
825 assert_eq!(len, boolean_buf.len());
826
827 assert_eq!(2, boolean_buf.count_set_bits());
828 assert_eq!(&buf, boolean_buf.inner());
829 assert_eq!(buf, boolean_buf.clone().into_inner());
830
831 assert!(!boolean_buf.is_empty())
832 }
833
834 #[test]
835 fn test_boolean_data_equality() {
836 let boolean_buf1 = BooleanBuffer::new(Buffer::from(&[0, 1, 4, 3, 5]), 0, 32);
837 let boolean_buf2 = BooleanBuffer::new(Buffer::from(&[0, 1, 4, 3, 5]), 0, 32);
838 assert_eq!(boolean_buf1, boolean_buf2);
839
840 let boolean_buf3 = boolean_buf1.slice(8, 16);
842 assert_ne!(boolean_buf1, boolean_buf3);
843 let boolean_buf4 = boolean_buf1.slice(0, 32);
844 assert_eq!(boolean_buf1, boolean_buf4);
845
846 let boolean_buf2 = BooleanBuffer::new(Buffer::from(&[0, 0, 2, 3, 4]), 0, 32);
848 assert_ne!(boolean_buf1, boolean_buf2);
849
850 let boolean_buf2 = BooleanBuffer::new(Buffer::from(&[0, 1, 4, 3, 5]), 0, 24);
852 assert_ne!(boolean_buf1, boolean_buf2);
853
854 assert!(boolean_buf1.ptr_eq(&boolean_buf1));
856 assert!(boolean_buf2.ptr_eq(&boolean_buf2));
857 assert!(!boolean_buf1.ptr_eq(&boolean_buf2));
858 }
859
860 #[test]
861 fn test_boolean_slice() {
862 let bytes = &[0, 3, 2, 6, 2];
863 let boolean_buf1 = BooleanBuffer::new(Buffer::from(bytes), 0, 32);
864 let boolean_buf2 = BooleanBuffer::new(Buffer::from(bytes), 0, 32);
865
866 let boolean_slice1 = boolean_buf1.slice(16, 16);
867 let boolean_slice2 = boolean_buf2.slice(0, 16);
868 assert_eq!(boolean_slice1.values(), boolean_slice2.values());
869
870 assert_eq!(bytes, boolean_slice1.values());
871 assert_eq!(16, boolean_slice1.bit_offset);
872 assert_eq!(16, boolean_slice1.bit_len);
873
874 assert_eq!(bytes, boolean_slice2.values());
875 assert_eq!(0, boolean_slice2.bit_offset);
876 assert_eq!(16, boolean_slice2.bit_len);
877 }
878
879 #[test]
880 fn test_boolean_bitand() {
881 let offset = 0;
882 let len = 40;
883
884 let buf1 = Buffer::from(&[0, 1, 1, 0, 0]);
885 let boolean_buf1 = &BooleanBuffer::new(buf1, offset, len);
886
887 let buf2 = Buffer::from(&[0, 1, 1, 1, 0]);
888 let boolean_buf2 = &BooleanBuffer::new(buf2, offset, len);
889
890 let expected = BooleanBuffer::new(Buffer::from(&[0, 1, 1, 0, 0]), offset, len);
891 assert_eq!(boolean_buf1 & boolean_buf2, expected);
892 }
893
894 #[test]
895 fn test_boolean_bitor() {
896 let offset = 0;
897 let len = 40;
898
899 let buf1 = Buffer::from(&[0, 1, 1, 0, 0]);
900 let boolean_buf1 = &BooleanBuffer::new(buf1, offset, len);
901
902 let buf2 = Buffer::from(&[0, 1, 1, 1, 0]);
903 let boolean_buf2 = &BooleanBuffer::new(buf2, offset, len);
904
905 let expected = BooleanBuffer::new(Buffer::from(&[0, 1, 1, 1, 0]), offset, len);
906 assert_eq!(boolean_buf1 | boolean_buf2, expected);
907 }
908
909 #[test]
910 fn test_boolean_bitxor() {
911 let offset = 0;
912 let len = 40;
913
914 let buf1 = Buffer::from(&[0, 1, 1, 0, 0]);
915 let boolean_buf1 = &BooleanBuffer::new(buf1, offset, len);
916
917 let buf2 = Buffer::from(&[0, 1, 1, 1, 0]);
918 let boolean_buf2 = &BooleanBuffer::new(buf2, offset, len);
919
920 let expected = BooleanBuffer::new(Buffer::from(&[0, 0, 0, 1, 0]), offset, len);
921 assert_eq!(boolean_buf1 ^ boolean_buf2, expected);
922 }
923
924 #[test]
925 fn test_boolean_bitand_assign_shared_and_unshared() {
926 let rhs = BooleanBuffer::from(&[true, true, false, true, false, true][..]);
927 let original = BooleanBuffer::from(&[true, false, true, true, true, false][..]);
928
929 let mut unshared = BooleanBuffer::from(&[true, false, true, true, true, false][..]);
930 unshared &= &rhs;
931
932 let mut shared = original.clone();
933 let _shared_owner = shared.clone();
934 shared &= &rhs;
935
936 let expected = &original & &rhs;
937 assert_eq!(unshared, expected);
938 assert_eq!(shared, expected);
939 }
940
941 #[test]
942 fn test_boolean_bitor_assign() {
943 let rhs = BooleanBuffer::from(&[true, true, false, true, false, true][..]);
944 let original = BooleanBuffer::from(&[true, false, true, true, true, false][..]);
945
946 let mut actual = original.clone();
947 actual |= &rhs;
948
949 let expected = &original | &rhs;
950 assert_eq!(actual, expected);
951 }
952
953 #[test]
954 fn test_boolean_bitxor_assign() {
955 let rhs = BooleanBuffer::from(&[true, true, false, true, false, true][..]);
956 let original = BooleanBuffer::from(&[true, false, true, true, true, false][..]);
957
958 let mut actual = original.clone();
959 actual ^= &rhs;
960
961 let expected = &original ^ &rhs;
962 assert_eq!(actual, expected);
963 }
964
965 #[test]
966 fn test_boolean_not() {
967 let offset = 0;
968 let len = 40;
969
970 let buf = Buffer::from(&[0, 1, 1, 0, 0]);
971 let boolean_buf = &BooleanBuffer::new(buf, offset, len);
972
973 let expected = BooleanBuffer::new(Buffer::from(&[255, 254, 254, 255, 255]), offset, len);
974 assert_eq!(!boolean_buf, expected);
975
976 let sliced = boolean_buf.slice(3, 20);
978 let result = !&sliced;
979 assert_eq!(result.offset(), 3);
980 assert_eq!(result.len(), sliced.len());
981 for i in 0..sliced.len() {
982 assert_eq!(result.value(i), !sliced.value(i));
983 }
984 }
985
986 #[test]
987 fn test_boolean_from_slice_bool() {
988 let v = [true, false, false];
989 let buf = BooleanBuffer::from(&v[..]);
990 assert_eq!(buf.offset(), 0);
991 assert_eq!(buf.len(), 3);
992 assert_eq!(buf.values().len(), 1);
993 assert!(buf.value(0));
994 }
995
996 #[test]
997 fn test_from_bitwise_unary_op() {
998 let input_bools = (0..1024)
1001 .map(|_| rand::random::<bool>())
1002 .collect::<Vec<bool>>();
1003 let input_buffer = BooleanBuffer::from(&input_bools[..]);
1004
1005 for offset in 0..1024 {
1007 let result = BooleanBuffer::from_bitwise_unary_op(
1008 input_buffer.values(),
1009 offset,
1010 input_buffer.len() - offset,
1011 |a| !a,
1012 );
1013 let expected = input_bools[offset..]
1014 .iter()
1015 .map(|b| !*b)
1016 .collect::<BooleanBuffer>();
1017 assert_eq!(result, expected);
1018 }
1019
1020 for offset in 0..512 {
1022 let len = 512 - offset; let result =
1024 BooleanBuffer::from_bitwise_unary_op(input_buffer.values(), offset, len, |a| !a);
1025 let expected = input_bools[offset..]
1026 .iter()
1027 .take(len)
1028 .map(|b| !*b)
1029 .collect::<BooleanBuffer>();
1030 assert_eq!(result, expected);
1031 }
1032 }
1033
1034 #[test]
1035 fn test_from_bitwise_unary_op_unaligned_fallback() {
1036 let bytes = (0..80)
1040 .map(|i| (i as u8).wrapping_mul(37).wrapping_add(11))
1041 .collect::<Vec<_>>();
1042 let base = bytes.as_ptr() as usize;
1043 let shift = (0..8).find(|s| !(base + s).is_multiple_of(8)).unwrap();
1044 let misaligned = &bytes[shift..];
1045
1046 let src = &misaligned[..24];
1048 let offset = 7;
1049 let len = 96;
1050 let result = BooleanBuffer::from_bitwise_unary_op(src, offset, len, |a| !a);
1051 let expected = (0..len)
1052 .map(|i| !bit_util::get_bit(src, offset + i))
1053 .collect::<BooleanBuffer>();
1054 assert_eq!(result, expected);
1055 assert_eq!(result.offset(), offset % 64);
1056
1057 let src = &misaligned[..13];
1059 let offset = 3;
1060 let len = 100;
1061 let result = BooleanBuffer::from_bitwise_unary_op(src, offset, len, |a| !a);
1062 let expected = (0..len)
1063 .map(|i| !bit_util::get_bit(src, offset + i))
1064 .collect::<BooleanBuffer>();
1065 assert_eq!(result, expected);
1066 assert_eq!(result.offset(), offset % 64);
1067 }
1068
1069 #[test]
1070 fn test_from_bitwise_binary_op() {
1071 let input_bools_left = (0..1024)
1073 .map(|_| rand::random::<bool>())
1074 .collect::<Vec<bool>>();
1075 let input_bools_right = (0..1024)
1076 .map(|_| rand::random::<bool>())
1077 .collect::<Vec<bool>>();
1078 let input_buffer_left = BooleanBuffer::from(&input_bools_left[..]);
1079 let input_buffer_right = BooleanBuffer::from(&input_bools_right[..]);
1080
1081 #[cfg(miri)] let left_offsets = [0, 1, 7, 8, 63, 64, 65];
1083 #[cfg(not(miri))]
1084 let left_offsets = 0..200;
1085
1086 for left_offset in left_offsets {
1087 for right_offset in [0, 4, 5, 17, 33, 24, 45, 64, 65, 100, 200] {
1088 for len_offset in [0, 1, 44, 100, 256, 300, 512] {
1089 let len = 1024 - len_offset - left_offset.max(right_offset); let result = BooleanBuffer::from_bitwise_binary_op(
1092 input_buffer_left.values(),
1093 left_offset,
1094 input_buffer_right.values(),
1095 right_offset,
1096 len,
1097 |a, b| a & b,
1098 );
1099 let expected = input_bools_left[left_offset..]
1101 .iter()
1102 .zip(&input_bools_right[right_offset..])
1103 .take(len)
1104 .map(|(a, b)| *a & *b)
1105 .collect::<BooleanBuffer>();
1106 assert_eq!(result, expected);
1107 }
1108 }
1109 }
1110 }
1111
1112 #[test]
1113 fn test_from_bitwise_binary_op_same_mod_64_unaligned_fallback() {
1114 let left_bytes = [
1117 0, 0b1101_0010, 0b0110_1101,
1120 0b1010_0111,
1121 0b0001_1110,
1122 0b1110_0001,
1123 0b0101_1010,
1124 0b1001_0110,
1125 0b0011_1100,
1126 0b1011_0001,
1127 0b0100_1110,
1128 0b1100_0011,
1129 0b0111_1000,
1130 ];
1131 let right_bytes = [
1132 0, 0b1010_1100, 0b0101_0011,
1135 0b1111_0000,
1136 0b0011_1010,
1137 0b1000_1111,
1138 0b0110_0101,
1139 0b1101_1000,
1140 0b0001_0111,
1141 0b1110_0100,
1142 0b0010_1101,
1143 0b1001_1010,
1144 0b0111_0001,
1145 ];
1146
1147 let left = &left_bytes[1..];
1148 let right = &right_bytes[1..];
1149
1150 let left_offset = 3;
1151 let right_offset = 67; let len = 24; let result = BooleanBuffer::from_bitwise_binary_op(
1155 left,
1156 left_offset,
1157 right,
1158 right_offset,
1159 len,
1160 |a, b| a & b,
1161 );
1162 let expected = (0..len)
1163 .map(|i| {
1164 bit_util::get_bit(left, left_offset + i)
1165 & bit_util::get_bit(right, right_offset + i)
1166 })
1167 .collect::<BooleanBuffer>();
1168
1169 assert_eq!(result, expected);
1170 assert_eq!(result.offset(), left_offset % 64);
1171 }
1172
1173 #[test]
1174 fn test_from_bitwise_binary_op_same_mod_64_unaligned_fallback_no_remainder() {
1175 let left_bytes = [
1177 0, 0b1010_1100, 0b0110_1001,
1180 0b1101_0011,
1181 0b0001_1110,
1182 0b1110_0101,
1183 0b0101_1000,
1184 0b1001_0111,
1185 0b0011_1101,
1186 ];
1187 let right_bytes = [
1188 0, 0b0111_0010, 0b1010_1001,
1191 0b0101_1110,
1192 0b1100_0011,
1193 0b0011_1011,
1194 0b1000_1110,
1195 0b1111_0001,
1196 0b0100_1101,
1197 0b1011_0110,
1198 0b0001_1011,
1199 0b1101_0100,
1200 0b0110_0011,
1201 0b1001_1110,
1202 0b0010_1001,
1203 0b1110_0110,
1204 0b0101_0001,
1205 ];
1206
1207 let left = &left_bytes[1..];
1208 let right = &right_bytes[1..];
1209
1210 let left_offset = 3;
1211 let right_offset = 67; let len = 61; let result = BooleanBuffer::from_bitwise_binary_op(
1215 left,
1216 left_offset,
1217 right,
1218 right_offset,
1219 len,
1220 |a, b| a | b,
1221 );
1222 let expected = (0..len)
1223 .map(|i| {
1224 bit_util::get_bit(left, left_offset + i)
1225 | bit_util::get_bit(right, right_offset + i)
1226 })
1227 .collect::<BooleanBuffer>();
1228
1229 assert_eq!(result, expected);
1230 assert_eq!(result.offset(), left_offset % 64);
1231 }
1232
1233 #[test]
1234 fn test_extend_trusted_len_sets_byte_len() {
1235 let mut builder = BooleanBufferBuilder::new(0);
1237 let bools: Vec<_> = (0..10).map(|i| i % 2 == 0).collect();
1238 unsafe { builder.extend_trusted_len(bools.into_iter()) };
1239 assert_eq!(builder.as_slice().len(), bit_util::ceil(builder.len(), 8));
1240 }
1241
1242 #[test]
1243 fn test_extend_trusted_len_then_append() {
1244 let mut builder = BooleanBufferBuilder::new(0);
1246 let bools: Vec<_> = (0..9).map(|i| i % 3 == 0).collect();
1247 unsafe { builder.extend_trusted_len(bools.clone().into_iter()) };
1248 builder.append(true);
1249 assert_eq!(builder.as_slice().len(), bit_util::ceil(builder.len(), 8));
1250 let finished = builder.finish();
1251 for (i, v) in bools.into_iter().chain(std::iter::once(true)).enumerate() {
1252 assert_eq!(finished.value(i), v, "at index {i}");
1253 }
1254 }
1255
1256 #[test]
1257 fn test_find_nth_set_bit_position() {
1258 let bools = vec![true, false, true, true, false, true];
1259 let buffer = BooleanBuffer::from(bools);
1260
1261 assert_eq!(buffer.clone().find_nth_set_bit_position(0, 1), 1);
1262 assert_eq!(buffer.clone().find_nth_set_bit_position(0, 2), 3);
1263 assert_eq!(buffer.clone().find_nth_set_bit_position(0, 3), 4);
1264 assert_eq!(buffer.clone().find_nth_set_bit_position(0, 4), 6);
1265 assert_eq!(buffer.clone().find_nth_set_bit_position(0, 5), 6);
1266
1267 assert_eq!(buffer.clone().find_nth_set_bit_position(1, 1), 3);
1268 assert_eq!(buffer.clone().find_nth_set_bit_position(3, 1), 4);
1269 assert_eq!(buffer.clone().find_nth_set_bit_position(3, 2), 6);
1270 }
1271
1272 #[test]
1273 fn test_find_nth_set_bit_position_large() {
1274 let mut bools = vec![false; 1000];
1275 bools[100] = true;
1276 bools[500] = true;
1277 bools[999] = true;
1278 let buffer = BooleanBuffer::from(bools);
1279
1280 assert_eq!(buffer.clone().find_nth_set_bit_position(0, 1), 101);
1281 assert_eq!(buffer.clone().find_nth_set_bit_position(0, 2), 501);
1282 assert_eq!(buffer.clone().find_nth_set_bit_position(0, 3), 1000);
1283 assert_eq!(buffer.clone().find_nth_set_bit_position(0, 4), 1000);
1284
1285 assert_eq!(buffer.clone().find_nth_set_bit_position(101, 1), 501);
1286 }
1287
1288 #[test]
1289 fn test_find_nth_set_bit_position_sliced() {
1290 let bools = vec![false, true, false, true, true, false, true]; let buffer = BooleanBuffer::from(bools);
1292 let slice = buffer.slice(1, 6); assert_eq!(slice.len(), 6);
1295 assert_eq!(slice.clone().find_nth_set_bit_position(0, 1), 1);
1299 assert_eq!(slice.clone().find_nth_set_bit_position(0, 2), 3);
1300 assert_eq!(slice.clone().find_nth_set_bit_position(0, 3), 4);
1301 assert_eq!(slice.clone().find_nth_set_bit_position(0, 4), 6);
1302 }
1303
1304 #[test]
1305 fn test_find_nth_set_bit_position_all_set() {
1306 let buffer = BooleanBuffer::new_set(100);
1307 for i in 1..=100 {
1308 assert_eq!(buffer.clone().find_nth_set_bit_position(0, i), i);
1309 }
1310 assert_eq!(buffer.clone().find_nth_set_bit_position(0, 101), 100);
1311 }
1312
1313 #[test]
1314 fn test_find_nth_set_bit_position_none_set() {
1315 let buffer = BooleanBuffer::new_unset(100);
1316 assert_eq!(buffer.clone().find_nth_set_bit_position(0, 1), 100);
1317 }
1318
1319 #[test]
1320 fn test_has_true_has_false_all_true() {
1321 let arr = BooleanBuffer::from(vec![true, true, true]);
1322 assert!(arr.has_true());
1323 assert!(!arr.has_false());
1324 }
1325
1326 #[test]
1327 fn test_has_true_has_false_all_false() {
1328 let arr = BooleanBuffer::from(vec![false, false, false]);
1329 assert!(!arr.has_true());
1330 assert!(arr.has_false());
1331 }
1332
1333 #[test]
1334 fn test_has_true_has_false_mixed() {
1335 let arr = BooleanBuffer::from(vec![true, false, true]);
1336 assert!(arr.has_true());
1337 assert!(arr.has_false());
1338 }
1339
1340 #[test]
1341 fn test_has_true_has_false_empty() {
1342 let arr = BooleanBuffer::from(Vec::<bool>::new());
1343 assert!(!arr.has_true());
1344 assert!(!arr.has_false());
1345 }
1346
1347 #[test]
1348 fn test_has_false_aligned_suffix_all_true() {
1349 let arr = BooleanBuffer::from(vec![true; 129]);
1350 assert!(arr.has_true());
1351 assert!(!arr.has_false());
1352 }
1353
1354 #[test]
1355 fn test_has_false_non_aligned_all_true() {
1356 let arr = BooleanBuffer::from(vec![true; 65]);
1358 assert!(arr.has_true());
1359 assert!(!arr.has_false());
1360 }
1361
1362 #[test]
1363 fn test_has_false_non_aligned_last_false() {
1364 let mut values = vec![true; 64];
1366 values.push(false);
1367 let arr = BooleanBuffer::from(values);
1368 assert!(arr.has_true());
1369 assert!(arr.has_false());
1370 }
1371
1372 #[test]
1373 fn test_has_false_exact_64_all_true() {
1374 let arr = BooleanBuffer::from(vec![true; 64]);
1376 assert!(arr.has_true());
1377 assert!(!arr.has_false());
1378 }
1379
1380 #[test]
1381 fn test_has_true_has_false_unaligned_slices() {
1382 let cases = [
1383 (1, 129, true, false),
1384 (3, 130, true, false),
1385 (5, 65, true, false),
1386 (7, 64, true, false),
1387 ];
1388
1389 let base = BooleanBuffer::from(vec![true; 300]);
1390
1391 for (offset, len, expected_has_true, expected_has_false) in cases {
1392 let arr = base.slice(offset, len);
1393 assert_eq!(
1394 arr.has_true(),
1395 expected_has_true,
1396 "offset={offset} len={len}"
1397 );
1398 assert_eq!(
1399 arr.has_false(),
1400 expected_has_false,
1401 "offset={offset} len={len}"
1402 );
1403 }
1404 }
1405
1406 #[test]
1407 fn test_has_true_has_false_exact_multiples_of_64() {
1408 let cases = [
1409 (64, true, false),
1410 (128, true, false),
1411 (192, true, false),
1412 (256, true, false),
1413 ];
1414
1415 for (len, expected_has_true, expected_has_false) in cases {
1416 let arr = BooleanBuffer::from(vec![true; len]);
1417 assert_eq!(arr.has_true(), expected_has_true, "len={len}");
1418 assert_eq!(arr.has_false(), expected_has_false, "len={len}");
1419 }
1420 }
1421}