Skip to content
This repository has been archived by the owner on Feb 18, 2024. It is now read-only.

Commit

Permalink
Added support for min/max for decimal (#897)
Browse files Browse the repository at this point in the history
  • Loading branch information
jorgecarleitao committed Mar 9, 2022
1 parent 6ed716e commit 3f0983b
Show file tree
Hide file tree
Showing 4 changed files with 70 additions and 53 deletions.
2 changes: 2 additions & 0 deletions src/compute/aggregate/min_max.rs
Original file line number Diff line number Diff line change
Expand Up @@ -394,6 +394,7 @@ pub fn max(array: &dyn Array) -> Result<Box<dyn Scalar>> {
DataType::Float16 => unreachable!(),
DataType::Float32 => dyn_primitive!(f32, array, max_primitive),
DataType::Float64 => dyn_primitive!(f64, array, max_primitive),
DataType::Decimal(_, _) => dyn_primitive!(i128, array, max_primitive),
DataType::Utf8 => dyn_generic!(Utf8Array<i32>, Utf8Scalar<i32>, array, max_string),
DataType::LargeUtf8 => dyn_generic!(Utf8Array<i64>, Utf8Scalar<i64>, array, max_string),
DataType::Binary => dyn_generic!(BinaryArray<i32>, BinaryScalar<i32>, array, max_binary),
Expand Down Expand Up @@ -435,6 +436,7 @@ pub fn min(array: &dyn Array) -> Result<Box<dyn Scalar>> {
DataType::Float16 => unreachable!(),
DataType::Float32 => dyn_primitive!(f32, array, min_primitive),
DataType::Float64 => dyn_primitive!(f64, array, min_primitive),
DataType::Decimal(_, _) => dyn_primitive!(i128, array, min_primitive),
DataType::Utf8 => dyn_generic!(Utf8Array<i32>, Utf8Scalar<i32>, array, min_string),
DataType::LargeUtf8 => dyn_generic!(Utf8Array<i64>, Utf8Scalar<i64>, array, min_string),
DataType::Binary => dyn_generic!(BinaryArray<i32>, BinaryScalar<i32>, array, min_binary),
Expand Down
60 changes: 60 additions & 0 deletions src/compute/aggregate/simd/mod.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,63 @@
use super::SimdOrd;
use crate::types::simd::{i128x8, NativeSimd};

macro_rules! simd_ord_int {
($simd:tt, $type:ty) => {
impl SimdOrd<$type> for $simd {
const MIN: $type = <$type>::MIN;
const MAX: $type = <$type>::MAX;

#[inline]
fn max_element(self) -> $type {
self.0.iter().copied().fold(Self::MIN, <$type>::max)
}

#[inline]
fn min_element(self) -> $type {
self.0.iter().copied().fold(Self::MAX, <$type>::min)
}

#[inline]
fn max_lane(self, x: Self) -> Self {
let mut result = <$simd>::default();
result
.0
.iter_mut()
.zip(self.0.iter())
.zip(x.0.iter())
.for_each(|((a, b), c)| *a = (*b).max(*c));
result
}

#[inline]
fn min_lane(self, x: Self) -> Self {
let mut result = <$simd>::default();
result
.0
.iter_mut()
.zip(self.0.iter())
.zip(x.0.iter())
.for_each(|((a, b), c)| *a = (*b).min(*c));
result
}

#[inline]
fn new_min() -> Self {
Self([Self::MAX; <$simd>::LANES])
}

#[inline]
fn new_max() -> Self {
Self([Self::MIN; <$simd>::LANES])
}
}
};
}

pub(super) use simd_ord_int;

simd_ord_int!(i128x8, i128);

#[cfg(not(feature = "simd"))]
mod native;
#[cfg(not(feature = "simd"))]
Expand Down
54 changes: 1 addition & 53 deletions src/compute/aggregate/simd/native.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ use crate::types::simd::*;

use super::super::min_max::SimdOrd;
use super::super::sum::Sum;
use super::simd_ord_int;

macro_rules! simd_add {
($simd:tt, $type:ty, $lanes:expr, $add:tt) => {
Expand Down Expand Up @@ -53,59 +54,6 @@ simd_add!(i64x8, i64, 8, wrapping_add);
simd_add!(f32x16, f32, 16, add);
simd_add!(f64x8, f64, 8, add);

macro_rules! simd_ord_int {
($simd:tt, $type:ty) => {
impl SimdOrd<$type> for $simd {
const MIN: $type = <$type>::MIN;
const MAX: $type = <$type>::MAX;

#[inline]
fn max_element(self) -> $type {
self.0.iter().copied().fold(Self::MIN, <$type>::max)
}

#[inline]
fn min_element(self) -> $type {
self.0.iter().copied().fold(Self::MAX, <$type>::min)
}

#[inline]
fn max_lane(self, x: Self) -> Self {
let mut result = <$simd>::default();
result
.0
.iter_mut()
.zip(self.0.iter())
.zip(x.0.iter())
.for_each(|((a, b), c)| *a = (*b).max(*c));
result
}

#[inline]
fn min_lane(self, x: Self) -> Self {
let mut result = <$simd>::default();
result
.0
.iter_mut()
.zip(self.0.iter())
.zip(x.0.iter())
.for_each(|((a, b), c)| *a = (*b).min(*c));
result
}

#[inline]
fn new_min() -> Self {
Self([Self::MAX; <$simd>::LANES])
}

#[inline]
fn new_max() -> Self {
Self([Self::MIN; <$simd>::LANES])
}
}
};
}

macro_rules! simd_ord_float {
($simd:tt, $type:ty) => {
impl SimdOrd<$type> for $simd {
Expand Down
7 changes: 7 additions & 0 deletions tests/it/compute/aggregate/min_max.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,13 @@ fn test_primitive_min_max_1() {
assert_eq!(Some(5), max_primitive(&a));
}

#[test]
fn decimal() {
let a = Int128Array::from(&[None, None, Some(5), Some(2)]);
assert_eq!(Some(2), min_primitive(&a));
assert_eq!(Some(5), max_primitive(&a));
}

#[test]
fn min_max_f32() {
let a = Float32Array::from(&[None, None, Some(5.0), Some(2.0)]);
Expand Down

0 comments on commit 3f0983b

Please sign in to comment.