1use crate::bit_iterator::{BitIndexIterator, BitIterator, BitSliceIterator};
19use crate::buffer::BooleanBuffer;
20use crate::{Buffer, MutableBuffer, OverflowError};
21
22#[derive(Debug, Clone, Eq, PartialEq)]
34pub struct NullBuffer {
35 buffer: BooleanBuffer,
36 null_count: usize,
37}
38
39impl NullBuffer {
40 pub fn new(buffer: BooleanBuffer) -> Self {
42 let null_count = buffer.len() - buffer.count_set_bits();
43 Self { buffer, null_count }
44 }
45
46 pub fn new_null(len: usize) -> Self {
48 Self {
49 buffer: BooleanBuffer::new_unset(len),
50 null_count: len,
51 }
52 }
53
54 pub fn new_valid(len: usize) -> Self {
59 Self {
60 buffer: BooleanBuffer::new_set(len),
61 null_count: 0,
62 }
63 }
64
65 pub unsafe fn new_unchecked(buffer: BooleanBuffer, null_count: usize) -> Self {
71 Self { buffer, null_count }
72 }
73
74 pub fn union(lhs: Option<&NullBuffer>, rhs: Option<&NullBuffer>) -> Option<NullBuffer> {
80 match (lhs, rhs) {
81 (Some(lhs), Some(rhs)) if lhs.null_count() > 0 || rhs.null_count() > 0 => {
82 Some(Self::new(lhs.inner() & rhs.inner()))
83 }
84 (Some(n), None) | (None, Some(n)) if n.null_count() > 0 => Some(n.clone()),
85 (_, _) => None,
86 }
87 }
88
89 pub fn union_many<'a>(
93 nulls: impl IntoIterator<Item = Option<&'a NullBuffer>>,
94 ) -> Option<NullBuffer> {
95 let mut buffers = nulls.into_iter().filter_map(|nb| match nb {
97 Some(nb) if nb.null_count > 0 => Some(nb.inner()),
98 _ => None,
99 });
100 let first = buffers.next()?;
101 let mut result = first.clone();
102 for buf in buffers {
103 result &= buf;
104 }
105 Some(Self::new(result))
106 }
107
108 pub fn contains(&self, other: &NullBuffer) -> bool {
110 if other.null_count == 0 {
111 return true;
112 }
113 let lhs = self.inner().bit_chunks().iter_padded();
114 let rhs = other.inner().bit_chunks().iter_padded();
115 lhs.zip(rhs).all(|(l, r)| (l & !r) == 0)
116 }
117
118 pub fn expand(&self, count: usize) -> Self {
127 self.try_expand(count).unwrap_or_else(|err| panic!("{err}"))
128 }
129
130 pub fn try_expand(&self, count: usize) -> Result<Self, OverflowError> {
138 let capacity = self
139 .buffer
140 .len()
141 .checked_mul(count)
142 .ok_or_else(|| OverflowError::new::<usize>("buffer length"))?;
143 let mut buffer = MutableBuffer::new_null(capacity);
144
145 if count.is_multiple_of(8) {
146 let bytes_per_bit = count / 8;
151 let buf = buffer.as_mut();
152 for (start, end) in BitSliceIterator::new(
153 self.buffer.values(),
154 self.buffer.offset(),
155 self.buffer.len(),
156 ) {
157 let byte_start = start * bytes_per_bit;
158 let byte_end = end * bytes_per_bit;
159 buf[byte_start..byte_end].fill(0xFF);
160 }
161 } else if count.is_multiple_of(4) {
162 let buf = buffer.as_mut();
166 for i in 0..self.buffer.len() {
167 if self.is_null(i) {
168 continue;
169 }
170 let start_bit = i * count;
171 let end_bit = start_bit + count;
172 if start_bit.is_multiple_of(8) {
173 buf[start_bit / 8..end_bit / 8].fill(0xFF);
174 buf[end_bit / 8] |= 0x0F;
175 } else {
176 buf[start_bit / 8] |= 0xF0;
177 buf[start_bit / 8 + 1..end_bit / 8].fill(0xFF);
178 }
179 }
180 } else {
181 let buf = buffer.as_mut();
186 for (start, end) in BitSliceIterator::new(
187 self.buffer.values(),
188 self.buffer.offset(),
189 self.buffer.len(),
190 ) {
191 let start_bit = start * count;
192 let end_bit = end * count;
193 let start_byte = start_bit / 8;
194 let start_offset = (start_bit % 8) as u32; let end_byte = end_bit / 8;
196 let end_offset = (end_bit % 8) as u32; if start_byte == end_byte {
199 buf[start_byte] |= (0xFFu8 << start_offset) & ((1u8 << end_offset) - 1);
204 } else {
205 if start_offset != 0 {
206 buf[start_byte] |= 0xFFu8 << start_offset;
208 }
209 let full_start = start_byte + (start_offset != 0) as usize;
211 buf[full_start..end_byte].fill(0xFF);
212 if end_offset != 0 {
213 buf[end_byte] |= (1u8 << end_offset) - 1;
216 }
217 }
218 }
219 }
220 Ok(Self {
221 buffer: BooleanBuffer::new(buffer.into(), 0, capacity),
222 null_count: self.null_count * count,
223 })
224 }
225
226 #[inline]
228 pub fn len(&self) -> usize {
229 self.buffer.len()
230 }
231
232 #[inline]
234 pub fn offset(&self) -> usize {
235 self.buffer.offset()
236 }
237
238 #[inline]
240 pub fn is_empty(&self) -> bool {
241 self.buffer.is_empty()
242 }
243
244 pub fn shrink_to_fit(&mut self) {
246 self.buffer.shrink_to_fit();
247 }
248
249 #[inline]
251 pub fn null_count(&self) -> usize {
252 self.null_count
253 }
254
255 #[inline]
261 pub fn is_valid(&self, idx: usize) -> bool {
262 self.buffer.value(idx)
263 }
264
265 #[inline]
271 pub fn is_null(&self, idx: usize) -> bool {
272 !self.is_valid(idx)
273 }
274
275 #[inline]
277 pub fn validity(&self) -> &[u8] {
278 self.buffer.values()
279 }
280
281 pub fn slice(&self, offset: usize, len: usize) -> Self {
287 Self::new(self.buffer.slice(offset, len))
288 }
289
290 pub fn iter(&self) -> BitIterator<'_> {
297 self.buffer.iter()
298 }
299
300 pub fn valid_indices(&self) -> BitIndexIterator<'_> {
304 self.buffer.set_indices()
305 }
306
307 pub fn valid_slices(&self) -> BitSliceIterator<'_> {
311 self.buffer.set_slices()
312 }
313
314 #[inline]
316 pub fn try_for_each_valid_idx<E, F: FnMut(usize) -> Result<(), E>>(
317 &self,
318 f: F,
319 ) -> Result<(), E> {
320 if self.null_count == self.len() {
321 return Ok(());
322 }
323 self.valid_indices().try_for_each(f)
324 }
325
326 #[inline]
328 pub fn inner(&self) -> &BooleanBuffer {
329 &self.buffer
330 }
331
332 #[inline]
334 pub fn into_inner(self) -> BooleanBuffer {
335 self.buffer
336 }
337
338 #[inline]
340 pub fn buffer(&self) -> &Buffer {
341 self.buffer.inner()
342 }
343
344 pub fn from_unsliced_buffer(buffer: impl Into<Buffer>, len: usize) -> Option<Self> {
348 let bb = BooleanBuffer::new(buffer.into(), 0, len);
349 let nb = NullBuffer::new(bb);
350 (nb.null_count() > 0).then_some(nb)
351 }
352
353 #[cfg(feature = "pool")]
355 pub fn claim(&self, pool: &dyn crate::MemoryPool) {
356 self.buffer.inner().claim(pool);
358 }
359}
360
361impl<'a> IntoIterator for &'a NullBuffer {
362 type Item = bool;
363 type IntoIter = BitIterator<'a>;
364
365 fn into_iter(self) -> Self::IntoIter {
366 self.buffer.iter()
367 }
368}
369
370impl From<BooleanBuffer> for NullBuffer {
371 fn from(value: BooleanBuffer) -> Self {
372 Self::new(value)
373 }
374}
375
376impl From<&[bool]> for NullBuffer {
377 fn from(value: &[bool]) -> Self {
378 BooleanBuffer::from(value).into()
379 }
380}
381
382impl<const N: usize> From<&[bool; N]> for NullBuffer {
383 fn from(value: &[bool; N]) -> Self {
384 value[..].into()
385 }
386}
387
388impl From<Vec<bool>> for NullBuffer {
389 fn from(value: Vec<bool>) -> Self {
390 BooleanBuffer::from(value).into()
391 }
392}
393
394impl FromIterator<bool> for NullBuffer {
395 fn from_iter<T: IntoIterator<Item = bool>>(iter: T) -> Self {
396 BooleanBuffer::from_iter(iter).into()
397 }
398}
399
400#[cfg(test)]
401mod tests {
402 use super::*;
403
404 #[test]
405 fn test_size() {
406 assert_eq!(
408 std::mem::size_of::<NullBuffer>(),
409 std::mem::size_of::<Option<NullBuffer>>()
410 );
411 }
412
413 #[test]
414 fn test_from_unsliced_buffer_with_nulls() {
415 let buf = Buffer::from([0b10110010u8]);
417 let result = NullBuffer::from_unsliced_buffer(buf, 8);
418 assert!(result.is_some());
419 let nb = result.unwrap();
420 assert_eq!(nb.len(), 8);
421 assert_eq!(nb.null_count(), 4);
422 assert!(nb.is_null(0));
423 assert!(nb.is_valid(1));
424 assert!(nb.is_null(2));
425 assert!(nb.is_null(3));
426 assert!(nb.is_valid(4));
427 assert!(nb.is_valid(5));
428 assert!(nb.is_null(6));
429 assert!(nb.is_valid(7));
430 }
431
432 #[test]
433 fn test_from_unsliced_buffer_all_valid() {
434 let buf = Buffer::from([0b11111111u8]);
436 let result = NullBuffer::from_unsliced_buffer(buf, 8);
437 assert!(result.is_none());
438 }
439
440 #[test]
441 fn test_from_unsliced_buffer_all_null() {
442 let buf = Buffer::from([0b00000000u8]);
444 let result = NullBuffer::from_unsliced_buffer(buf, 8);
445 assert!(result.is_some());
446 let nb = result.unwrap();
447 assert_eq!(nb.len(), 8);
448 assert_eq!(nb.null_count(), 8);
449 }
450
451 #[test]
452 fn test_from_unsliced_buffer_empty() {
453 let buf = Buffer::from([]);
454 let result = NullBuffer::from_unsliced_buffer(buf, 0);
455 assert!(result.is_none());
456 }
457
458 #[test]
459 fn test_union_many_all_none() {
460 let result = NullBuffer::union_many([None, None, None]);
461 assert!(result.is_none());
462 }
463
464 #[test]
465 fn test_union_many_single_some() {
466 let a = NullBuffer::from(&[true, false, true, true]);
467 let result = NullBuffer::union_many([Some(&a)]);
468 assert_eq!(result, Some(a));
469 }
470
471 #[test]
472 fn test_union_many_two_inputs() {
473 let a = NullBuffer::from(&[true, false, true, true]);
474 let b = NullBuffer::from(&[true, true, false, true]);
475 let result = NullBuffer::union_many([Some(&a), Some(&b)]);
476 let expected = NullBuffer::union(Some(&a), Some(&b));
477 assert_eq!(result, expected);
478 }
479
480 #[test]
481 fn test_union_many_three_inputs() {
482 let a = NullBuffer::from(&[true, false, true, true]);
483 let b = NullBuffer::from(&[true, true, false, true]);
484 let c = NullBuffer::from(&[false, true, true, true]);
485 let result = NullBuffer::union_many([Some(&a), Some(&b), Some(&c)]);
486 let expected = NullBuffer::from(&[false, false, false, true]);
487 assert_eq!(result, Some(expected));
488 }
489
490 #[test]
491 fn test_union_many_mixed_none() {
492 let a = NullBuffer::from(&[true, false, true, true]);
493 let b = NullBuffer::from(&[false, true, true, true]);
494 let result = NullBuffer::union_many([Some(&a), None, Some(&b)]);
495 let expected = NullBuffer::union(Some(&a), Some(&b));
496 assert_eq!(result, expected);
497 }
498
499 #[test]
500 fn test_union_many_empty_slice() {
501 let result = NullBuffer::union_many([] as [Option<&NullBuffer>; 0]);
502 assert!(result.is_none());
503 }
504
505 #[test]
506 fn test_union_many_no_nulls() {
507 let a = NullBuffer::from(&[true, true, true, true]);
508
509 let result = NullBuffer::union_many([Some(&a), Some(&a), Some(&a)]);
510 assert_eq!(result, None);
511 }
512
513 #[test]
514 fn test_union_no_nulls() {
515 let a = NullBuffer::from(&[true, true, true, true]);
516
517 let result = NullBuffer::union(Some(&a), Some(&a));
518 assert_eq!(result, None);
519
520 let result = NullBuffer::union(Some(&a), None);
521 assert_eq!(result, None);
522
523 let result = NullBuffer::union(None, Some(&a));
524 assert_eq!(result, None);
525 }
526
527 #[test]
528 fn test_union_nulls_one_side() {
529 let all_valid = NullBuffer::from(&[true, true, true, true]);
530 let all_null = NullBuffer::from(&[false, false, false, false]);
531
532 let result = NullBuffer::union(Some(&all_valid), Some(&all_null));
533 assert_eq!(result, Some(all_null.clone()));
534
535 let result = NullBuffer::union(Some(&all_null), Some(&all_valid));
536 assert_eq!(result, Some(all_null.clone()));
537 }
538
539 #[test]
540 fn test_expand_code_paths() {
541 let source = NullBuffer::from(&[true, false, true] as &[bool]);
542
543 for count in [8, 4, 3] {
544 let expanded = source.expand(count);
545 assert_eq!(expanded.len(), 3 * count);
546 assert_eq!(expanded.null_count(), count);
547 assert!((0..count).all(|i| expanded.is_valid(i)));
548 assert!((count..2 * count).all(|i| expanded.is_null(i)));
549 assert!((2 * count..3 * count).all(|i| expanded.is_valid(i)));
550 }
551 }
552}