vortex_array/arrays/bool/compute/
is_constant.rs

1use vortex_error::VortexResult;
2
3use crate::arrays::{BoolArray, BoolEncoding};
4use crate::compute::{IsConstantFn, IsConstantOpts};
5
6impl IsConstantFn<&BoolArray> for BoolEncoding {
7    fn is_constant(&self, array: &BoolArray, _opts: &IsConstantOpts) -> VortexResult<Option<bool>> {
8        let buffer = array.boolean_buffer();
9
10        // Safety:
11        // We must have at least one value at this point
12        let first_value = unsafe { buffer.value_unchecked(0) };
13        let value_block = if first_value { u64::MAX } else { 0_u64 };
14
15        let bit_chunks = buffer.bit_chunks();
16        let packed = bit_chunks.iter().all(|chunk| chunk == value_block);
17        let reminder = bit_chunks.remainder_bits().count_ones() as usize
18            == bit_chunks.remainder_len() * (first_value as usize);
19
20        // We iterate on blocks of u64
21        Ok(Some(packed & reminder))
22    }
23}
24
25#[cfg(test)]
26mod tests {
27    use rstest::rstest;
28
29    use super::*;
30
31    #[rstest]
32    #[case(vec![true], Some(true))]
33    #[case(vec![false; 65], Some(true))]
34    #[case({
35        let mut v = vec![true; 64];
36        v.push(false);
37        v
38    }, Some(false))]
39    fn test_is_constant(#[case] input: Vec<bool>, #[case] expected: Option<bool>) {
40        let array = BoolArray::from_iter(input);
41
42        let output = BoolEncoding
43            .is_constant(&array, &IsConstantOpts::default())
44            .unwrap();
45        assert_eq!(output, expected);
46    }
47}