1use std::any::Any;
5use std::fmt::{Debug, Formatter};
6use std::sync::Arc;
7
8use arcref::ArcRef;
9use itertools::Itertools;
10use vortex_array::SerializeMetadata;
11use vortex_dtype::{DType, FieldName};
12use vortex_error::{VortexExpect, VortexResult, vortex_err};
13
14use crate::segments::{SegmentId, SegmentSource};
15use crate::{LayoutEncodingId, LayoutEncodingRef, LayoutReaderRef, VTable};
16
17pub type LayoutId = ArcRef<str>;
18
19pub type LayoutRef = Arc<dyn Layout>;
20
21pub trait Layout: 'static + Send + Sync + Debug + private::Sealed {
22 fn as_any(&self) -> &dyn Any;
23
24 fn as_any_arc(self: Arc<Self>) -> Arc<dyn Any + Send + Sync>;
25
26 fn to_layout(&self) -> LayoutRef;
27
28 fn encoding(&self) -> LayoutEncodingRef;
30
31 fn row_count(&self) -> u64;
33
34 fn dtype(&self) -> &DType;
36
37 fn nchildren(&self) -> usize;
39
40 fn child(&self, idx: usize) -> VortexResult<LayoutRef>;
42
43 fn child_type(&self, idx: usize) -> LayoutChildType;
46
47 fn metadata(&self) -> Vec<u8>;
49
50 fn segment_ids(&self) -> Vec<SegmentId>;
52
53 fn new_reader(
54 &self,
55 name: Arc<str>,
56 segment_source: Arc<dyn SegmentSource>,
57 ) -> VortexResult<LayoutReaderRef>;
58}
59
60pub trait IntoLayout {
61 fn into_layout(self) -> LayoutRef;
63}
64
65#[derive(Debug, Clone, PartialEq, Eq)]
67pub enum LayoutChildType {
68 Transparent(Arc<str>),
70 Auxiliary(Arc<str>),
73 Chunk((usize, u64)),
76 Field(FieldName),
79 }
85
86impl LayoutChildType {
87 pub fn name(&self) -> Arc<str> {
89 match self {
90 LayoutChildType::Chunk((idx, _offset)) => format!("[{idx}]").into(),
91 LayoutChildType::Auxiliary(name) => name.clone(),
92 LayoutChildType::Transparent(name) => name.clone(),
93 LayoutChildType::Field(name) => name.clone(),
94 }
95 }
96
97 pub fn row_offset(&self) -> Option<u64> {
100 match self {
101 LayoutChildType::Chunk((_idx, offset)) => Some(*offset),
102 LayoutChildType::Auxiliary(_) => None,
103 LayoutChildType::Transparent(_) => Some(0),
104 LayoutChildType::Field(_) => Some(0),
105 }
106 }
107}
108
109impl dyn Layout + '_ {
110 pub fn encoding_id(&self) -> LayoutEncodingId {
112 self.encoding().id()
113 }
114
115 pub fn children(&self) -> VortexResult<Vec<LayoutRef>> {
117 (0..self.nchildren()).map(|i| self.child(i)).try_collect()
118 }
119
120 pub fn child_types(&self) -> impl Iterator<Item = LayoutChildType> {
122 (0..self.nchildren()).map(|i| self.child_type(i))
123 }
124
125 pub fn child_names(&self) -> impl Iterator<Item = Arc<str>> {
127 self.child_types().map(|child| child.name())
128 }
129
130 pub fn child_row_offsets(&self) -> impl Iterator<Item = Option<u64>> {
132 self.child_types().map(|child| child.row_offset())
133 }
134
135 pub fn is<V: VTable>(&self) -> bool {
136 self.as_opt::<V>().is_some()
137 }
138
139 pub fn as_<V: VTable>(&self) -> &V::Layout {
141 self.as_opt::<V>().vortex_expect("Failed to downcast")
142 }
143
144 pub fn as_opt<V: VTable>(&self) -> Option<&V::Layout> {
146 self.as_any()
147 .downcast_ref::<LayoutAdapter<V>>()
148 .map(|adapter| &adapter.0)
149 }
150
151 pub fn into<V: VTable>(self: Arc<Self>) -> Arc<V::Layout> {
153 let layout_adapter = self
154 .as_any_arc()
155 .downcast::<LayoutAdapter<V>>()
156 .map_err(|_| vortex_err!("Invalid layout type"))
157 .vortex_expect("Invalid layout type");
158
159 unsafe { std::mem::transmute::<Arc<LayoutAdapter<V>>, Arc<V::Layout>>(layout_adapter) }
162 }
163
164 pub fn depth_first_traversal(&self) -> impl Iterator<Item = VortexResult<LayoutRef>> {
166 struct ChildrenIterator {
168 stack: Vec<LayoutRef>,
169 }
170
171 impl Iterator for ChildrenIterator {
172 type Item = VortexResult<LayoutRef>;
173
174 fn next(&mut self) -> Option<Self::Item> {
175 let next = self.stack.pop()?;
176 let Ok(children) = next.children() else {
177 return Some(Ok(next));
178 };
179 for child in children.into_iter().rev() {
180 self.stack.push(child);
181 }
182 Some(Ok(next))
183 }
184 }
185
186 ChildrenIterator {
187 stack: vec![self.to_layout()],
188 }
189 }
190}
191
192#[repr(transparent)]
193pub struct LayoutAdapter<V: VTable>(V::Layout);
194
195impl<V: VTable> Debug for LayoutAdapter<V> {
196 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
197 self.0.fmt(f)
198 }
199}
200
201impl<V: VTable> Layout for LayoutAdapter<V> {
202 fn as_any(&self) -> &dyn Any {
203 self
204 }
205
206 fn as_any_arc(self: Arc<Self>) -> Arc<dyn Any + Send + Sync> {
207 self
208 }
209
210 fn to_layout(&self) -> LayoutRef {
211 Arc::new(LayoutAdapter::<V>(self.0.clone()))
212 }
213
214 fn encoding(&self) -> LayoutEncodingRef {
215 V::encoding(&self.0)
216 }
217
218 fn row_count(&self) -> u64 {
219 V::row_count(&self.0)
220 }
221
222 fn dtype(&self) -> &DType {
223 V::dtype(&self.0)
224 }
225
226 fn nchildren(&self) -> usize {
227 V::nchildren(&self.0)
228 }
229
230 fn child(&self, idx: usize) -> VortexResult<LayoutRef> {
231 V::child(&self.0, idx)
232 }
233
234 fn child_type(&self, idx: usize) -> LayoutChildType {
235 V::child_type(&self.0, idx)
236 }
237
238 fn metadata(&self) -> Vec<u8> {
239 V::metadata(&self.0).serialize()
240 }
241
242 fn segment_ids(&self) -> Vec<SegmentId> {
243 V::segment_ids(&self.0)
244 }
245
246 fn new_reader(
247 &self,
248 name: Arc<str>,
249 segment_source: Arc<dyn SegmentSource>,
250 ) -> VortexResult<LayoutReaderRef> {
251 V::new_reader(&self.0, name, segment_source)
252 }
253}
254
255mod private {
256 use super::*;
257
258 pub trait Sealed {}
259
260 impl<V: VTable> Sealed for LayoutAdapter<V> {}
261}