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