vortex_array/arrays/chunked/compute/
min_max.rs

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