vortex_array/arrays/bool/compute/
min_max.rs1use std::ops::BitAnd;
5
6use Nullability::NonNullable;
7use vortex_error::VortexResult;
8use vortex_mask::Mask;
9
10use crate::arrays::BoolArray;
11use crate::arrays::BoolVTable;
12use crate::compute::MinMaxKernel;
13use crate::compute::MinMaxKernelAdapter;
14use crate::compute::MinMaxResult;
15use crate::dtype::Nullability;
16use crate::register_kernel;
17use crate::scalar::Scalar;
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.to_bit_buffer(),
24 Mask::AllFalse(_) => return Ok(None),
25 Mask::Values(v) => array.to_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.to_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
81 use crate::IntoArray;
82 use crate::arrays::BoolArray;
83 use crate::compute::MinMaxResult;
84 use crate::compute::min_max;
85 use crate::dtype::Nullability;
86 use crate::scalar::Scalar;
87
88 #[test]
89 fn test_min_max_nulls() {
90 assert_eq!(
91 min_max(&BoolArray::from_iter(vec![Some(true), Some(true), None, None]).into_array())
92 .unwrap(),
93 Some(MinMaxResult {
94 min: Scalar::bool(true, NonNullable),
95 max: Scalar::bool(true, NonNullable),
96 })
97 );
98
99 assert_eq!(
100 min_max(&BoolArray::from_iter(vec![None, Some(true), Some(true)]).into_array())
101 .unwrap(),
102 Some(MinMaxResult {
103 min: Scalar::bool(true, NonNullable),
104 max: Scalar::bool(true, NonNullable),
105 })
106 );
107
108 assert_eq!(
109 min_max(&BoolArray::from_iter(vec![None, Some(true), Some(true), None]).into_array())
110 .unwrap(),
111 Some(MinMaxResult {
112 min: Scalar::bool(true, NonNullable),
113 max: Scalar::bool(true, NonNullable),
114 })
115 );
116
117 assert_eq!(
118 min_max(&BoolArray::from_iter(vec![Some(false), Some(false), None, None]).into_array())
119 .unwrap(),
120 Some(MinMaxResult {
121 min: Scalar::bool(false, NonNullable),
122 max: Scalar::bool(false, NonNullable),
123 })
124 );
125 }
126}