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