MCPcopy Create free account
hub / github.com/apache/arrow-rs / gather_nulls

Method gather_nulls

arrow-array/src/array/union_array.rs:608–667  ·  view source on GitHub ↗

Computes the logical nulls for a sparse or dense union, by gathering individual bits from the null buffer of the selected field

(&self, nulls: Vec<(i8, NullBuffer)>)

Source from the content-addressed store, hash-verified

606
607 /// Computes the logical nulls for a sparse or dense union, by gathering individual bits from the null buffer of the selected field
608 fn gather_nulls(&self, nulls: Vec<(i8, NullBuffer)>) -> BooleanBuffer {
609 let one_null = NullBuffer::new_null(1);
610 let one_valid = NullBuffer::new_valid(1);
611
612 // Unsafe code below depend on it:
613 // To remove one branch from the loop, if the a type_id is not utilized, or it's logical_nulls is None/all set,
614 // we use a null buffer of len 1 and a index_mask of 0, or the true null buffer and usize::MAX otherwise.
615 // We then unconditionally access the null buffer with index & index_mask,
616 // which always return 0 for the 1-len buffer, or the true index unchanged otherwise
617 // We also use a 256 array, so llvm knows that `type_id as u8 as usize` is always in bounds
618 let mut logical_nulls_array = [(&one_valid, Mask::Zero); 256];
619
620 for (type_id, nulls) in &nulls {
621 if nulls.null_count() == nulls.len() {
622 // Similarly, if all values are null, use a 1-null null-buffer to reduce cache pressure a bit
623 logical_nulls_array[*type_id as u8 as usize] = (&one_null, Mask::Zero);
624 } else {
625 logical_nulls_array[*type_id as u8 as usize] = (nulls, Mask::Max);
626 }
627 }
628
629 match &self.offsets {
630 Some(offsets) => {
631 assert_eq!(self.type_ids.len(), offsets.len());
632
633 BooleanBuffer::collect_bool(self.type_ids.len(), |i| unsafe {
634 // SAFETY: BooleanBuffer::collect_bool calls us 0..self.type_ids.len()
635 let type_id = *self.type_ids.get_unchecked(i);
636 // SAFETY: We asserted that offsets len and self.type_ids len are equal
637 let offset = *offsets.get_unchecked(i);
638
639 let (nulls, offset_mask) = &logical_nulls_array[type_id as u8 as usize];
640
641 // SAFETY:
642 // If offset_mask is Max
643 // 1. Offset validity is checked at union creation
644 // 2. If the null buffer len equals it's array len is checked at array creation
645 // If offset_mask is Zero, the null buffer len is 1
646 nulls
647 .inner()
648 .value_unchecked(offset as usize & *offset_mask as usize)
649 })
650 }
651 None => {
652 BooleanBuffer::collect_bool(self.type_ids.len(), |index| unsafe {
653 // SAFETY: BooleanBuffer::collect_bool calls us 0..self.type_ids.len()
654 let type_id = *self.type_ids.get_unchecked(index);
655
656 let (nulls, index_mask) = &logical_nulls_array[type_id as u8 as usize];
657
658 // SAFETY:
659 // If index_mask is Max
660 // 1. On sparse union, every child len match it's parent, this is checked at union creation
661 // 2. If the null buffer len equals it's array len is checked at array creation
662 // If index_mask is Zero, the null buffer len is 1
663 nulls.inner().value_unchecked(index & *index_mask as usize)
664 })
665 }

Callers 1

logical_nullsMethod · 0.80

Calls 5

collect_boolFunction · 0.85
null_countMethod · 0.45
lenMethod · 0.45
value_uncheckedMethod · 0.45
innerMethod · 0.45

Tested by

no test coverage detected