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