Skip to content

Commit

Permalink
implement binary_boolean for chunked encoding (#1532)
Browse files Browse the repository at this point in the history
Close #1443
  • Loading branch information
doki23 authored Dec 5, 2024
1 parent ff8cd91 commit 8e754ad
Show file tree
Hide file tree
Showing 5 changed files with 55 additions and 17 deletions.
56 changes: 43 additions & 13 deletions vortex-array/src/array/chunked/compute/boolean.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
use vortex_dtype::{DType, Nullability};
use vortex_dtype::DType;
use vortex_error::VortexResult;

use crate::array::{ChunkedArray, ChunkedEncoding};
use crate::compute::{and, and_kleene, or, or_kleene, slice, BinaryBooleanFn, BinaryOperator};
use crate::{ArrayData, IntoArrayData};
use crate::compute::{binary_boolean, slice, BinaryBooleanFn, BinaryOperator};
use crate::{ArrayDType, ArrayData, IntoArrayData};

impl BinaryBooleanFn<ChunkedArray> for ChunkedEncoding {
fn binary_boolean(
Expand All @@ -17,18 +17,48 @@ impl BinaryBooleanFn<ChunkedArray> for ChunkedEncoding {

for chunk in lhs.chunks() {
let sliced = slice(rhs, idx, idx + chunk.len())?;
let result = match op {
BinaryOperator::And => and(&chunk, &sliced),
BinaryOperator::AndKleene => and_kleene(&chunk, &sliced),
BinaryOperator::Or => or(&chunk, &sliced),
BinaryOperator::OrKleene => or_kleene(&chunk, &sliced),
};
chunks.push(result?);
let result = binary_boolean(&chunk, &sliced, op)?;
chunks.push(result);
idx += chunk.len();
}

Ok(Some(
ChunkedArray::try_new(chunks, DType::Bool(Nullability::Nullable))?.into_array(),
))
let nullable = lhs.dtype().is_nullable() || rhs.dtype().is_nullable();
let dtype = DType::Bool(nullable.into());
Ok(Some(ChunkedArray::try_new(chunks, dtype)?.into_array()))
}
}

#[cfg(test)]
mod tests {
use vortex_dtype::{DType, Nullability};

use crate::array::{BoolArray, ChunkedArray};
use crate::compute::{binary_boolean, BinaryOperator};
use crate::{IntoArrayData, IntoArrayVariant};

#[test]
fn test_bin_bool_chunked() {
let arr0 = BoolArray::from_iter(vec![true, false]).into_array();
let arr1 = BoolArray::from_iter(vec![false, false, true]).into_array();
let chunked1 =
ChunkedArray::try_new(vec![arr0, arr1], DType::Bool(Nullability::NonNullable)).unwrap();

let arr2 = BoolArray::from_iter(vec![Some(false), Some(true)]).into_array();
let arr3 = BoolArray::from_iter(vec![Some(false), None, Some(false)]).into_array();
let chunked2 =
ChunkedArray::try_new(vec![arr2, arr3], DType::Bool(Nullability::Nullable)).unwrap();

assert_eq!(
binary_boolean(
&chunked1.into_array(),
&chunked2.into_array(),
BinaryOperator::Or
)
.unwrap()
.into_bool()
.unwrap()
.boolean_buffer(),
vec![true, true, false, false, true].into()
);
}
}
1 change: 1 addition & 0 deletions vortex-array/src/array/chunked/compute/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ impl ComputeVTable for ChunkedEncoding {
fn scalar_at_fn(&self) -> Option<&dyn ScalarAtFn<ArrayData>> {
Some(self)
}

fn slice_fn(&self) -> Option<&dyn SliceFn<ArrayData>> {
Some(self)
}
Expand Down
6 changes: 5 additions & 1 deletion vortex-array/src/compute/boolean.rs
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,11 @@ pub fn or_kleene(
binary_boolean(lhs.as_ref(), rhs.as_ref(), BinaryOperator::OrKleene)
}

fn binary_boolean(lhs: &ArrayData, rhs: &ArrayData, op: BinaryOperator) -> VortexResult<ArrayData> {
pub fn binary_boolean(
lhs: &ArrayData,
rhs: &ArrayData,
op: BinaryOperator,
) -> VortexResult<ArrayData> {
if lhs.len() != rhs.len() {
vortex_bail!("Boolean operations aren't supported on arrays of different lengths")
}
Expand Down
4 changes: 3 additions & 1 deletion vortex-array/src/compute/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,9 @@
//! implementations of these operators, else we will decode, and perform the equivalent operator
//! from Arrow.
pub use boolean::{and, and_kleene, or, or_kleene, BinaryBooleanFn, BinaryOperator};
pub use boolean::{
and, and_kleene, binary_boolean, or, or_kleene, BinaryBooleanFn, BinaryOperator,
};
pub use cast::{try_cast, CastFn};
pub use compare::{compare, scalar_cmp, CompareFn, Operator};
pub use fill_forward::{fill_forward, FillForwardFn};
Expand Down
5 changes: 3 additions & 2 deletions vortex-array/src/macros.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,8 @@ impl<A: AsRef<ArrayData>> ToArrayData for A {

/// Macro to generate all the necessary code for a new type of array encoding. Including:
/// 1. New Array type that implements `AsRef<ArrayData>`, `GetArrayMetadata`, `ToArray`, `IntoArray`, and multiple useful `From`/`TryFrom` implementations.
/// 1. New Encoding type that implements `ArrayEncoding`.
/// 1. New metadata type that implements `ArrayMetadata`.
/// 2. New Encoding type that implements `ArrayEncoding`.
/// 3. New metadata type that implements `ArrayMetadata`.
#[macro_export]
macro_rules! impl_encoding {
($id:literal, $code:expr, $Name:ident) => {
Expand All @@ -26,6 +26,7 @@ macro_rules! impl_encoding {
self.0
}
}

impl AsRef<$crate::ArrayData> for [<$Name Array>] {
fn as_ref(&self) -> &$crate::ArrayData {
&self.0
Expand Down

0 comments on commit 8e754ad

Please sign in to comment.