vortex_layout/
children.rs1use std::fmt::{Debug, Formatter};
2use std::sync::Arc;
3
4use flatbuffers::Follow;
5use itertools::Itertools;
6use vortex_dtype::DType;
7use vortex_error::{VortexResult, vortex_bail, vortex_err, vortex_panic};
8use vortex_flatbuffers::{FlatBuffer, layout as fbl};
9
10use crate::segments::SegmentId;
11use crate::{LayoutContext, LayoutRef};
12
13pub trait LayoutChildren: 'static + Send + Sync {
18 fn to_arc(&self) -> Arc<dyn LayoutChildren>;
19
20 fn child(&self, idx: usize, dtype: &DType) -> VortexResult<LayoutRef>;
21
22 fn child_row_count(&self, idx: usize) -> u64;
23
24 fn nchildren(&self) -> usize;
25}
26
27impl Debug for dyn LayoutChildren {
28 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
29 f.debug_struct("LayoutChildren")
30 .field("nchildren", &self.nchildren())
31 .finish()
32 }
33}
34
35impl LayoutChildren for Arc<dyn LayoutChildren> {
36 fn to_arc(&self) -> Arc<dyn LayoutChildren> {
37 self.clone()
38 }
39
40 fn child(&self, idx: usize, dtype: &DType) -> VortexResult<LayoutRef> {
41 self.as_ref().child(idx, dtype)
42 }
43
44 fn child_row_count(&self, idx: usize) -> u64 {
45 self.as_ref().child_row_count(idx)
46 }
47
48 fn nchildren(&self) -> usize {
49 self.as_ref().nchildren()
50 }
51}
52
53#[derive(Clone)]
56pub(crate) struct OwnedLayoutChildren(Vec<LayoutRef>);
57
58impl OwnedLayoutChildren {
59 pub fn layout_children(children: Vec<LayoutRef>) -> Arc<dyn LayoutChildren> {
60 Arc::new(Self(children))
61 }
62}
63
64impl LayoutChildren for OwnedLayoutChildren {
66 fn to_arc(&self) -> Arc<dyn LayoutChildren> {
67 Arc::new(self.clone())
68 }
69
70 fn child(&self, idx: usize, dtype: &DType) -> VortexResult<LayoutRef> {
71 if idx >= self.0.len() {
72 vortex_bail!("Child index out of bounds: {} of {}", idx, self.0.len());
73 }
74 let child = &self.0[idx];
75 if child.dtype() != dtype {
76 vortex_panic!("Child dtype mismatch: {} != {}", child.dtype(), dtype);
77 }
78 Ok(child.clone())
79 }
80
81 fn child_row_count(&self, idx: usize) -> u64 {
82 self.0[idx].row_count()
83 }
84
85 fn nchildren(&self) -> usize {
86 self.0.len()
87 }
88}
89
90#[derive(Clone)]
91pub(crate) struct ViewedLayoutChildren {
92 flatbuffer: FlatBuffer,
93 flatbuffer_loc: usize,
94 ctx: LayoutContext,
95}
96
97impl ViewedLayoutChildren {
98 pub(super) unsafe fn new_unchecked(
104 flatbuffer: FlatBuffer,
105 flatbuffer_loc: usize,
106 ctx: LayoutContext,
107 ) -> Self {
108 Self {
109 flatbuffer,
110 flatbuffer_loc,
111 ctx,
112 }
113 }
114
115 fn flatbuffer(&self) -> fbl::Layout<'_> {
117 unsafe { fbl::Layout::follow(self.flatbuffer.as_ref(), self.flatbuffer_loc) }
118 }
119}
120
121impl LayoutChildren for ViewedLayoutChildren {
122 fn to_arc(&self) -> Arc<dyn LayoutChildren> {
123 Arc::new(self.clone())
124 }
125
126 fn child(&self, idx: usize, dtype: &DType) -> VortexResult<LayoutRef> {
127 if idx >= self.nchildren() {
128 vortex_bail!("Child index out of bounds: {} of {}", idx, self.nchildren());
129 }
130 let fb_child = self.flatbuffer().children().unwrap_or_default().get(idx);
131
132 let viewed_children = ViewedLayoutChildren {
133 flatbuffer: self.flatbuffer.clone(),
134 flatbuffer_loc: fb_child._tab.loc(),
135 ctx: self.ctx.clone(),
136 };
137 let encoding = self
138 .ctx
139 .lookup_encoding(fb_child.encoding())
140 .ok_or_else(|| vortex_err!("Encoding not found: {}", fb_child.encoding()))?;
141
142 encoding.build(
143 dtype,
144 fb_child.row_count(),
145 fb_child
146 .metadata()
147 .map(|m| m.bytes())
148 .unwrap_or_else(|| &[]),
149 fb_child
150 .segments()
151 .unwrap_or_default()
152 .iter()
153 .map(SegmentId::from)
154 .collect_vec(),
155 &viewed_children,
156 )
157 }
158
159 fn child_row_count(&self, idx: usize) -> u64 {
160 self.flatbuffer()
163 .children()
164 .unwrap_or_default()
165 .get(idx)
166 .row_count()
167 }
168
169 fn nchildren(&self) -> usize {
170 self.flatbuffer().children().unwrap_or_default().len()
171 }
172}