use std::any::Any;
use std::fmt::Debug;
use std::fmt::Display;
use std::fmt::Formatter;
use arcref::ArcRef;
use vortex_array::DeserializeMetadata;
use vortex_array::dtype::DType;
use vortex_error::VortexExpect;
use vortex_error::VortexResult;
use vortex_session::VortexSession;
use vortex_session::registry::ReadContext;
use crate::LayoutId;
use crate::LayoutRef;
use crate::VTable;
use crate::children::LayoutChildren;
use crate::segments::SegmentId;
pub type LayoutEncodingId = LayoutId;
pub type LayoutVTableRef = ArcRef<dyn LayoutVTablePlugin>;
pub type LayoutEncodingRef = LayoutVTableRef;
pub struct LayoutDeserializeArgs<'a> {
pub session: &'a VortexSession,
pub array_read_ctx: &'a ReadContext,
pub dtype: &'a DType,
pub row_count: u64,
pub segment_ids: Vec<SegmentId>,
pub children: &'a dyn LayoutChildren,
}
pub struct LayoutBuildContext<'a> {
pub session: &'a VortexSession,
pub array_read_ctx: &'a ReadContext,
}
pub trait LayoutVTablePlugin: 'static + Send + Sync + Debug {
fn as_any(&self) -> &dyn Any;
fn id(&self) -> LayoutEncodingId;
fn build(
&self,
dtype: &DType,
row_count: u64,
metadata: &[u8],
segment_ids: Vec<SegmentId>,
children: &dyn LayoutChildren,
build_ctx: &LayoutBuildContext<'_>,
) -> VortexResult<LayoutRef>;
fn is_indivisible(&self) -> bool {
false
}
}
pub use LayoutVTablePlugin as LayoutEncoding;
impl<V: VTable> LayoutVTablePlugin for V {
fn as_any(&self) -> &dyn Any {
self
}
fn id(&self) -> LayoutEncodingId {
VTable::id(self)
}
fn build(
&self,
dtype: &DType,
row_count: u64,
metadata: &[u8],
segment_ids: Vec<SegmentId>,
children: &dyn LayoutChildren,
build_ctx: &LayoutBuildContext<'_>,
) -> VortexResult<LayoutRef> {
let metadata = <V::Metadata as DeserializeMetadata>::deserialize(metadata)?;
Ok(V::build(
self,
dtype,
row_count,
&metadata,
segment_ids,
children,
build_ctx,
)?
.into_layout())
}
fn is_indivisible(&self) -> bool {
VTable::is_indivisible(self)
}
}
impl Display for dyn LayoutVTablePlugin + '_ {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
write!(f, "{}", self.id())
}
}
impl PartialEq for dyn LayoutVTablePlugin + '_ {
fn eq(&self, other: &Self) -> bool {
self.id() == other.id()
}
}
impl Eq for dyn LayoutVTablePlugin + '_ {}
impl dyn LayoutVTablePlugin + '_ {
pub fn is<V: VTable>(&self) -> bool {
self.as_opt::<V>().is_some()
}
pub fn as_<V: VTable>(&self) -> &V {
self.as_opt::<V>()
.vortex_expect("layout encoding type mismatch")
}
pub fn as_opt<V: VTable>(&self) -> Option<&V> {
self.as_any().downcast_ref()
}
}