format: in-memory fast path in the Storage read helpers

read_exact_at and read_upto (and so Window::read) ask as_contiguous()
first and slice the file directly when the backend holds it in memory:
one dynamic call per structure read instead of two or three (len,
read_at, then len again for errors). Same results and errors.

Provisional (busy machine, not for docs): a listing that walks 400
symbol-table groups through the facade went from about 18% to about 14%
slower than before the Storage conversion; the extra cost is a few tens
of nanoseconds per structure read, which the facade's per-lookup
re-listing (range-reads.md M0) multiplies.

Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]>
This commit is contained in:
osobh
2026-09-26 13:41:26 -05:00
co-authored by Claude Opus 5.5
parent 5d17712adb
commit d2b25f154f
+13
View File
@@ -198,6 +198,14 @@ pub fn read_exact_at(
.saturating_add(len),
available: len_usize(file),
};
// In-memory fast path: one dynamic call, then plain slicing.
if let Some(all) = file.as_contiguous() {
return usize::try_from(offset)
.ok()
.and_then(|start| all.get(start..start.checked_add(len)?))
.map(Cow::Borrowed)
.ok_or_else(eof);
}
match offset.checked_add(len as u64) {
Some(end) if end <= file.len() => {}
_ => return Err(eof()),
@@ -271,6 +279,11 @@ pub fn read_upto(
offset: u64,
max: usize,
) -> Result<Cow<'_, [u8]>, FormatError> {
if let Some(all) = file.as_contiguous() {
let start = usize::try_from(offset).map_or(all.len(), |o| o.min(all.len()));
let end = start.saturating_add(max).min(all.len());
return Ok(Cow::Borrowed(&all[start..end]));
}
let avail = file.len().saturating_sub(offset);
let len = usize::try_from(avail).map_or(max, |a| a.min(max));
let bytes = file.read_at(offset, len)?;