vortex_array/vtable/mod.rs
1//! This module contains the VTable definitions for a Vortex encoding.
2
3mod array;
4mod compute;
5mod decode;
6mod encode;
7mod operations;
8mod serde;
9mod validity;
10mod visitor;
11
12use std::fmt::Debug;
13use std::ops::Deref;
14
15pub use array::*;
16pub use compute::*;
17pub use decode::*;
18pub use encode::*;
19pub use operations::*;
20pub use serde::*;
21pub use validity::*;
22pub use visitor::*;
23
24use crate::{Array, Encoding, EncodingId, EncodingRef, IntoArray};
25
26/// The encoding [`VTable`] encapsulates logic for an Encoding type and associated Array type.
27/// The logic is split across several "VTable" traits to enable easier code organization than
28/// simply lumping everything into a single trait.
29///
30/// Some of these vtables are optional, such as the [`SerdeVTable`], which is only required if
31/// the encoding supports serialization.
32///
33/// From this [`VTable`] trait, we derive implementations for the sealed [`Array`] and [`Encoding`]
34/// traits via the [`crate::ArrayAdapter`] and [`crate::EncodingAdapter`] types respectively.
35///
36/// The functions defined in these vtable traits will typically document their pre- and
37/// post-conditions. The pre-conditions are validated inside the [`Array`] and [`Encoding`]
38/// implementations so do not need to be checked in the vtable implementations (for example, index
39/// out of bounds). Post-conditions are validated after invocation of the vtable function and will
40/// panic if violated.
41pub trait VTable: 'static + Sized + Send + Sync + Debug {
42 type Array: 'static + Send + Sync + Clone + Debug + Deref<Target = dyn Array> + IntoArray;
43 type Encoding: 'static + Send + Sync + Clone + Deref<Target = dyn Encoding>;
44
45 type ArrayVTable: ArrayVTable<Self>;
46 type CanonicalVTable: CanonicalVTable<Self>;
47 type OperationsVTable: OperationsVTable<Self>;
48 type ValidityVTable: ValidityVTable<Self>;
49 type VisitorVTable: VisitorVTable<Self>;
50
51 /// Optionally enable implementing dynamic compute dispatch for this encoding.
52 /// Can be disabled by assigning to the [`NotSupported`] type.
53 type ComputeVTable: ComputeVTable<Self>;
54 /// Optionally enable the [`EncodeVTable`] for this encoding. This allows it to partake in
55 /// compression.
56 /// Can be disabled by assigning to the [`NotSupported`] type.
57 type EncodeVTable: EncodeVTable<Self>;
58 /// Optionally enable serde for this encoding by implementing the [`SerdeVTable`] trait.
59 /// Can be disabled by assigning to the [`NotSupported`] type.
60 type SerdeVTable: SerdeVTable<Self>;
61
62 /// Returns the ID of the encoding.
63 fn id(encoding: &Self::Encoding) -> EncodingId;
64
65 /// Returns the encoding for the array.
66 fn encoding(array: &Self::Array) -> EncodingRef;
67}
68
69/// Placeholder type used to indicate when a particular vtable is not supported by the encoding.
70pub struct NotSupported;
71
72#[macro_export]
73macro_rules! vtable {
74 ($V:ident) => {
75 $crate::aliases::paste::paste! {
76 #[derive(Debug)]
77 pub struct [<$V VTable>];
78
79 impl AsRef<dyn $crate::Array> for [<$V Array>] {
80 fn as_ref(&self) -> &dyn $crate::Array {
81 // We can unsafe cast ourselves to an ArrayAdapter.
82 unsafe { &*(self as *const [<$V Array>] as *const $crate::ArrayAdapter<[<$V VTable>]>) }
83 }
84 }
85
86 impl std::ops::Deref for [<$V Array>] {
87 type Target = dyn $crate::Array;
88
89 fn deref(&self) -> &Self::Target {
90 // We can unsafe cast ourselves to an ArrayAdapter.
91 unsafe { &*(self as *const [<$V Array>] as *const $crate::ArrayAdapter<[<$V VTable>]>) }
92 }
93 }
94
95 impl $crate::IntoArray for [<$V Array>] {
96 fn into_array(self) -> $crate::ArrayRef {
97 // We can unsafe transmute ourselves to an ArrayAdapter.
98 std::sync::Arc::new(unsafe { std::mem::transmute::<[<$V Array>], $crate::ArrayAdapter::<[<$V VTable>]>>(self) })
99 }
100 }
101
102 impl AsRef<dyn $crate::Encoding> for [<$V Encoding>] {
103 fn as_ref(&self) -> &dyn $crate::Encoding {
104 // We can unsafe cast ourselves to an EncodingAdapter.
105 unsafe { &*(self as *const [<$V Encoding>] as *const $crate::EncodingAdapter<[<$V VTable>]>) }
106 }
107 }
108
109 impl std::ops::Deref for [<$V Encoding>] {
110 type Target = dyn $crate::Encoding;
111
112 fn deref(&self) -> &Self::Target {
113 // We can unsafe cast ourselves to an EncodingAdapter.
114 unsafe { &*(self as *const [<$V Encoding>] as *const $crate::EncodingAdapter<[<$V VTable>]>) }
115 }
116 }
117 }
118 };
119}