Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 21 additions & 0 deletions encodings/fsst/src/kernel.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ use vortex_array::arrays::FilterArray;
use vortex_array::arrays::FilterVTable;
use vortex_array::arrays::VarBinVTable;
use vortex_array::compute::FilterKernel;
use vortex_array::compute::filter_preconditions;
use vortex_array::kernel::ExecuteParentKernel;
use vortex_array::kernel::ParentKernelSet;
use vortex_array::matchers::Exact;
Expand Down Expand Up @@ -37,6 +38,11 @@ impl ExecuteParentKernel<FSSTVTable> for FSSTFilterKernel {
_child_idx: usize,
_ctx: &mut ExecutionCtx,
) -> VortexResult<Option<ArrayRef>> {
// TODO(joe): add a pattern to adding checks to all filter impls
let mask = parent.filter_mask();
if let Some(array) = filter_preconditions(array.as_ref(), mask) {
return Ok(Some(array));
}
// TODO(ngates): pass execution context when we update the FilterKernel trait.
let filtered_codes =
FilterKernel::filter(&VarBinVTable, array.codes(), parent.filter_mask())?
Expand Down Expand Up @@ -214,4 +220,19 @@ mod tests {
assert_arrays_eq!(result.into_array(), expected);
Ok(())
}

#[test]
fn test_fsst_filter_all_true() -> VortexResult<()> {
let fsst_array = build_test_fsst_array();
assert_eq!(fsst_array.len(), 10);

let mask = Mask::new_true(10);

let filter_array = fsst_array.filter(mask)?;
let mut ctx = SESSION.create_execution_ctx();
let result = filter_array.execute::<Canonical>(&mut ctx)?.into_array();

assert_arrays_eq!(result, fsst_array);
Ok(())
}
}
26 changes: 18 additions & 8 deletions vortex-array/src/compute/filter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,22 @@ pub fn filter(array: &dyn Array, mask: &Mask) -> VortexResult<ArrayRef> {
Ok(array.filter(mask.clone())?.to_canonical()?.into_array())
}

/// The set of common preconditions that apply to all arrays.
pub fn filter_preconditions(array: &dyn Array, mask: &Mask) -> Option<ArrayRef> {
let true_count = mask.true_count();
// Fast-path for empty mask.
if true_count == 0 {
return Some(Canonical::empty(array.dtype()).into_array());
}

// Fast-path for full mask
if true_count == mask.len() {
return Some(array.to_array());
}

None
}

struct Filter;

impl ComputeFnVTable for Filter {
Expand All @@ -97,14 +113,8 @@ impl ComputeFnVTable for Filter {

let true_count = mask.true_count();

// Fast-path for empty mask.
if true_count == 0 {
return Ok(Canonical::empty(array.dtype()).into_array().into());
}

// Fast-path for full mask
if true_count == mask.len() {
return Ok(array.to_array().into());
if let Some(array) = filter_preconditions(array, mask) {
return Ok(array.into());
}

// If the entire array is null, then we only need to adjust the length of the array.
Expand Down
Loading