Skip to content
This repository has been archived by the owner on Feb 18, 2024. It is now read-only.

Commit

Permalink
fix: correct for endiannes in leading ones compute (#1348)
Browse files Browse the repository at this point in the history
* fix: correct for endiannes in leading ones compute

* clippy
  • Loading branch information
ritchie46 authored Dec 30, 2022
1 parent 0dd5680 commit 26d1b11
Show file tree
Hide file tree
Showing 2 changed files with 32 additions and 3 deletions.
13 changes: 11 additions & 2 deletions src/compute/filter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,15 @@ use crate::{array::*, types::NativeType};
/// Function that can filter arbitrary arrays
pub type Filter<'a> = Box<dyn Fn(&dyn Array) -> Box<dyn Array> + 'a + Send + Sync>;

#[inline]
fn get_leading_ones(chunk: u64) -> u32 {
if cfg!(target_endian = "little") {
chunk.trailing_ones()
} else {
chunk.leading_ones()
}
}

/// # Safety
/// This assumes that the `mask_chunks` contains a number of set/true items equal
/// to `filter_count`
Expand All @@ -29,7 +38,7 @@ where
.zip(mask_chunks.by_ref())
.for_each(|(chunk, mask_chunk)| {
let ones = mask_chunk.count_ones();
let leading_ones = mask_chunk.leading_ones();
let leading_ones = get_leading_ones(mask_chunk);

if ones == leading_ones {
let size = leading_ones as usize;
Expand Down Expand Up @@ -91,7 +100,7 @@ where
.zip(mask_chunks.by_ref())
.for_each(|((chunk, validity_chunk), mask_chunk)| {
let ones = mask_chunk.count_ones();
let leading_ones = mask_chunk.leading_ones();
let leading_ones = get_leading_ones(mask_chunk);

if ones == leading_ones {
let size = leading_ones as usize;
Expand Down
22 changes: 21 additions & 1 deletion tests/it/compute/filter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,26 @@ fn array_slice() {
assert_eq!(expected, c.as_ref());
}

#[test]
fn array_large_filter_chunks() {
let len = 65usize;
let a = Int32Array::from_iter((0..(len as i32)).map(Some));

let init = vec![true, true, true, false, false, true];
let remaining = len - init.len();
let iter = init
.into_iter()
.chain(std::iter::repeat(false).take(remaining))
.map(Some);
let b = BooleanArray::from_iter(iter);

let c = filter(&a, &b).unwrap();

let expected = Int32Array::from_slice([0, 1, 2, 5]);

assert_eq!(expected, c.as_ref());
}

#[test]
fn array_low_density() {
// this test exercises the all 0's branch of the filter algorithm
Expand Down Expand Up @@ -71,7 +91,7 @@ fn string_array_simple() {
}

#[test]
fn primative_array_with_null() {
fn primitive_array_with_null() {
let a = Int32Array::from(&[Some(5), None]);
let b = BooleanArray::from_slice(vec![false, true]);
let c = filter(&a, &b).unwrap();
Expand Down

0 comments on commit 26d1b11

Please sign in to comment.