mod dyn_;
mod operations;
mod validity;
use std::fmt::Debug;
use std::hash::Hasher;
use std::ops::Deref;
pub use dyn_::*;
pub use operations::*;
pub use validity::*;
use vortex_error::VortexExpect;
use vortex_error::VortexResult;
use vortex_error::vortex_panic;
use vortex_session::VortexSession;
use crate::ArrayRef;
use crate::Canonical;
use crate::DynArray;
use crate::ExecutionStep;
use crate::IntoArray;
use crate::Precision;
use crate::arrays::ConstantArray;
use crate::buffer::BufferHandle;
use crate::builders::ArrayBuilder;
use crate::dtype::DType;
use crate::executor::ExecutionCtx;
use crate::patches::Patches;
use crate::serde::ArrayChildren;
use crate::stats::StatsSetRef;
use crate::validity::Validity;
pub trait VTable: 'static + Sized + Send + Sync + Debug {
type Array: 'static + Send + Sync + Clone + Debug + Deref<Target = dyn DynArray> + IntoArray;
type Metadata: Debug;
type OperationsVTable: OperationsVTable<Self>;
type ValidityVTable: ValidityVTable<Self>;
fn id(array: &Self::Array) -> ArrayId;
fn len(array: &Self::Array) -> usize;
fn dtype(array: &Self::Array) -> &DType;
fn stats(array: &Self::Array) -> StatsSetRef<'_>;
fn array_hash<H: Hasher>(array: &Self::Array, state: &mut H, precision: Precision);
fn array_eq(array: &Self::Array, other: &Self::Array, precision: Precision) -> bool;
fn nbuffers(array: &Self::Array) -> usize;
fn buffer(array: &Self::Array, idx: usize) -> BufferHandle;
fn buffer_name(array: &Self::Array, idx: usize) -> Option<String>;
fn nchildren(array: &Self::Array) -> usize;
fn child(array: &Self::Array, idx: usize) -> ArrayRef;
fn child_name(array: &Self::Array, idx: usize) -> String;
fn metadata(array: &Self::Array) -> VortexResult<Self::Metadata>;
fn serialize(metadata: Self::Metadata) -> VortexResult<Option<Vec<u8>>>;
fn deserialize(
bytes: &[u8],
_dtype: &DType,
_len: usize,
_buffers: &[BufferHandle],
_session: &VortexSession,
) -> VortexResult<Self::Metadata>;
fn append_to_builder(
array: &Self::Array,
builder: &mut dyn ArrayBuilder,
ctx: &mut ExecutionCtx,
) -> VortexResult<()> {
let canonical = array.to_array().execute::<Canonical>(ctx)?.into_array();
builder.extend_from_array(&canonical);
Ok(())
}
fn build(
dtype: &DType,
len: usize,
metadata: &Self::Metadata,
buffers: &[BufferHandle],
children: &dyn ArrayChildren,
) -> VortexResult<Self::Array>;
fn with_children(array: &mut Self::Array, children: Vec<ArrayRef>) -> VortexResult<()>;
fn execute(array: &Self::Array, ctx: &mut ExecutionCtx) -> VortexResult<ExecutionStep>;
fn execute_parent(
array: &Self::Array,
parent: &ArrayRef,
child_idx: usize,
ctx: &mut ExecutionCtx,
) -> VortexResult<Option<ArrayRef>> {
_ = (array, parent, child_idx, ctx);
Ok(None)
}
fn reduce(array: &Self::Array) -> VortexResult<Option<ArrayRef>> {
_ = array;
Ok(None)
}
fn reduce_parent(
array: &Self::Array,
parent: &ArrayRef,
child_idx: usize,
) -> VortexResult<Option<ArrayRef>> {
_ = (array, parent, child_idx);
Ok(None)
}
}
pub struct NotSupported;
#[inline]
pub fn validity_to_child(validity: &Validity, len: usize) -> Option<ArrayRef> {
match validity {
Validity::NonNullable | Validity::AllValid => None,
Validity::AllInvalid => Some(ConstantArray::new(false, len).into_array()),
Validity::Array(array) => Some(array.clone()),
}
}
#[inline]
pub fn validity_nchildren(validity: &Validity) -> usize {
match validity {
Validity::NonNullable | Validity::AllValid => 0,
Validity::AllInvalid | Validity::Array(_) => 1,
}
}
#[inline]
pub fn patches_nchildren(patches: &Patches) -> usize {
2 + patches.chunk_offsets().is_some() as usize
}
#[inline]
pub fn patches_child(patches: &Patches, idx: usize) -> ArrayRef {
match idx {
0 => patches.indices().clone(),
1 => patches.values().clone(),
2 => patches
.chunk_offsets()
.as_ref()
.vortex_expect("patch_chunk_offsets child out of bounds")
.clone(),
_ => vortex_panic!("patches child index {idx} out of bounds"),
}
}
#[inline]
pub fn patches_child_name(idx: usize) -> &'static str {
match idx {
0 => "patch_indices",
1 => "patch_values",
2 => "patch_chunk_offsets",
_ => vortex_panic!("patches child name index {idx} out of bounds"),
}
}
#[macro_export]
macro_rules! vtable {
($V:ident) => {
$crate::aliases::paste::paste! {
impl AsRef<dyn $crate::DynArray> for [<$V Array>] {
fn as_ref(&self) -> &dyn $crate::DynArray {
unsafe { &*(self as *const [<$V Array>] as *const $crate::ArrayAdapter<[<$V VTable>]>) }
}
}
impl std::ops::Deref for [<$V Array>] {
type Target = dyn $crate::DynArray;
fn deref(&self) -> &Self::Target {
unsafe { &*(self as *const [<$V Array>] as *const $crate::ArrayAdapter<[<$V VTable>]>) }
}
}
impl $crate::IntoArray for [<$V Array>] {
fn into_array(self) -> $crate::ArrayRef {
std::sync::Arc::new(unsafe { std::mem::transmute::<[<$V Array>], $crate::ArrayAdapter::<[<$V VTable>]>>(self) })
}
}
impl From<[<$V Array>]> for $crate::ArrayRef {
fn from(value: [<$V Array>]) -> $crate::ArrayRef {
use $crate::IntoArray;
value.into_array()
}
}
impl [<$V Array>] {
#[deprecated(note = "use `.into_array()` (owned) or `.clone().into_array()` (ref) to make clones explicit")]
pub fn to_array(&self) -> $crate::ArrayRef {
use $crate::IntoArray;
self.clone().into_array()
}
}
}
};
}