use crate::compute::comparison::{finish_eq_validities, finish_neq_validities};
use crate::{
array::BooleanArray,
bitmap::{binary, unary, Bitmap},
datatypes::DataType,
};
use super::super::utils::combine_validities;
fn compare_op<F>(lhs: &BooleanArray, rhs: &BooleanArray, op: F) -> BooleanArray
where
F: Fn(u64, u64) -> u64,
{
assert_eq!(lhs.len(), rhs.len());
let validity = combine_validities(lhs.validity(), rhs.validity());
let values = binary(lhs.values(), rhs.values(), op);
BooleanArray::new(DataType::Boolean, values, validity)
}
pub fn compare_op_scalar<F>(lhs: &BooleanArray, rhs: bool, op: F) -> BooleanArray
where
F: Fn(u64, u64) -> u64,
{
let rhs = if rhs { !0 } else { 0 };
let values = unary(lhs.values(), |x| op(x, rhs));
BooleanArray::new(DataType::Boolean, values, lhs.validity().cloned())
}
pub fn eq(lhs: &BooleanArray, rhs: &BooleanArray) -> BooleanArray {
compare_op(lhs, rhs, |a, b| !(a ^ b))
}
pub fn eq_and_validity(lhs: &BooleanArray, rhs: &BooleanArray) -> BooleanArray {
let validity_lhs = lhs.validity().cloned();
let validity_rhs = rhs.validity().cloned();
let lhs = lhs.clone().with_validity(None);
let rhs = rhs.clone().with_validity(None);
let out = compare_op(&lhs, &rhs, |a, b| !(a ^ b));
finish_eq_validities(out, validity_lhs, validity_rhs)
}
pub fn eq_scalar(lhs: &BooleanArray, rhs: bool) -> BooleanArray {
if rhs {
lhs.clone()
} else {
compare_op_scalar(lhs, rhs, |a, _| !a)
}
}
pub fn eq_scalar_and_validity(lhs: &BooleanArray, rhs: bool) -> BooleanArray {
let validity = lhs.validity().cloned();
let lhs = lhs.clone().with_validity(None);
if rhs {
finish_eq_validities(lhs, validity, None)
} else {
let lhs = lhs.with_validity(None);
let out = compare_op_scalar(&lhs, rhs, |a, _| !a);
finish_eq_validities(out, validity, None)
}
}
pub fn neq(lhs: &BooleanArray, rhs: &BooleanArray) -> BooleanArray {
compare_op(lhs, rhs, |a, b| a ^ b)
}
pub fn neq_and_validity(lhs: &BooleanArray, rhs: &BooleanArray) -> BooleanArray {
let validity_lhs = lhs.validity().cloned();
let validity_rhs = rhs.validity().cloned();
let lhs = lhs.clone().with_validity(None);
let rhs = rhs.clone().with_validity(None);
let out = compare_op(&lhs, &rhs, |a, b| a ^ b);
finish_neq_validities(out, validity_lhs, validity_rhs)
}
pub fn neq_scalar(lhs: &BooleanArray, rhs: bool) -> BooleanArray {
eq_scalar(lhs, !rhs)
}
pub fn neq_scalar_and_validity(lhs: &BooleanArray, rhs: bool) -> BooleanArray {
let validity = lhs.validity().cloned();
let lhs = lhs.clone().with_validity(None);
let out = eq_scalar(&lhs, !rhs);
finish_neq_validities(out, validity, None)
}
pub fn lt(lhs: &BooleanArray, rhs: &BooleanArray) -> BooleanArray {
compare_op(lhs, rhs, |a, b| !a & b)
}
pub fn lt_scalar(lhs: &BooleanArray, rhs: bool) -> BooleanArray {
if rhs {
compare_op_scalar(lhs, rhs, |a, _| !a)
} else {
BooleanArray::new(
DataType::Boolean,
Bitmap::new_zeroed(lhs.len()),
lhs.validity().cloned(),
)
}
}
pub fn lt_eq(lhs: &BooleanArray, rhs: &BooleanArray) -> BooleanArray {
compare_op(lhs, rhs, |a, b| !a | b)
}
pub fn lt_eq_scalar(lhs: &BooleanArray, rhs: bool) -> BooleanArray {
if rhs {
let all_ones = !0;
compare_op_scalar(lhs, rhs, |_, _| all_ones)
} else {
compare_op_scalar(lhs, rhs, |a, _| !a)
}
}
pub fn gt(lhs: &BooleanArray, rhs: &BooleanArray) -> BooleanArray {
compare_op(lhs, rhs, |a, b| a & !b)
}
pub fn gt_scalar(lhs: &BooleanArray, rhs: bool) -> BooleanArray {
if rhs {
BooleanArray::new(
DataType::Boolean,
Bitmap::new_zeroed(lhs.len()),
lhs.validity().cloned(),
)
} else {
lhs.clone()
}
}
pub fn gt_eq(lhs: &BooleanArray, rhs: &BooleanArray) -> BooleanArray {
compare_op(lhs, rhs, |a, b| a | !b)
}
pub fn gt_eq_scalar(lhs: &BooleanArray, rhs: bool) -> BooleanArray {
if rhs {
lhs.clone()
} else {
let all_ones = !0;
compare_op_scalar(lhs, rhs, |_, _| all_ones)
}
}