use std::ops::BitAnd;
use Nullability::NonNullable;
use vortex_error::VortexResult;
use vortex_mask::Mask;
use crate::arrays::BoolArray;
use crate::arrays::BoolVTable;
use crate::compute::MinMaxKernel;
use crate::compute::MinMaxKernelAdapter;
use crate::compute::MinMaxResult;
use crate::dtype::Nullability;
use crate::register_kernel;
use crate::scalar::Scalar;
impl MinMaxKernel for BoolVTable {
fn min_max(&self, array: &BoolArray) -> VortexResult<Option<MinMaxResult>> {
let mask = array.validity_mask()?;
let true_non_null = match &mask {
Mask::AllTrue(_) => array.to_bit_buffer(),
Mask::AllFalse(_) => return Ok(None),
Mask::Values(v) => array.to_bit_buffer().bitand(v.bit_buffer()),
};
let mut true_slices = true_non_null.set_slices();
let Some(slice) = true_slices.next() else {
return Ok(Some(MinMaxResult {
min: Scalar::bool(false, NonNullable),
max: Scalar::bool(false, NonNullable),
}));
};
if slice.0 == 0 && slice.1 == array.len() {
return Ok(Some(MinMaxResult {
min: Scalar::bool(true, NonNullable),
max: Scalar::bool(true, NonNullable),
}));
};
match &mask {
Mask::AllTrue(_) | Mask::AllFalse(_) => {}
Mask::Values(v) => {
let false_non_null = (!array.to_bit_buffer()).bitand(v.bit_buffer());
let mut false_slices = false_non_null.set_slices();
let Some(_) = false_slices.next() else {
return Ok(Some(MinMaxResult {
min: Scalar::bool(true, NonNullable),
max: Scalar::bool(true, NonNullable),
}));
};
}
}
Ok(Some(MinMaxResult {
min: Scalar::bool(false, NonNullable),
max: Scalar::bool(true, NonNullable),
}))
}
}
register_kernel!(MinMaxKernelAdapter(BoolVTable).lift());
#[cfg(test)]
mod tests {
use Nullability::NonNullable;
use crate::IntoArray;
use crate::arrays::BoolArray;
use crate::compute::MinMaxResult;
use crate::compute::min_max;
use crate::dtype::Nullability;
use crate::scalar::Scalar;
#[test]
fn test_min_max_nulls() {
assert_eq!(
min_max(&BoolArray::from_iter(vec![Some(true), Some(true), None, None]).into_array())
.unwrap(),
Some(MinMaxResult {
min: Scalar::bool(true, NonNullable),
max: Scalar::bool(true, NonNullable),
})
);
assert_eq!(
min_max(&BoolArray::from_iter(vec![None, Some(true), Some(true)]).into_array())
.unwrap(),
Some(MinMaxResult {
min: Scalar::bool(true, NonNullable),
max: Scalar::bool(true, NonNullable),
})
);
assert_eq!(
min_max(&BoolArray::from_iter(vec![None, Some(true), Some(true), None]).into_array())
.unwrap(),
Some(MinMaxResult {
min: Scalar::bool(true, NonNullable),
max: Scalar::bool(true, NonNullable),
})
);
assert_eq!(
min_max(&BoolArray::from_iter(vec![Some(false), Some(false), None, None]).into_array())
.unwrap(),
Some(MinMaxResult {
min: Scalar::bool(false, NonNullable),
max: Scalar::bool(false, NonNullable),
})
);
}
}