vortex_layout/
encoding.rs1use 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 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}