mod operations;
mod validity;
use std::fmt::Debug;
use std::fmt::Display;
use std::fmt::Formatter;
use std::hash::Hasher;
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::Array;
use crate::ArrayRef;
use crate::ArrayView;
use crate::Canonical;
use crate::ExecutionResult;
use crate::IntoArray;
use crate::Precision;
pub use crate::array::plugin::*;
use crate::arrays::ConstantArray;
use crate::arrays::constant::Constant;
use crate::buffer::BufferHandle;
use crate::builders::ArrayBuilder;
use crate::dtype::DType;
use crate::dtype::Nullability;
use crate::executor::ExecutionCtx;
use crate::hash::ArrayEq;
use crate::hash::ArrayHash;
use crate::patches::Patches;
use crate::scalar::ScalarValue;
use crate::serde::ArrayChildren;
use crate::validity::Validity;
pub trait VTable: 'static + Clone + Sized + Send + Sync + Debug {
type ArrayData: 'static + Send + Sync + Clone + Debug + Display + ArrayHash + ArrayEq;
type OperationsVTable: OperationsVTable<Self>;
type ValidityVTable: ValidityVTable<Self>;
fn id(&self) -> ArrayId;
fn validate(
&self,
data: &Self::ArrayData,
dtype: &DType,
len: usize,
slots: &[Option<ArrayRef>],
) -> VortexResult<()>;
fn nbuffers(array: ArrayView<'_, Self>) -> usize;
fn buffer(array: ArrayView<'_, Self>, idx: usize) -> BufferHandle;
fn buffer_name(array: ArrayView<'_, Self>, idx: usize) -> Option<String>;
fn nchildren(array: ArrayView<'_, Self>) -> usize {
array.slots().iter().filter(|s| s.is_some()).count()
}
fn child(array: ArrayView<'_, Self>, idx: usize) -> ArrayRef {
array
.slots()
.iter()
.filter_map(|s| s.clone())
.nth(idx)
.vortex_expect("child index out of bounds")
}
fn child_name(array: ArrayView<'_, Self>, idx: usize) -> String {
array
.slots()
.iter()
.enumerate()
.filter(|(_, s)| s.is_some())
.nth(idx)
.map(|(slot_idx, _)| Self::slot_name(array, slot_idx))
.vortex_expect("child_name index out of bounds")
}
fn serialize(
array: ArrayView<'_, Self>,
session: &VortexSession,
) -> VortexResult<Option<Vec<u8>>>;
fn deserialize(
&self,
dtype: &DType,
len: usize,
metadata: &[u8],
buffers: &[BufferHandle],
children: &dyn ArrayChildren,
session: &VortexSession,
) -> VortexResult<crate::array::ArrayParts<Self>>;
fn append_to_builder(
array: ArrayView<'_, Self>,
builder: &mut dyn ArrayBuilder,
ctx: &mut ExecutionCtx,
) -> VortexResult<()> {
let canonical = array
.array()
.clone()
.execute::<Canonical>(ctx)?
.into_array();
builder.extend_from_array(&canonical);
Ok(())
}
fn slot_name(array: ArrayView<'_, Self>, idx: usize) -> String;
fn execute(array: Array<Self>, ctx: &mut ExecutionCtx) -> VortexResult<ExecutionResult>;
fn execute_parent(
array: ArrayView<'_, Self>,
parent: &ArrayRef,
child_idx: usize,
ctx: &mut ExecutionCtx,
) -> VortexResult<Option<ArrayRef>> {
_ = (array, parent, child_idx, ctx);
Ok(None)
}
fn reduce(array: ArrayView<'_, Self>) -> VortexResult<Option<ArrayRef>> {
_ = array;
Ok(None)
}
fn reduce_parent(
array: ArrayView<'_, Self>,
parent: &ArrayRef,
child_idx: usize,
) -> VortexResult<Option<ArrayRef>> {
_ = (array, parent, child_idx);
Ok(None)
}
}
pub use VTable as ArrayVTable;
use crate::array::ArrayId;
#[derive(Clone, Debug, Default)]
pub struct EmptyArrayData;
impl ArrayEq for EmptyArrayData {
fn array_eq(&self, _other: &Self, _precision: Precision) -> bool {
true
}
}
impl ArrayHash for EmptyArrayData {
fn array_hash<H: Hasher>(&self, _state: &mut H, _precision: Precision) {}
}
impl Display for EmptyArrayData {
fn fmt(&self, _f: &mut Formatter<'_>) -> std::fmt::Result {
Ok(())
}
}
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 child_to_validity(child: &Option<ArrayRef>, nullability: Nullability) -> Validity {
match child {
Some(arr) => {
if let Some(c) = arr.as_opt::<Constant>()
&& let Some(ScalarValue::Bool(val)) = c.scalar().value()
{
return if *val {
Validity::AllValid
} else {
Validity::AllInvalid
};
}
Validity::Array(arr.clone())
}
None => Validity::from(nullability),
}
}
#[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"),
}
}