use crate::datatypes::DataType;
use crate::error::{ArrowError, Result};
use crate::{
array::{Array, BooleanArray},
bitmap::{quaternary, ternary},
};
pub fn or(lhs: &BooleanArray, rhs: &BooleanArray) -> Result<BooleanArray> {
if lhs.len() != rhs.len() {
return Err(ArrowError::InvalidArgumentError(
"Cannot perform bitwise operation on arrays of different length".to_string(),
));
}
let lhs_values = lhs.values();
let rhs_values = rhs.values();
let lhs_validity = lhs.validity();
let rhs_validity = rhs.validity();
let validity = match (lhs_validity, rhs_validity) {
(Some(lhs_validity), Some(rhs_validity)) => {
Some(quaternary(
lhs_values,
rhs_values,
lhs_validity,
rhs_validity,
|lhs, rhs, lhs_v, rhs_v| {
(lhs & lhs_v) |
(rhs & rhs_v) |
(!lhs & lhs_v) & (!rhs & rhs_v)
},
))
}
(Some(lhs_validity), None) => {
Some(ternary(
lhs_values,
rhs_values,
lhs_validity,
|lhs, rhs, lhs_v| {
(lhs & lhs_v) |
rhs |
(!lhs & lhs_v) & !rhs
},
))
}
(None, Some(rhs_validity)) => {
Some(ternary(
lhs_values,
rhs_values,
rhs_validity,
|lhs, rhs, rhs_v| {
lhs |
(rhs & rhs_v) |
!lhs & (!rhs & rhs_v)
},
))
}
(None, None) => None,
};
Ok(BooleanArray::from_data(
DataType::Boolean,
lhs_values | rhs_values,
validity,
))
}
pub fn and(lhs: &BooleanArray, rhs: &BooleanArray) -> Result<BooleanArray> {
if lhs.len() != rhs.len() {
return Err(ArrowError::InvalidArgumentError(
"Cannot perform bitwise operation on arrays of different length".to_string(),
));
}
let lhs_values = lhs.values();
let rhs_values = rhs.values();
let lhs_validity = lhs.validity();
let rhs_validity = rhs.validity();
let validity = match (lhs_validity, rhs_validity) {
(Some(lhs_validity), Some(rhs_validity)) => {
Some(quaternary(
lhs_values,
rhs_values,
lhs_validity,
rhs_validity,
|lhs, rhs, lhs_v, rhs_v| {
(!rhs & rhs_v) |
(!lhs & lhs_v) |
(lhs & lhs_v) & (rhs & rhs_v)
},
))
}
(Some(lhs_validity), None) => {
Some(ternary(
lhs_values,
rhs_values,
lhs_validity,
|lhs, rhs, lhs_v| {
!rhs |
(!lhs & lhs_v) |
(lhs & lhs_v) & rhs
},
))
}
(None, Some(rhs_validity)) => {
Some(ternary(
lhs_values,
rhs_values,
rhs_validity,
|lhs, rhs, rhs_v| {
(!rhs & rhs_v) |
!lhs |
lhs & (rhs & rhs_v)
},
))
}
(None, None) => None,
};
Ok(BooleanArray::from_data(
DataType::Boolean,
lhs_values & rhs_values,
validity,
))
}