Carry an extent hint on batch returns

This commit is contained in:
Dennis Kobert
2026-08-21 12:32:57 +00:00
parent 61cf619f4b
commit e68254eff3
6 changed files with 46 additions and 20 deletions

View File

@@ -7,11 +7,15 @@ use std::ops::Range;
#[derive(Debug)]
pub enum BatchStatus<'a> {
/// Producer-resident lanes, shared: read-only for the caller.
Lent(RecordBatch<'a>, Finality),
/// Producer-resident lanes, shared: read-only for the caller. The extent
/// is the producer's knowledge of the level's total after serving the
/// range: a sound lower bound, or exact; a batch shorter than the
/// requested range carries `Exactly` and marks the end of the data.
Lent(RecordBatch<'a>, Finality, Extent),
/// The caller's scratch, filled: the caller is the exclusive owner and may
/// mutate the lanes or reclaim the buffer for in-place reuse.
Filled(RecordBatchMut<'a>, Finality),
/// mutate the lanes or reclaim the buffer for in-place reuse. The extent
/// hint is as for `Lent`.
Filled(RecordBatchMut<'a>, Finality, Extent),
/// No batch implementation behind this edge; a driver answers with the
/// per-lane eval and copy-out loop ([`crate::record::fill_frames`]).
Unbatched,

View File

@@ -499,6 +499,8 @@ where
let base = scratch.as_mut_ptr().cast::<u8>();
let mut local = *input;
let mut finality = crate::gpoll::Finality::AllFinal;
let mut filled = len;
let mut hint = crate::gpoll::Extent::AtLeast(range.end as usize);
for lane in 0..len {
local.set_index(range.start + lane as u64);
let mark = stack::sp();
@@ -510,6 +512,16 @@ where
}
GPoll::Pending => return BatchStatus::Pending,
GPoll::Fallback(boxed) => return BatchStatus::Error(boxed.1),
// A lane past a lower-bound level ends the data: the fill comes
// back short and the hint turns exact.
GPoll::Error(error) if error.kind == crate::gpoll::ErrorKind::PastEnd => {
filled = lane;
hint = crate::gpoll::Extent::Exactly(range.start as usize + lane);
// SAFETY: the failed lane produced no record, so nothing above
// its mark is live.
unsafe { stack::rewind(mark) };
break;
}
GPoll::Error(error) => return BatchStatus::Error(*error),
};
// SAFETY: the lane region is in-bounds by the scratch check, and the
@@ -519,8 +531,8 @@ where
stack::rewind(mark);
}
}
// SAFETY: all `len` lanes were filled above with records of `layout`.
BatchStatus::Filled(unsafe { crate::node::RecordBatchMut::new(scratch, len, layout) }, finality)
// SAFETY: the first `filled` lanes were filled above with records of `layout`.
BatchStatus::Filled(unsafe { crate::node::RecordBatchMut::new(scratch, filled, layout) }, finality, hint)
}
/// The driver a consumer runs on a record edge: a resident batch returns with