vortex_layout/
encoding.rs

1use std::any::Any;
2use std::fmt::{Debug, Display, Formatter};
3
4use arcref::ArcRef;
5use vortex_array::DeserializeMetadata;
6use vortex_dtype::DType;
7use vortex_error::{VortexExpect, VortexResult, vortex_panic};
8
9use crate::segments::SegmentId;
10use crate::{IntoLayout, LayoutChildren, LayoutRef, VTable};
11
12pub type LayoutEncodingId = ArcRef<str>;
13pub type LayoutEncodingRef = ArcRef<dyn LayoutEncoding>;
14
15pub trait LayoutEncoding: 'static + Send + Sync + Debug + private::Sealed {
16    fn as_any(&self) -> &dyn Any;
17
18    fn id(&self) -> LayoutEncodingId;
19
20    fn build(
21        &self,
22        dtype: &DType,
23        row_count: u64,
24        metadata: &[u8],
25        segment_ids: Vec<SegmentId>,
26        children: &dyn LayoutChildren,
27    ) -> VortexResult<LayoutRef>;
28}
29
30#[repr(transparent)]
31pub struct LayoutEncodingAdapter<V: VTable>(V::Encoding);
32
33impl<V: VTable> LayoutEncoding for LayoutEncodingAdapter<V> {
34    fn as_any(&self) -> &dyn Any {
35        self
36    }
37
38    fn id(&self) -> LayoutEncodingId {
39        V::id(&self.0)
40    }
41
42    fn build(
43        &self,
44        dtype: &DType,
45        row_count: u64,
46        metadata: &[u8],
47        segment_ids: Vec<SegmentId>,
48        children: &dyn LayoutChildren,
49    ) -> VortexResult<LayoutRef> {
50        let metadata = <V::Metadata as DeserializeMetadata>::deserialize(metadata)?;
51        let layout = V::build(&self.0, dtype, row_count, &metadata, segment_ids, children)?;
52
53        // Validate that the builder function returned the expected values.
54        if layout.row_count() != row_count {
55            vortex_panic!(
56                "Layout row count mismatch: {} != {}",
57                layout.row_count(),
58                row_count
59            );
60        }
61        if layout.dtype() != dtype {
62            vortex_panic!("Layout dtype mismatch: {} != {}", layout.dtype(), dtype);
63        }
64
65        Ok(layout.into_layout())
66    }
67}
68
69impl<V: VTable> Debug for LayoutEncodingAdapter<V> {
70    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
71        f.debug_struct("LayoutEncoding")
72            .field("id", &self.id())
73            .finish()
74    }
75}
76
77impl Display for dyn LayoutEncoding + '_ {
78    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
79        write!(f, "{}", self.id())
80    }
81}
82
83impl PartialEq for dyn LayoutEncoding + '_ {
84    fn eq(&self, other: &Self) -> bool {
85        self.id() == other.id()
86    }
87}
88
89impl Eq for dyn LayoutEncoding + '_ {}
90
91impl dyn LayoutEncoding + '_ {
92    pub fn is<V: VTable>(&self) -> bool {
93        self.as_opt::<V>().is_some()
94    }
95
96    pub fn as_<V: VTable>(&self) -> &V::Encoding {
97        self.as_opt::<V>()
98            .vortex_expect("LayoutEncoding is not of the expected type")
99    }
100
101    pub fn as_opt<V: VTable>(&self) -> Option<&V::Encoding> {
102        self.as_any()
103            .downcast_ref::<LayoutEncodingAdapter<V>>()
104            .map(|e| &e.0)
105    }
106}
107
108mod private {
109    use super::*;
110
111    pub trait Sealed {}
112
113    impl<V: VTable> Sealed for LayoutEncodingAdapter<V> {}
114}