vortex_array/vtable/
mod.rs

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