Skip to content

Commit e33f8d3

Browse files
committed
ViewedLayoutChildren child layout cache
Signed-off-by: Mikhail Kot <mikhail@spiraldb.com>
1 parent 679fc05 commit e33f8d3

1 file changed

Lines changed: 60 additions & 41 deletions

File tree

vortex-layout/src/children.rs

Lines changed: 60 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ use std::sync::Arc;
77

88
use flatbuffers::Follow;
99
use itertools::Itertools;
10+
use once_cell::sync::OnceCell;
1011
use vortex_array::dtype::DType;
1112
use vortex_error::VortexResult;
1213
use vortex_error::vortex_bail;
@@ -105,6 +106,7 @@ pub(crate) struct ViewedLayoutChildren {
105106
layout_read_ctx: ReadContext,
106107
layouts: LayoutRegistry,
107108
allow_unknown: bool,
109+
cache: Arc<[OnceCell<LayoutRef>]>,
108110
}
109111

110112
impl ViewedLayoutChildren {
@@ -121,13 +123,22 @@ impl ViewedLayoutChildren {
121123
layouts: LayoutRegistry,
122124
allow_unknown: bool,
123125
) -> Self {
126+
// SAFETY: guaranteed by caller
127+
let nchildren = unsafe {
128+
fbl::Layout::follow(flatbuffer.as_ref(), flatbuffer_loc)
129+
.children()
130+
.unwrap_or_default()
131+
.len()
132+
};
133+
let cache = vec![OnceCell::new(); nchildren].into_boxed_slice().into();
124134
Self {
125135
flatbuffer,
126136
flatbuffer_loc,
127137
array_read_ctx,
128138
layout_read_ctx,
129139
layouts,
130140
allow_unknown,
141+
cache,
131142
}
132143
}
133144

@@ -181,50 +192,58 @@ impl LayoutChildren for ViewedLayoutChildren {
181192
}
182193

183194
fn child(&self, idx: usize, dtype: &DType) -> VortexResult<LayoutRef> {
184-
if idx >= self.nchildren() {
185-
vortex_bail!("Child index out of bounds: {} of {}", idx, self.nchildren());
195+
if idx >= self.cache.len() {
196+
vortex_bail!("Child index out of bounds: {} of {}", idx, self.cache.len());
186197
}
187-
let fb_child = self.flatbuffer().children().unwrap_or_default().get(idx);
188-
189-
let viewed_children = ViewedLayoutChildren {
190-
flatbuffer: self.flatbuffer.clone(),
191-
flatbuffer_loc: fb_child._tab.loc(),
192-
array_read_ctx: self.array_read_ctx.clone(),
193-
layout_read_ctx: self.layout_read_ctx.clone(),
194-
layouts: self.layouts.clone(),
195-
allow_unknown: self.allow_unknown,
196-
};
197198

198-
let encoding_id = self
199-
.layout_read_ctx
200-
.resolve(fb_child.encoding())
201-
.ok_or_else(|| vortex_err!("Encoding not found: {}", fb_child.encoding()))?;
202-
let Some(encoding) = self.layouts.find(&encoding_id) else {
203-
if self.allow_unknown {
204-
return viewed_children.foreign_layout_from_fb(fb_child, dtype);
205-
}
206-
return Err(vortex_err!(
207-
"Encoding not found in registry: {}",
208-
fb_child.encoding()
209-
));
210-
};
199+
let layout_ref = self.cache[idx].get_or_try_init(|| {
200+
let fb_child = self.flatbuffer().children().unwrap_or_default().get(idx);
211201

212-
encoding.build(
213-
dtype,
214-
fb_child.row_count(),
215-
fb_child
216-
.metadata()
217-
.map(|m| m.bytes())
218-
.unwrap_or_else(|| &[]),
219-
fb_child
220-
.segments()
221-
.unwrap_or_default()
222-
.iter()
223-
.map(SegmentId::from)
224-
.collect_vec(),
225-
&viewed_children,
226-
&self.array_read_ctx,
227-
)
202+
// SAFETY: same validated flatbuffer; fb_child._tab.loc() is a valid offset
203+
// We need this to avoid re-initializing cache here
204+
let viewed_children = unsafe {
205+
ViewedLayoutChildren::new_unchecked(
206+
self.flatbuffer.clone(),
207+
fb_child._tab.loc(),
208+
self.array_read_ctx.clone(),
209+
self.layout_read_ctx.clone(),
210+
self.layouts.clone(),
211+
self.allow_unknown,
212+
)
213+
};
214+
215+
let encoding_id = self
216+
.layout_read_ctx
217+
.resolve(fb_child.encoding())
218+
.ok_or_else(|| vortex_err!("Encoding not found: {}", fb_child.encoding()))?;
219+
let Some(encoding) = self.layouts.find(&encoding_id) else {
220+
if self.allow_unknown {
221+
return viewed_children.foreign_layout_from_fb(fb_child, dtype);
222+
}
223+
return Err(vortex_err!(
224+
"Encoding not found in registry: {}",
225+
fb_child.encoding()
226+
));
227+
};
228+
229+
encoding.build(
230+
dtype,
231+
fb_child.row_count(),
232+
fb_child
233+
.metadata()
234+
.map(|m| m.bytes())
235+
.unwrap_or_else(|| &[]),
236+
fb_child
237+
.segments()
238+
.unwrap_or_default()
239+
.iter()
240+
.map(SegmentId::from)
241+
.collect_vec(),
242+
&viewed_children,
243+
&self.array_read_ctx,
244+
)
245+
})?;
246+
Ok(Arc::clone(layout_ref))
228247
}
229248

230249
fn child_row_count(&self, idx: usize) -> u64 {

0 commit comments

Comments
 (0)