vortex_array/arrays/varbin/compute/
min_max.rs

1use itertools::Itertools;
2use vortex_dtype::DType;
3use vortex_error::VortexResult;
4use vortex_scalar::Scalar;
5
6use crate::Array;
7use crate::accessor::ArrayAccessor;
8use crate::arrays::{VarBinArray, VarBinEncoding};
9use crate::compute::{MinMaxFn, MinMaxResult};
10
11impl MinMaxFn<&VarBinArray> for VarBinEncoding {
12    fn min_max(&self, array: &VarBinArray) -> VortexResult<Option<MinMaxResult>> {
13        compute_min_max(array, array.dtype())
14    }
15}
16
17/// Compute the min and max of VarBin like array.
18pub fn compute_min_max<T: ArrayAccessor<[u8]>>(
19    array: &T,
20    dtype: &DType,
21) -> VortexResult<Option<MinMaxResult>> {
22    let minmax = array.with_iterator(|iter| match iter.flatten().minmax() {
23        itertools::MinMaxResult::NoElements => None,
24        itertools::MinMaxResult::OneElement(value) => {
25            let scalar = Scalar::new(dtype.clone(), value.into());
26            Some(MinMaxResult {
27                min: scalar.clone(),
28                max: scalar,
29            })
30        }
31        itertools::MinMaxResult::MinMax(min, max) => Some(MinMaxResult {
32            min: Scalar::new(dtype.clone(), (*min).into()),
33            max: Scalar::new(dtype.clone(), (*max).into()),
34        }),
35    })?;
36
37    Ok(minmax)
38}
39
40#[cfg(test)]
41mod tests {
42    use vortex_buffer::BufferString;
43    use vortex_dtype::DType::Utf8;
44    use vortex_dtype::Nullability::Nullable;
45    use vortex_scalar::Scalar;
46
47    use crate::Array;
48    use crate::arrays::VarBinArray;
49    use crate::compute::{MinMaxResult, min_max};
50    use crate::stats::{Stat, StatsProvider};
51
52    #[test]
53    fn some_nulls() {
54        let array = VarBinArray::from_iter(
55            vec![
56                Some("hello world"),
57                None,
58                Some("hello world this is a long string"),
59                None,
60            ],
61            Utf8(Nullable),
62        );
63        let MinMaxResult { min, max } = min_max(&array).unwrap().unwrap();
64
65        assert_eq!(
66            min,
67            Scalar::new(
68                Utf8(Nullable),
69                BufferString::from("hello world".to_string()).into(),
70            )
71        );
72        assert_eq!(
73            max,
74            Scalar::new(
75                Utf8(Nullable),
76                BufferString::from("hello world this is a long string".to_string()).into()
77            )
78        );
79    }
80
81    #[test]
82    fn all_nulls() {
83        let array = VarBinArray::from_iter(vec![Option::<&str>::None, None, None], Utf8(Nullable));
84        let stats = array.statistics();
85        assert!(stats.get(Stat::Min).is_none());
86        assert!(stats.get(Stat::Max).is_none());
87    }
88}