use super::utils::combine_validities;
use crate::compute::arithmetics::basic::check_same_len;
use crate::{
array::{Array, PrimitiveArray},
bitmap::{Bitmap, MutableBitmap},
buffer::Buffer,
datatypes::DataType,
error::Result,
types::NativeType,
};
#[inline]
pub fn unary<I, F, O>(array: &PrimitiveArray<I>, op: F, data_type: DataType) -> PrimitiveArray<O>
where
I: NativeType,
O: NativeType,
F: Fn(I) -> O,
{
let values = array.values().iter().map(|v| op(*v));
let values = Buffer::from_trusted_len_iter(values);
PrimitiveArray::<O>::from_data(data_type, values, array.validity().cloned())
}
pub fn try_unary<I, F, O>(
array: &PrimitiveArray<I>,
op: F,
data_type: DataType,
) -> Result<PrimitiveArray<O>>
where
I: NativeType,
O: NativeType,
F: Fn(I) -> Result<O>,
{
let values = array.values().iter().map(|v| op(*v));
let values = Buffer::try_from_trusted_len_iter(values)?;
Ok(PrimitiveArray::<O>::from_data(
data_type,
values,
array.validity().cloned(),
))
}
pub fn unary_with_bitmap<I, F, O>(
array: &PrimitiveArray<I>,
op: F,
data_type: DataType,
) -> (PrimitiveArray<O>, Bitmap)
where
I: NativeType,
O: NativeType,
F: Fn(I) -> (O, bool),
{
let mut mut_bitmap = MutableBitmap::with_capacity(array.len());
let values = array.values().iter().map(|v| {
let (res, over) = op(*v);
mut_bitmap.push(over);
res
});
let values = Buffer::from_trusted_len_iter(values);
(
PrimitiveArray::<O>::from_data(data_type, values, array.validity().cloned()),
mut_bitmap.into(),
)
}
pub fn unary_checked<I, F, O>(
array: &PrimitiveArray<I>,
op: F,
data_type: DataType,
) -> PrimitiveArray<O>
where
I: NativeType,
O: NativeType,
F: Fn(I) -> Option<O>,
{
let mut mut_bitmap = MutableBitmap::with_capacity(array.len());
let values = array.values().iter().map(|v| match op(*v) {
Some(val) => {
mut_bitmap.push(true);
val
}
None => {
mut_bitmap.push(false);
O::default()
}
});
let values = Buffer::from_trusted_len_iter(values);
let bitmap: Bitmap = mut_bitmap.into();
let validity = combine_validities(array.validity(), Some(&bitmap));
PrimitiveArray::<O>::from_data(data_type, values, validity)
}
#[inline]
pub fn binary<T, D, F>(
lhs: &PrimitiveArray<T>,
rhs: &PrimitiveArray<D>,
data_type: DataType,
op: F,
) -> Result<PrimitiveArray<T>>
where
T: NativeType,
D: NativeType,
F: Fn(T, D) -> T,
{
check_same_len(lhs, rhs)?;
let validity = combine_validities(lhs.validity(), rhs.validity());
let values = lhs
.values()
.iter()
.zip(rhs.values().iter())
.map(|(l, r)| op(*l, *r));
let values = Buffer::from_trusted_len_iter(values);
Ok(PrimitiveArray::<T>::from_data(data_type, values, validity))
}
pub fn try_binary<T, D, F>(
lhs: &PrimitiveArray<T>,
rhs: &PrimitiveArray<D>,
data_type: DataType,
op: F,
) -> Result<PrimitiveArray<T>>
where
T: NativeType,
D: NativeType,
F: Fn(T, D) -> Result<T>,
{
check_same_len(lhs, rhs)?;
let validity = combine_validities(lhs.validity(), rhs.validity());
let values = lhs
.values()
.iter()
.zip(rhs.values().iter())
.map(|(l, r)| op(*l, *r));
let values = Buffer::try_from_trusted_len_iter(values)?;
Ok(PrimitiveArray::<T>::from_data(data_type, values, validity))
}
pub fn binary_with_bitmap<T, D, F>(
lhs: &PrimitiveArray<T>,
rhs: &PrimitiveArray<D>,
data_type: DataType,
op: F,
) -> Result<(PrimitiveArray<T>, Bitmap)>
where
T: NativeType,
D: NativeType,
F: Fn(T, D) -> (T, bool),
{
check_same_len(lhs, rhs)?;
let validity = combine_validities(lhs.validity(), rhs.validity());
let mut mut_bitmap = MutableBitmap::with_capacity(lhs.len());
let values = lhs.values().iter().zip(rhs.values().iter()).map(|(l, r)| {
let (res, over) = op(*l, *r);
mut_bitmap.push(over);
res
});
let values = Buffer::from_trusted_len_iter(values);
Ok((
PrimitiveArray::<T>::from_data(data_type, values, validity),
mut_bitmap.into(),
))
}
pub fn binary_checked<T, D, F>(
lhs: &PrimitiveArray<T>,
rhs: &PrimitiveArray<D>,
data_type: DataType,
op: F,
) -> Result<PrimitiveArray<T>>
where
T: NativeType,
D: NativeType,
F: Fn(T, D) -> Option<T>,
{
check_same_len(lhs, rhs)?;
let mut mut_bitmap = MutableBitmap::with_capacity(lhs.len());
let values = lhs
.values()
.iter()
.zip(rhs.values().iter())
.map(|(l, r)| match op(*l, *r) {
Some(val) => {
mut_bitmap.push(true);
val
}
None => {
mut_bitmap.push(false);
T::default()
}
});
let values = Buffer::from_trusted_len_iter(values);
let bitmap: Bitmap = mut_bitmap.into();
let validity = combine_validities(lhs.validity(), rhs.validity());
let validity = combine_validities(validity.as_ref(), Some(&bitmap));
Ok(PrimitiveArray::<T>::from_data(data_type, values, validity))
}