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