vortex_array/arrays/bool/compute/
min_max.rs1use std::ops::BitAnd;
5
6use Nullability::NonNullable;
7use vortex_dtype::Nullability;
8use vortex_error::VortexResult;
9use vortex_mask::Mask;
10use vortex_scalar::Scalar;
11
12use crate::arrays::BoolArray;
13use crate::arrays::BoolVTable;
14use crate::compute::MinMaxKernel;
15use crate::compute::MinMaxKernelAdapter;
16use crate::compute::MinMaxResult;
17use crate::register_kernel;
18
19impl MinMaxKernel for BoolVTable {
20 fn min_max(&self, array: &BoolArray) -> VortexResult<Option<MinMaxResult>> {
21 let mask = array.validity_mask();
22 let true_non_null = match mask {
23 Mask::AllTrue(_) => array.bit_buffer().clone(),
24 Mask::AllFalse(_) => return Ok(None),
25 Mask::Values(ref v) => array.bit_buffer().bitand(v.bit_buffer()),
26 };
27
28 let mut true_slices = true_non_null.set_slices();
31 let Some(slice) = true_slices.next() else {
36 return Ok(Some(MinMaxResult {
38 min: Scalar::bool(false, NonNullable),
39 max: Scalar::bool(false, NonNullable),
40 }));
41 };
42 if slice.0 == 0 && slice.1 == array.len() {
43 return Ok(Some(MinMaxResult {
45 min: Scalar::bool(true, NonNullable),
46 max: Scalar::bool(true, NonNullable),
47 }));
48 };
49
50 match mask {
52 Mask::AllTrue(_) | Mask::AllFalse(_) => {}
54 Mask::Values(v) => {
55 let false_non_null = (!array.bit_buffer()).bitand(v.bit_buffer());
56 let mut false_slices = false_non_null.set_slices();
57
58 let Some(_) = false_slices.next() else {
59 return Ok(Some(MinMaxResult {
61 min: Scalar::bool(true, NonNullable),
62 max: Scalar::bool(true, NonNullable),
63 }));
64 };
65 }
66 }
67
68 Ok(Some(MinMaxResult {
69 min: Scalar::bool(false, NonNullable),
70 max: Scalar::bool(true, NonNullable),
71 }))
72 }
73}
74
75register_kernel!(MinMaxKernelAdapter(BoolVTable).lift());
76
77#[cfg(test)]
78mod tests {
79 use Nullability::NonNullable;
80 use vortex_dtype::Nullability;
81 use vortex_scalar::Scalar;
82
83 use crate::arrays::BoolArray;
84 use crate::compute::MinMaxResult;
85 use crate::compute::min_max;
86
87 #[test]
88 fn test_min_max_nulls() {
89 assert_eq!(
90 min_max(BoolArray::from_iter(vec![Some(true), Some(true), None, None]).as_ref())
91 .unwrap(),
92 Some(MinMaxResult {
93 min: Scalar::bool(true, NonNullable),
94 max: Scalar::bool(true, NonNullable),
95 })
96 );
97
98 assert_eq!(
99 min_max(BoolArray::from_iter(vec![None, Some(true), Some(true)]).as_ref()).unwrap(),
100 Some(MinMaxResult {
101 min: Scalar::bool(true, NonNullable),
102 max: Scalar::bool(true, NonNullable),
103 })
104 );
105
106 assert_eq!(
107 min_max(BoolArray::from_iter(vec![None, Some(true), Some(true), None]).as_ref())
108 .unwrap(),
109 Some(MinMaxResult {
110 min: Scalar::bool(true, NonNullable),
111 max: Scalar::bool(true, NonNullable),
112 })
113 );
114
115 assert_eq!(
116 min_max(BoolArray::from_iter(vec![Some(false), Some(false), None, None]).as_ref())
117 .unwrap(),
118 Some(MinMaxResult {
119 min: Scalar::bool(false, NonNullable),
120 max: Scalar::bool(false, NonNullable),
121 })
122 );
123 }
124}