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)>)
| 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 | } |
no test coverage detected