vortex_array/arrays/bool/compute/
min_max.rs

1use std::ops::BitAnd;
2
3use vortex_error::VortexResult;
4use vortex_mask::Mask;
5use vortex_scalar::Scalar;
6
7use crate::arrays::{BoolArray, BoolVTable};
8use crate::compute::{MinMaxKernel, MinMaxKernelAdapter, MinMaxResult};
9use crate::register_kernel;
10
11impl MinMaxKernel for BoolVTable {
12    fn min_max(&self, array: &BoolArray) -> VortexResult<Option<MinMaxResult>> {
13        let x = match array.validity_mask()? {
14            Mask::AllTrue(_) => array.boolean_buffer().clone(),
15            Mask::AllFalse(_) => return Ok(None),
16            Mask::Values(v) => array.boolean_buffer().bitand(v.boolean_buffer()),
17        };
18
19        // TODO(ngates): we should be able to bail out earlier as soon as we have one true and
20        //  one false value.
21        let mut slices = x.set_slices();
22        // If there are no slices, then all values are false
23        // if there is a single slice that covers the entire array, then all values are true
24        // otherwise, we have a mix of true and false values
25
26        let Some(slice) = slices.next() else {
27            // all false
28            return Ok(Some(MinMaxResult {
29                min: Scalar::new(array.dtype().clone(), false.into()),
30                max: Scalar::new(array.dtype().clone(), false.into()),
31            }));
32        };
33        if slice.0 == 0 && slice.1 == x.len() {
34            // all true
35            return Ok(Some(MinMaxResult {
36                min: Scalar::new(array.dtype().clone(), true.into()),
37                max: Scalar::new(array.dtype().clone(), true.into()),
38            }));
39        };
40
41        Ok(Some(MinMaxResult {
42            min: Scalar::new(array.dtype().clone(), false.into()),
43            max: Scalar::new(array.dtype().clone(), true.into()),
44        }))
45    }
46}
47
48register_kernel!(MinMaxKernelAdapter(BoolVTable).lift());