vortex_array/arrays/chunked/compute/
is_constant.rs

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