| 792 | } |
| 793 | |
| 794 | fn logical_nulls(&self) -> Option<NullBuffer> { |
| 795 | let fields = match self.data_type() { |
| 796 | DataType::Union(fields, _) => fields, |
| 797 | _ => unreachable!(), |
| 798 | }; |
| 799 | |
| 800 | if fields.len() <= 1 { |
| 801 | return self.fields.iter().find_map(|field_opt| { |
| 802 | field_opt |
| 803 | .as_ref() |
| 804 | .and_then(|field| field.logical_nulls()) |
| 805 | .map(|logical_nulls| { |
| 806 | if self.is_dense() { |
| 807 | self.gather_nulls(vec![(0, logical_nulls)]).into() |
| 808 | } else { |
| 809 | logical_nulls |
| 810 | } |
| 811 | }) |
| 812 | }); |
| 813 | } |
| 814 | |
| 815 | let logical_nulls = self.fields_logical_nulls(); |
| 816 | |
| 817 | if logical_nulls.is_empty() { |
| 818 | return None; |
| 819 | } |
| 820 | |
| 821 | let fully_null_count = logical_nulls |
| 822 | .iter() |
| 823 | .filter(|(_, nulls)| nulls.null_count() == nulls.len()) |
| 824 | .count(); |
| 825 | |
| 826 | if fully_null_count == fields.len() { |
| 827 | if let Some((_, exactly_sized)) = logical_nulls |
| 828 | .iter() |
| 829 | .find(|(_, nulls)| nulls.len() == self.len()) |
| 830 | { |
| 831 | return Some(exactly_sized.clone()); |
| 832 | } |
| 833 | |
| 834 | if let Some((_, bigger)) = logical_nulls |
| 835 | .iter() |
| 836 | .find(|(_, nulls)| nulls.len() > self.len()) |
| 837 | { |
| 838 | return Some(bigger.slice(0, self.len())); |
| 839 | } |
| 840 | |
| 841 | return Some(NullBuffer::new_null(self.len())); |
| 842 | } |
| 843 | |
| 844 | let boolean_buffer = match &self.offsets { |
| 845 | Some(_) => self.gather_nulls(logical_nulls), |
| 846 | None => { |
| 847 | // Choose the fastest way to compute the logical nulls |
| 848 | // Gather computes one null per iteration, while the others work on 64 nulls chunks, |
| 849 | // but must also compute selection masks, which is expensive, |
| 850 | // so it's cost is the number of selection masks computed per chunk |
| 851 | // Since computing the selection mask gets auto-vectorized, it's performance depends on which simd feature is enabled |