use crate::array::{Array, BooleanArray};
use crate::bitmap::{Bitmap, MutableBitmap};
use crate::datatypes::DataType;
use crate::scalar::BooleanScalar;
use super::utils::combine_validities;
fn assert_lengths(lhs: &BooleanArray, rhs: &BooleanArray) {
assert_eq!(
lhs.len(),
rhs.len(),
"lhs and rhs must have the same length"
);
}
pub(crate) fn binary_boolean_kernel<F>(
lhs: &BooleanArray,
rhs: &BooleanArray,
op: F,
) -> BooleanArray
where
F: Fn(&Bitmap, &Bitmap) -> Bitmap,
{
assert_lengths(lhs, rhs);
let validity = combine_validities(lhs.validity(), rhs.validity());
let left_buffer = lhs.values();
let right_buffer = rhs.values();
let values = op(left_buffer, right_buffer);
BooleanArray::new(DataType::Boolean, values, validity)
}
pub fn and(lhs: &BooleanArray, rhs: &BooleanArray) -> BooleanArray {
if lhs.null_count() == 0 && rhs.null_count() == 0 {
let left_buffer = lhs.values();
let right_buffer = rhs.values();
match (left_buffer.unset_bits(), right_buffer.unset_bits()) {
(0, 0) => {
assert_lengths(lhs, rhs);
return lhs.clone();
}
(l, _) if l == lhs.len() => {
assert_lengths(lhs, rhs);
return lhs.clone();
}
(_, r) if r == rhs.len() => {
assert_lengths(lhs, rhs);
return rhs.clone();
}
_ => {}
}
}
binary_boolean_kernel(lhs, rhs, |lhs, rhs| lhs & rhs)
}
pub fn or(lhs: &BooleanArray, rhs: &BooleanArray) -> BooleanArray {
if lhs.null_count() == 0 && rhs.null_count() == 0 {
let left_buffer = lhs.values();
let right_buffer = rhs.values();
match (left_buffer.unset_bits(), right_buffer.unset_bits()) {
(0, _) => {
assert_lengths(lhs, rhs);
return lhs.clone();
}
(_, 0) => {
assert_lengths(lhs, rhs);
return rhs.clone();
}
(l, r) if l == lhs.len() && r == rhs.len() => {
assert_lengths(lhs, rhs);
return rhs.clone();
}
_ => {}
}
}
binary_boolean_kernel(lhs, rhs, |lhs, rhs| lhs | rhs)
}
pub fn not(array: &BooleanArray) -> BooleanArray {
let values = !array.values();
let validity = array.validity().cloned();
BooleanArray::new(DataType::Boolean, values, validity)
}
pub fn is_null(input: &dyn Array) -> BooleanArray {
let len = input.len();
let values = match input.validity() {
None => MutableBitmap::from_len_zeroed(len).into(),
Some(buffer) => !buffer,
};
BooleanArray::new(DataType::Boolean, values, None)
}
pub fn is_not_null(input: &dyn Array) -> BooleanArray {
let values = match input.validity() {
None => {
let mut mutable = MutableBitmap::new();
mutable.extend_constant(input.len(), true);
mutable.into()
}
Some(buffer) => buffer.clone(),
};
BooleanArray::new(DataType::Boolean, values, None)
}
pub fn and_scalar(array: &BooleanArray, scalar: &BooleanScalar) -> BooleanArray {
match scalar.value() {
Some(true) => array.clone(),
Some(false) => {
let values = Bitmap::new_zeroed(array.len());
BooleanArray::new(DataType::Boolean, values, array.validity().cloned())
}
None => BooleanArray::new_null(DataType::Boolean, array.len()),
}
}
pub fn or_scalar(array: &BooleanArray, scalar: &BooleanScalar) -> BooleanArray {
match scalar.value() {
Some(true) => {
let mut values = MutableBitmap::new();
values.extend_constant(array.len(), true);
BooleanArray::new(DataType::Boolean, values.into(), array.validity().cloned())
}
Some(false) => array.clone(),
None => BooleanArray::new_null(DataType::Boolean, array.len()),
}
}
pub fn any(array: &BooleanArray) -> bool {
if array.is_empty() {
false
} else if array.null_count() > 0 {
array.into_iter().any(|v| v == Some(true))
} else {
let vals = array.values();
vals.unset_bits() != vals.len()
}
}
pub fn all(array: &BooleanArray) -> bool {
if array.is_empty() {
true
} else if array.null_count() > 0 {
!array.into_iter().any(|v| v == Some(false))
} else {
let vals = array.values();
vals.unset_bits() == 0
}
}