vortex_array/arrays/chunked/compute/
min_max.rs1use vortex_error::{VortexResult, vortex_err};
5use vortex_scalar::Scalar;
6
7use crate::arrays::{ChunkedArray, ChunkedVTable};
8use crate::compute::{MinMaxKernel, MinMaxKernelAdapter, MinMaxResult, min_max};
9use crate::partial_ord::{partial_max, partial_min};
10use crate::register_kernel;
11
12impl MinMaxKernel for ChunkedVTable {
13 fn min_max(&self, array: &ChunkedArray) -> VortexResult<Option<MinMaxResult>> {
14 let mut min_max_all_null = true;
15 let res = array
16 .array_iterator()
17 .map(|chunk| {
18 let chunk = chunk?;
19 if let Some(min_max) = min_max(&chunk)? {
20 min_max_all_null = false;
21 Ok((Some(min_max.min), Some(min_max.max)))
22 } else {
23 Ok((None, None))
24 }
25 })
26 .collect::<VortexResult<Vec<_>>>()?;
27
28 if min_max_all_null {
30 return Ok(None);
31 }
32
33 let (min_values, max_values): (Vec<Option<Scalar>>, Vec<Option<Scalar>>) =
34 res.into_iter().unzip();
35
36 Ok(Some(MinMaxResult {
37 min: min_values
38 .into_iter()
39 .flatten()
40 .fold(None, |acc, x| {
42 if let Some(acc) = acc {
43 partial_min(x, acc)
44 } else {
45 Some(x)
46 }
47 })
48 .ok_or_else(|| {
49 vortex_err!("Incomparable scalars (from partial_min), this is likely a bug",)
50 })?,
51 max: max_values
52 .into_iter()
53 .flatten()
54 .fold(None, |acc, x| {
55 if let Some(acc) = acc {
56 partial_max(x, acc)
57 } else {
58 Some(x)
59 }
60 })
61 .ok_or_else(|| vortex_err!("Incomparable scalars, this is likely a bug"))?,
62 }))
63 }
64}
65
66register_kernel!(MinMaxKernelAdapter(ChunkedVTable).lift());