vortex_array/arrays/chunked/compute/
is_constant.rs

1use vortex_error::{VortexExpect, VortexResult};
2
3use crate::arrays::{ChunkedArray, ChunkedVTable};
4use crate::compute::{IsConstantKernel, IsConstantKernelAdapter, IsConstantOpts, is_constant_opts};
5use crate::{Array, register_kernel};
6
7impl IsConstantKernel for ChunkedVTable {
8    fn is_constant(
9        &self,
10        array: &ChunkedArray,
11        opts: &IsConstantOpts,
12    ) -> VortexResult<Option<bool>> {
13        let mut chunks = array.chunks().iter().skip_while(|c| c.is_empty());
14
15        let first_chunk = chunks.next().vortex_expect("Must have at least one value");
16
17        match is_constant_opts(first_chunk, opts)? {
18            // Un-determined
19            None => return Ok(None),
20            Some(false) => return Ok(Some(false)),
21            Some(true) => {}
22        }
23
24        let first_value = first_chunk.scalar_at(0)?.into_nullable();
25
26        for chunk in chunks {
27            if chunk.is_empty() {
28                continue;
29            }
30
31            match is_constant_opts(chunk, opts)? {
32                // Un-determined
33                None => return Ok(None),
34                Some(false) => return Ok(Some(false)),
35                Some(true) => {}
36            }
37
38            if first_value != chunk.scalar_at(0)?.into_nullable() {
39                return Ok(Some(false));
40            }
41        }
42
43        Ok(Some(true))
44    }
45}
46
47register_kernel!(IsConstantKernelAdapter(ChunkedVTable).lift());
48
49#[cfg(test)]
50mod tests {
51    use vortex_buffer::{Buffer, buffer};
52    use vortex_dtype::{DType, Nullability, PType};
53
54    use crate::arrays::ChunkedArray;
55    use crate::{Array, IntoArray};
56
57    #[test]
58    fn empty_chunk_is_constant() {
59        let chunked = ChunkedArray::try_new(
60            vec![
61                Buffer::<u8>::empty().into_array(),
62                Buffer::<u8>::empty().into_array(),
63                buffer![255u8, 255].into_array(),
64                Buffer::<u8>::empty().into_array(),
65                buffer![255u8, 255].into_array(),
66            ],
67            DType::Primitive(PType::U8, Nullability::NonNullable),
68        )
69        .unwrap()
70        .into_array();
71
72        assert!(chunked.statistics().compute_is_constant().unwrap());
73    }
74}