From ca831c00db9ec3e742257dbcc7e0df0455ed86a9 Mon Sep 17 00:00:00 2001 From: Dennis Kobert Date: Sat, 29 Aug 2026 22:07:27 +0000 Subject: [PATCH] Promote a materialized batch into a target region --- node-graph/libraries/core-types/src/record.rs | 32 +++++++++++++++++++ 1 file changed, 32 insertions(+) diff --git a/node-graph/libraries/core-types/src/record.rs b/node-graph/libraries/core-types/src/record.rs index 5c1687380b..bb325c625a 100644 --- a/node-graph/libraries/core-types/src/record.rs +++ b/node-graph/libraries/core-types/src/record.rs @@ -1801,6 +1801,38 @@ impl MaterializedSpan { } } + /// Copies the batch into `arena`, re-parking every payload its records + /// reference so the span's bytes reference nothing outside that region. + /// `None` where the region could not hold the copy, which leaves the + /// caller with nothing to cache. + /// + /// # Safety + /// The batch's lanes must be live records of its layout. + pub unsafe fn promote(batch: &crate::node::RecordBatch<'_>, arena: &crate::arena::Arena) -> Option { + let layout = batch.layout(); + let stride = layout.lane_stride(); + let len = batch.len(); + if len == 0 { + return Some(MaterializedSpan { + base: crate::arena::ArenaWeak::NULL, + len: 0, + }); + } + let slab = arena.alloc_scratch::((len * stride).div_ceil(8))?; + let base: *mut u8 = slab.as_mut_ptr().cast(); + for lane in 0..len { + // SAFETY: the caller's contract on the batch's lanes. + let owned = unsafe { OwnedRecord::copy_out(layout, batch.get(lane).rec()) }; + // SAFETY: the lane's own region of the freshly reserved slab. + let dst = unsafe { base.add(lane * stride) }; + owned.write_into(layout, dst, arena)?; + } + Some(MaterializedSpan { + base: arena.handle_at(base.cast_const())?, + len, + }) + } + /// The span's lanes at `layout`, or `None` once the generation moved on. pub fn batch<'a>(&self, arena: &'a crate::arena::Arena, layout: &'a Layout) -> Option> { let base: *const u8 = match self.len {