-
Notifications
You must be signed in to change notification settings - Fork 130
chore: implement Filter for new MaskIndices type for all vectors #5333
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -4,12 +4,12 @@ | |
| use vortex_buffer::{Buffer, BufferMut}; | ||
| use vortex_mask::{Mask, MaskIter}; | ||
|
|
||
| use crate::filter::Filter; | ||
| use crate::filter::{Filter, MaskIndices}; | ||
|
|
||
| // This is modeled after the constant with the equivalent name in arrow-rs. | ||
| const FILTER_SLICES_SELECTIVITY_THRESHOLD: f64 = 0.8; | ||
|
|
||
| impl<T: Copy> Filter for &Buffer<T> { | ||
| impl<T: Copy> Filter<Mask> for &Buffer<T> { | ||
| type Output = Buffer<T>; | ||
|
|
||
| fn filter(self, selection_mask: &Mask) -> Buffer<T> { | ||
|
|
@@ -32,7 +32,15 @@ impl<T: Copy> Filter for &Buffer<T> { | |
| } | ||
| } | ||
|
|
||
| impl<T: Copy> Filter for &mut BufferMut<T> { | ||
| impl<T: Copy> Filter<MaskIndices<'_>> for &Buffer<T> { | ||
| type Output = Buffer<T>; | ||
|
|
||
| fn filter(self, indices: &MaskIndices) -> Buffer<T> { | ||
| filter_indices(self, indices) | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. assert that the lengths are the same?
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. the lengths won't be the same b/c it's an indices |
||
| } | ||
| } | ||
|
|
||
| impl<T: Copy> Filter<Mask> for &mut BufferMut<T> { | ||
| type Output = (); | ||
|
|
||
| fn filter(self, selection_mask: &Mask) { | ||
|
|
@@ -69,16 +77,26 @@ impl<T: Copy> Filter for &mut BufferMut<T> { | |
| } | ||
| } | ||
|
|
||
| impl<T: Copy> Filter for Buffer<T> { | ||
| type Output = Self; | ||
| impl<T: Copy> Filter<MaskIndices<'_>> for &mut BufferMut<T> { | ||
| type Output = (); | ||
|
|
||
| fn filter(self, selection_mask: &Mask) -> Self { | ||
| assert_eq!( | ||
| selection_mask.len(), | ||
| self.len(), | ||
| "Selection mask length must equal the buffer length" | ||
| ); | ||
| fn filter(self, indices: &MaskIndices) -> Self::Output { | ||
| for (write_index, &read_index) in indices.iter().enumerate() { | ||
| self[write_index] = self[read_index]; | ||
| } | ||
|
|
||
| self.truncate(indices.len()); | ||
| } | ||
| } | ||
|
|
||
| impl<M, T: Copy> Filter<M> for Buffer<T> | ||
| where | ||
| for<'a> &'a Buffer<T>: Filter<M, Output = Buffer<T>>, | ||
| for<'a> &'a mut BufferMut<T>: Filter<M, Output = ()>, | ||
| { | ||
| type Output = Self; | ||
|
|
||
| fn filter(self, selection_mask: &M) -> Self { | ||
| // If we have exclusive access, we can perform the filter in place. | ||
| match self.try_into_mut() { | ||
| Ok(mut buffer_mut) => { | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -3,15 +3,15 @@ | |
|
|
||
| //! Filter function. | ||
|
|
||
| use std::ops::Deref; | ||
|
|
||
| mod bitbuffer; | ||
| mod buffer; | ||
| mod mask; | ||
| mod vector; | ||
|
|
||
| use vortex_mask::Mask; | ||
|
|
||
| /// Function for filtering based on a selection mask. | ||
| pub trait Filter { | ||
| pub trait Filter<By: ?Sized> { | ||
| /// The result type after performing the operation. | ||
| type Output; | ||
|
|
||
|
|
@@ -22,5 +22,37 @@ pub trait Filter { | |
| /// # Panics | ||
| /// | ||
| /// If the length of the mask does not equal the length of the value being filtered. | ||
| fn filter(self, selection_mask: &Mask) -> Self::Output; | ||
| fn filter(self, selection: &By) -> Self::Output; | ||
| } | ||
|
|
||
| /// A view over a set of strictly sorted indices from a bit mask. | ||
| /// | ||
| /// Unlike other indices, `MaskIndices` are always strict-sorted, meaning they are | ||
| /// always unique and monotonic. | ||
| /// | ||
| /// You can treat a `MaskIndices` just like a `&[usize]` by iterating or indexing | ||
| /// into it just like you would a slice. | ||
| pub struct MaskIndices<'a>(&'a [usize]); | ||
|
|
||
| impl<'a> MaskIndices<'a> { | ||
| /// Create new indices from a slice of strict-sorted index values. | ||
| /// | ||
| /// # Safety | ||
| /// | ||
| /// The caller must ensure that the indices are strict-sorted, i.e. that they | ||
| /// are monotonic and unique. | ||
| /// | ||
| /// Users of the `Indices` type assume this and failure to uphold this guarantee | ||
| /// can result in UB downstream. | ||
| pub unsafe fn new_unchecked(indices: &'a [usize]) -> Self { | ||
| Self(indices) | ||
|
Comment on lines
+47
to
+48
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. You can add a |
||
| } | ||
| } | ||
|
|
||
| impl Deref for MaskIndices<'_> { | ||
| type Target = [usize]; | ||
|
|
||
| fn deref(&self) -> &Self::Target { | ||
| self.0 | ||
| } | ||
| } | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
here too