Skip to content
Closed
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
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
1 change: 1 addition & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 3 additions & 2 deletions benchmarks/compress-bench/src/vortex.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ use async_trait::async_trait;
use bytes::Bytes;
use futures::StreamExt;
use futures::pin_mut;
use vortex::array::IntoArray;
use vortex::file::OpenOptionsSessionExt;
use vortex::file::WriteOptionsSessionExt;
use vortex_bench::Format;
Expand All @@ -37,7 +38,7 @@ impl Compressor for VortexCompressor {
let mut cursor = Cursor::new(&mut buf);
SESSION
.write_options()
.write(&mut cursor, uncompressed.to_array_stream())
.write(&mut cursor, uncompressed.into_array().to_array_stream())
.await?;
let elapsed = start.elapsed();

Expand All @@ -51,7 +52,7 @@ impl Compressor for VortexCompressor {
let mut cursor = Cursor::new(&mut buf);
SESSION
.write_options()
.write(&mut cursor, uncompressed.to_array_stream())
.write(&mut cursor, uncompressed.into_array().to_array_stream())
.await?;

// Now decompress
Expand Down
218 changes: 110 additions & 108 deletions encodings/alp/public-api.lock

Large diffs are not rendered by default.

114 changes: 79 additions & 35 deletions encodings/alp/src/alp/array.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,6 @@ use vortex_array::patches::Patches;
use vortex_array::patches::PatchesMetadata;
use vortex_array::serde::ArrayChildren;
use vortex_array::stats::ArrayStats;
use vortex_array::stats::StatsSetRef;
use vortex_array::vtable;
use vortex_array::vtable::Array;
use vortex_array::vtable::ArrayId;
Expand All @@ -47,66 +46,66 @@ use crate::alp::decompress::execute_decompress;
use crate::alp::rules::PARENT_KERNELS;
use crate::alp::rules::RULES;

vtable!(ALP);
vtable!(ALP, ALP, ALPData);

impl VTable for ALP {
type Array = ALPArray;
type ArrayData = ALPData;

type Metadata = ProstMetadata<ALPMetadata>;
type OperationsVTable = Self;
type ValidityVTable = ValidityVTableFromChild;

fn vtable(_array: &Self::Array) -> &Self {
fn vtable(_array: &Self::ArrayData) -> &Self {
&ALP
}

fn id(&self) -> ArrayId {
Self::ID
}

fn len(array: &ALPArray) -> usize {
fn len(array: &ALPData) -> usize {
array.encoded.len()
}

fn dtype(array: &ALPArray) -> &DType {
fn dtype(array: &ALPData) -> &DType {
&array.dtype
}

fn stats(array: &ALPArray) -> StatsSetRef<'_> {
array.stats_set.to_ref(array.as_ref())
fn stats(array: &ALPData) -> &ArrayStats {
&array.stats_set
}

fn array_hash<H: std::hash::Hasher>(array: &ALPArray, state: &mut H, precision: Precision) {
fn array_hash<H: std::hash::Hasher>(array: &Array<Self>, state: &mut H, precision: Precision) {
array.dtype.hash(state);
array.encoded.array_hash(state, precision);
array.exponents.hash(state);
array.patches.array_hash(state, precision);
}

fn array_eq(array: &ALPArray, other: &ALPArray, precision: Precision) -> bool {
fn array_eq(array: &Array<Self>, other: &Array<Self>, precision: Precision) -> bool {
array.dtype == other.dtype
&& array.encoded.array_eq(&other.encoded, precision)
&& array.exponents == other.exponents
&& array.patches.array_eq(&other.patches, precision)
}

fn nbuffers(_array: &ALPArray) -> usize {
fn nbuffers(_array: &Array<Self>) -> usize {
0
}

fn buffer(_array: &ALPArray, idx: usize) -> BufferHandle {
fn buffer(_array: &Array<Self>, idx: usize) -> BufferHandle {
vortex_panic!("ALPArray buffer index {idx} out of bounds")
}

fn buffer_name(_array: &ALPArray, _idx: usize) -> Option<String> {
fn buffer_name(_array: &Array<Self>, _idx: usize) -> Option<String> {
None
}

fn nchildren(array: &ALPArray) -> usize {
fn nchildren(array: &Array<Self>) -> usize {
1 + array.patches().map_or(0, patches_nchildren)
}

fn child(array: &ALPArray, idx: usize) -> ArrayRef {
fn child(array: &Array<Self>, idx: usize) -> ArrayRef {
match idx {
0 => array.encoded().clone(),
_ => {
Expand All @@ -118,7 +117,7 @@ impl VTable for ALP {
}
}

fn child_name(array: &ALPArray, idx: usize) -> String {
fn child_name(array: &Array<Self>, idx: usize) -> String {
match idx {
0 => "encoded".to_string(),
_ => {
Expand All @@ -130,7 +129,7 @@ impl VTable for ALP {
}
}

fn metadata(array: &ALPArray) -> VortexResult<Self::Metadata> {
fn metadata(array: &Array<Self>) -> VortexResult<Self::Metadata> {
let exponents = array.exponents();
Ok(ProstMetadata(ALPMetadata {
exp_e: exponents.e as u32,
Expand Down Expand Up @@ -164,7 +163,7 @@ impl VTable for ALP {
metadata: &Self::Metadata,
_buffers: &[BufferHandle],
children: &dyn ArrayChildren,
) -> VortexResult<ALPArray> {
) -> VortexResult<ALPData> {
let encoded_ptype = match &dtype {
DType::Primitive(PType::F32, n) => DType::Primitive(PType::I32, *n),
DType::Primitive(PType::F64, n) => DType::Primitive(PType::I64, *n),
Expand All @@ -186,7 +185,7 @@ impl VTable for ALP {
})
.transpose()?;

ALPArray::try_new(
ALPData::try_new(
encoded,
Exponents {
e: u8::try_from(metadata.exp_e)?,
Expand All @@ -196,7 +195,7 @@ impl VTable for ALP {
)
}

fn with_children(array: &mut Self::Array, children: Vec<ArrayRef>) -> VortexResult<()> {
fn with_children(array: &mut Self::ArrayData, children: Vec<ArrayRef>) -> VortexResult<()> {
// Children: encoded, patches (if present): indices, values, chunk_offsets (optional)
let patches_info = array
.patches
Expand Down Expand Up @@ -243,7 +242,7 @@ impl VTable for ALP {

fn execute(array: Arc<Array<Self>>, ctx: &mut ExecutionCtx) -> VortexResult<ExecutionResult> {
Ok(ExecutionResult::done(
execute_decompress(Arc::unwrap_or_clone(array).into_inner(), ctx)?.into_array(),
execute_decompress(Arc::unwrap_or_clone(array), ctx)?.into_array(),
))
}

Expand All @@ -266,7 +265,7 @@ impl VTable for ALP {
}

#[derive(Clone, Debug)]
pub struct ALPArray {
pub struct ALPData {
encoded: ArrayRef,
patches: Option<Patches>,
dtype: DType,
Expand All @@ -291,7 +290,7 @@ pub struct ALPMetadata {
pub(crate) patches: Option<PatchesMetadata>,
}

impl ALPArray {
impl ALPData {
fn validate(
encoded: &ArrayRef,
exponents: Exponents,
Expand Down Expand Up @@ -363,10 +362,10 @@ impl ALPArray {
}
}

impl ALPArray {
impl ALPData {
/// Build a new `ALPArray` from components, panicking on validation failure.
///
/// See [`ALPArray::try_new`] for reference on preconditions that must pass before
/// See [`ALPData::try_new`] for reference on preconditions that must pass before
/// calling this method.
pub fn new(encoded: ArrayRef, exponents: Exponents, patches: Option<Patches>) -> Self {
Self::try_new(encoded, exponents, patches).vortex_expect("ALPArray new")
Expand Down Expand Up @@ -394,32 +393,32 @@ impl ALPArray {
/// # Examples
///
/// ```
/// # use vortex_alp::{ALPArray, Exponents};
/// # use vortex_alp::{ALPData, ALPArray, Exponents};
/// # use vortex_array::IntoArray;
/// # use vortex_buffer::buffer;
///
/// // Returns error because buffer has wrong PType.
/// let result = ALPArray::try_new(
/// let result = ALPData::try_new(
/// buffer![1i8].into_array(),
/// Exponents { e: 1, f: 1 },
/// None
/// );
/// assert!(result.is_err());
///
/// // Returns error because Exponents are out of bounds for f32
/// let result = ALPArray::try_new(
/// let result = ALPData::try_new(
/// buffer![1i32, 2i32].into_array(),
/// Exponents { e: 100, f: 100 },
/// None
/// );
/// assert!(result.is_err());
///
/// // Success!
/// let value = ALPArray::try_new(
/// let value = ALPArray::try_from_data(ALPData::try_new(
/// buffer![0i32].into_array(),
/// Exponents { e: 1, f: 1 },
/// None
/// ).unwrap();
/// ).unwrap()).unwrap();
///
/// assert_eq!(value.scalar_at(0).unwrap(), 0f32.into());
/// ```
Expand Down Expand Up @@ -447,7 +446,7 @@ impl ALPArray {

/// Build a new `ALPArray` from components without validation.
///
/// See [`ALPArray::try_new`] for information about the preconditions that should be checked
/// See [`ALPData::try_new`] for information about the preconditions that should be checked
/// **before** calling this method.
pub(crate) unsafe fn new_unchecked(
encoded: ArrayRef,
Expand All @@ -463,6 +462,51 @@ impl ALPArray {
stats_set: Default::default(),
}
}
}

/// Constructors for [`ALPArray`].
impl ALP {
pub fn new(encoded: ArrayRef, exponents: Exponents, patches: Option<Patches>) -> ALPArray {
Array::try_from_data(ALPData::new(encoded, exponents, patches))
.vortex_expect("ALPData is always valid")
}

pub fn try_new(
encoded: ArrayRef,
exponents: Exponents,
patches: Option<Patches>,
) -> VortexResult<ALPArray> {
Array::try_from_data(ALPData::try_new(encoded, exponents, patches)?)
}

/// # Safety
/// See [`ALPData::try_new`] for preconditions.
pub unsafe fn new_unchecked(
encoded: ArrayRef,
exponents: Exponents,
patches: Option<Patches>,
dtype: DType,
) -> ALPArray {
Array::try_from_data(unsafe { ALPData::new_unchecked(encoded, exponents, patches, dtype) })
.vortex_expect("ALPData is always valid")
}
}

impl ALPData {
/// Returns the number of elements in the array.
pub fn len(&self) -> usize {
self.encoded.len()
}

/// Returns `true` if the array contains no elements.
pub fn is_empty(&self) -> bool {
self.encoded.len() == 0
}

/// Returns the logical data type of the array.
pub fn dtype(&self) -> &DType {
&self.dtype
}

pub fn ptype(&self) -> PType {
self.dtype.as_ptype()
Expand All @@ -489,7 +533,7 @@ impl ALPArray {
}

impl ValidityChild<ALP> for ALP {
fn validity_child(array: &ALPArray) -> &ArrayRef {
fn validity_child(array: &ALPData) -> &ArrayRef {
array.encoded()
}
}
Expand All @@ -508,7 +552,6 @@ mod tests {
use vortex_array::arrays::PrimitiveArray;
use vortex_array::assert_arrays_eq;
use vortex_array::session::ArraySession;
use vortex_array::vtable::ValidityHelper;
use vortex_session::VortexSession;

use super::*;
Expand Down Expand Up @@ -809,11 +852,12 @@ mod tests {
.unwrap();

// Build a new ALPArray with the same encoded data but patches without chunk_offsets.
let alp_without_chunk_offsets = ALPArray::new(
let alp_without_chunk_offsets = ALPArray::try_from_data(ALPData::new(
normally_encoded.encoded().clone(),
normally_encoded.exponents(),
Some(patches_without_chunk_offsets),
);
))
.vortex_expect("ALPData is always valid");

// The legacy decompress_into_array path should work correctly.
let result_legacy = decompress_into_array(
Expand Down
4 changes: 2 additions & 2 deletions encodings/alp/src/alp/compress.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,13 @@ use vortex_array::arrays::PrimitiveArray;
use vortex_array::dtype::PType;
use vortex_array::patches::Patches;
use vortex_array::validity::Validity;
use vortex_array::vtable::ValidityHelper;
use vortex_buffer::Buffer;
use vortex_buffer::BufferMut;
use vortex_error::VortexResult;
use vortex_error::vortex_bail;
use vortex_mask::Mask;

use crate::ALP;
use crate::Exponents;
use crate::alp::ALPArray;
use crate::alp::ALPFloat;
Expand Down Expand Up @@ -48,7 +48,7 @@ pub fn alp_encode(parray: &PrimitiveArray, exponents: Option<Exponents>) -> Vort

// SAFETY: alp_encode_components_typed must return well-formed components
unsafe {
Ok(ALPArray::new_unchecked(
Ok(ALP::new_unchecked(
encoded,
exponents,
patches,
Expand Down
9 changes: 2 additions & 7 deletions encodings/alp/src/alp/compute/cast.rs
Original file line number Diff line number Diff line change
Expand Up @@ -45,13 +45,8 @@ impl CastReduce for ALP {
// SAFETY: casting nullability doesn't alter the invariants
unsafe {
Ok(Some(
ALPArray::new_unchecked(
new_encoded,
array.exponents(),
new_patches,
dtype.clone(),
)
.into_array(),
ALP::new_unchecked(new_encoded, array.exponents(), new_patches, dtype.clone())
.into_array(),
))
}
} else {
Expand Down
2 changes: 1 addition & 1 deletion encodings/alp/src/alp/compute/filter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ impl FilterKernel for ALP {
// SAFETY: filtering the values does not change correctness
unsafe {
Ok(Some(
ALPArray::new_unchecked(
ALP::new_unchecked(
array.encoded().filter(mask.clone())?,
array.exponents(),
patches,
Expand Down
Loading
Loading