vortex_layout/
encoding.rs1use std::any::Any;
5use std::fmt::Debug;
6use std::fmt::Display;
7use std::fmt::Formatter;
8
9use arcref::ArcRef;
10use vortex_array::DeserializeMetadata;
11use vortex_array::dtype::DType;
12use vortex_error::VortexExpect;
13use vortex_error::VortexResult;
14use vortex_error::vortex_panic;
15use vortex_session::registry::Id;
16
17use crate::IntoLayout;
18use crate::LayoutBuildContext;
19use crate::LayoutChildren;
20use crate::LayoutRef;
21use crate::VTable;
22use crate::segments::SegmentId;
23
24pub type LayoutEncodingId = Id;
26pub type LayoutEncodingRef = ArcRef<dyn LayoutEncoding>;
28
29pub trait LayoutEncoding: 'static + Send + Sync + Debug + private::Sealed {
35 fn as_any(&self) -> &dyn Any;
37
38 fn id(&self) -> LayoutEncodingId;
40
41 fn build(
46 &self,
47 dtype: &DType,
48 row_count: u64,
49 metadata: &[u8],
50 segment_ids: Vec<SegmentId>,
51 children: &dyn LayoutChildren,
52 build_ctx: &LayoutBuildContext<'_>,
53 ) -> VortexResult<LayoutRef>;
54}
55
56#[repr(transparent)]
58pub struct LayoutEncodingAdapter<V: VTable>(V::Encoding);
59
60impl<V: VTable> LayoutEncoding for LayoutEncodingAdapter<V> {
61 fn as_any(&self) -> &dyn Any {
62 self
63 }
64
65 fn id(&self) -> LayoutEncodingId {
66 V::id(&self.0)
67 }
68
69 fn build(
70 &self,
71 dtype: &DType,
72 row_count: u64,
73 metadata: &[u8],
74 segment_ids: Vec<SegmentId>,
75 children: &dyn LayoutChildren,
76 build_ctx: &LayoutBuildContext<'_>,
77 ) -> VortexResult<LayoutRef> {
78 let metadata = <V::Metadata as DeserializeMetadata>::deserialize(metadata)?;
79 let layout = V::build(
80 &self.0,
81 dtype,
82 row_count,
83 &metadata,
84 segment_ids,
85 children,
86 build_ctx,
87 )?;
88
89 if layout.row_count() != row_count {
91 vortex_panic!(
92 "Layout row count mismatch: {} != {}",
93 layout.row_count(),
94 row_count
95 );
96 }
97 if layout.dtype() != dtype {
98 vortex_panic!("Layout dtype mismatch: {} != {}", layout.dtype(), dtype);
99 }
100
101 Ok(layout.into_layout())
102 }
103}
104
105impl<V: VTable> Debug for LayoutEncodingAdapter<V> {
106 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
107 f.debug_struct("LayoutEncoding")
108 .field("id", &self.id())
109 .finish()
110 }
111}
112
113impl Display for dyn LayoutEncoding + '_ {
114 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
115 write!(f, "{}", self.id())
116 }
117}
118
119impl PartialEq for dyn LayoutEncoding + '_ {
120 fn eq(&self, other: &Self) -> bool {
121 self.id() == other.id()
122 }
123}
124
125impl Eq for dyn LayoutEncoding + '_ {}
126
127impl dyn LayoutEncoding + '_ {
128 pub fn is<V: VTable>(&self) -> bool {
129 self.as_opt::<V>().is_some()
130 }
131
132 pub fn as_<V: VTable>(&self) -> &V::Encoding {
133 self.as_opt::<V>()
134 .vortex_expect("LayoutEncoding is not of the expected type")
135 }
136
137 pub fn as_opt<V: VTable>(&self) -> Option<&V::Encoding> {
138 self.as_any()
139 .downcast_ref::<LayoutEncodingAdapter<V>>()
140 .map(|e| &e.0)
141 }
142}
143
144mod private {
145 use super::*;
146 use crate::layouts::foreign::ForeignLayoutEncoding;
147
148 pub trait Sealed {}
149
150 impl<V: VTable> Sealed for LayoutEncodingAdapter<V> {}
151 impl Sealed for ForeignLayoutEncoding {}
152}