mirror of
https://github.com/GraphiteEditor/Graphite.git
synced 2026-09-15 22:28:10 +08:00
Carry an extent hint on batch returns
This commit is contained in:
@@ -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,
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user