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}