vortex_array/arrays/chunked/compute/
min_max.rs

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