use crate::array::{Array, BooleanArray};
use crate::bitmap::{Bitmap, MutableBitmap};
use crate::datatypes::DataType;
use crate::error::{ArrowError, Result};
use crate::scalar::BooleanScalar;
use super::utils::combine_validities;
fn binary_boolean_kernel<F>(lhs: &BooleanArray, rhs: &BooleanArray, op: F) -> Result<BooleanArray>
where
F: Fn(&Bitmap, &Bitmap) -> Bitmap,
{
if lhs.len() != rhs.len() {
return Err(ArrowError::InvalidArgumentError(
"Cannot perform bitwise operation on arrays of different length".to_string(),
));
}
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);
Ok(BooleanArray::from_data(DataType::Boolean, values, validity))
}
pub fn and(lhs: &BooleanArray, rhs: &BooleanArray) -> Result<BooleanArray> {
binary_boolean_kernel(lhs, rhs, |lhs, rhs| lhs & rhs)
}
pub fn or(lhs: &BooleanArray, rhs: &BooleanArray) -> Result<BooleanArray> {
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::from_data(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::from_data(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::from_data(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::from_data(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::from_data(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.validity().is_some() {
array.into_iter().any(|v| v == Some(true))
} else {
let vals = array.values();
vals.null_count() != vals.len()
}
}
pub fn all(array: &BooleanArray) -> bool {
if array.is_empty() || array.null_count() > 0 {
false
} else {
let vals = array.values();
vals.null_count() == 0
}
}