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