1use std::fmt::Debug;
5use std::ops::Deref;
6use std::sync::Arc;
7
8use vortex_array::{ArrayContext, DeserializeMetadata, SerializeMetadata};
9use vortex_dtype::DType;
10use vortex_error::VortexResult;
11
12use crate::children::LayoutChildren;
13use crate::segments::{SegmentId, SegmentSource};
14use crate::{
15 IntoLayout, Layout, LayoutChildType, LayoutEncoding, LayoutEncodingRef, LayoutId,
16 LayoutReaderRef, LayoutRef,
17};
18
19pub trait VTable: 'static + Sized + Send + Sync + Debug {
20 type Layout: 'static + Send + Sync + Clone + Debug + Deref<Target = dyn Layout> + IntoLayout;
21 type Encoding: 'static + Send + Sync + Deref<Target = dyn LayoutEncoding>;
22 type Metadata: SerializeMetadata + DeserializeMetadata + Debug;
23
24 fn id(encoding: &Self::Encoding) -> LayoutId;
26
27 fn encoding(layout: &Self::Layout) -> LayoutEncodingRef;
29
30 fn row_count(layout: &Self::Layout) -> u64;
32
33 fn dtype(layout: &Self::Layout) -> &DType;
35
36 fn metadata(layout: &Self::Layout) -> Self::Metadata;
38
39 fn segment_ids(layout: &Self::Layout) -> Vec<SegmentId>;
41
42 fn nchildren(layout: &Self::Layout) -> usize;
44
45 fn child(layout: &Self::Layout, idx: usize) -> VortexResult<LayoutRef>;
47
48 fn child_type(layout: &Self::Layout, idx: usize) -> LayoutChildType;
50
51 fn new_reader(
53 layout: &Self::Layout,
54 name: Arc<str>,
55 segment_source: Arc<dyn SegmentSource>,
56 ) -> VortexResult<LayoutReaderRef>;
57
58 #[cfg(gpu_unstable)]
59 fn new_gpu_reader(
61 layout: &Self::Layout,
62 name: Arc<str>,
63 segment_source: Arc<dyn SegmentSource>,
64 ctx: Arc<cudarc::driver::CudaContext>,
65 ) -> VortexResult<crate::gpu::GpuLayoutReaderRef>;
66
67 fn build(
69 encoding: &Self::Encoding,
70 dtype: &DType,
71 row_count: u64,
72 metadata: &<Self::Metadata as DeserializeMetadata>::Output,
73 segment_ids: Vec<SegmentId>,
74 children: &dyn LayoutChildren,
75 ctx: ArrayContext,
76 ) -> VortexResult<Self::Layout>;
77}
78
79#[macro_export]
80macro_rules! vtable {
81 ($V:ident) => {
82 $crate::aliases::paste::paste! {
83 #[derive(Debug)]
84 pub struct [<$V VTable>];
85
86 impl AsRef<dyn $crate::Layout> for [<$V Layout>] {
87 fn as_ref(&self) -> &dyn $crate::Layout {
88 unsafe { &*(self as *const [<$V Layout>] as *const $crate::LayoutAdapter<[<$V VTable>]>) }
92 }
93 }
94
95 impl std::ops::Deref for [<$V Layout>] {
96 type Target = dyn $crate::Layout;
97
98 fn deref(&self) -> &Self::Target {
99 unsafe { &*(self as *const [<$V Layout>] as *const $crate::LayoutAdapter<[<$V VTable>]>) }
103 }
104 }
105
106 impl $crate::IntoLayout for [<$V Layout>] {
107 fn into_layout(self) -> $crate::LayoutRef {
108 std::sync::Arc::new(unsafe { std::mem::transmute::<[<$V Layout>], $crate::LayoutAdapter::<[<$V VTable>]>>(self) })
112 }
113 }
114
115 impl From<[<$V Layout>]> for $crate::LayoutRef {
116 fn from(value: [<$V Layout>]) -> $crate::LayoutRef {
117 use $crate::IntoLayout;
118 value.into_layout()
119 }
120 }
121
122 impl AsRef<dyn $crate::LayoutEncoding> for [<$V LayoutEncoding>] {
123 fn as_ref(&self) -> &dyn $crate::LayoutEncoding {
124 unsafe { &*(self as *const [<$V LayoutEncoding>] as *const $crate::LayoutEncodingAdapter<[<$V VTable>]>) }
128 }
129 }
130
131 impl std::ops::Deref for [<$V LayoutEncoding>] {
132 type Target = dyn $crate::LayoutEncoding;
133
134 fn deref(&self) -> &Self::Target {
135 unsafe { &*(self as *const [<$V LayoutEncoding>] as *const $crate::LayoutEncodingAdapter<[<$V VTable>]>) }
139 }
140 }
141 }
142 };
143}