Merge branch 'perf/wasm-listing-passes' into feat/listing-header-last-files
# Conflicts: # CHANGELOG.md
This commit is contained in:
@@ -163,6 +163,12 @@ impl ObjectHeader {
|
||||
offset_size: u8,
|
||||
length_size: u8,
|
||||
) -> Result<ObjectHeader, FormatError> {
|
||||
// The first chunk is read once the prefix says how long it is: say
|
||||
// so (see `Storage::hint`), for a storage that fetches between
|
||||
// attempts.
|
||||
if file.as_contiguous().is_none() {
|
||||
file.hint(offset, OBJECT_HEADER_HINT_LEN);
|
||||
}
|
||||
// The longest prefix of either version, in one read. It holds the
|
||||
// whole prefix or ends at the end of the file, so its bounds checks
|
||||
// are the whole-file ones.
|
||||
@@ -279,10 +285,20 @@ impl ObjectHeader {
|
||||
let mut spans = ChunkSpans::new(file.len(), offset, length)?;
|
||||
let mut chunk0_count = 0usize;
|
||||
let mut next = 0usize;
|
||||
let hints = file.as_contiguous().is_none();
|
||||
while let Some((chunk_offset, chunk_length)) = spans.get(next) {
|
||||
let chunk = read_exact_at(file, chunk_offset, chunk_length)?;
|
||||
let known = spans.len;
|
||||
let count =
|
||||
Self::parse_v1_messages(&chunk, offset_size, length_size, messages, &mut spans)?;
|
||||
// The continuation chunks this one names are read next.
|
||||
if hints {
|
||||
for i in known..spans.len {
|
||||
if let Some((o, l)) = spans.get(i) {
|
||||
file.hint(o, l);
|
||||
}
|
||||
}
|
||||
}
|
||||
// Only the first chunk's messages are held to the prefix count.
|
||||
if next == 0 {
|
||||
chunk0_count = count;
|
||||
@@ -483,8 +499,17 @@ impl ObjectHeader {
|
||||
// whenever a message no longer fits), up to the same bound as a
|
||||
// version-1 header.
|
||||
let mut spans = ChunkSpans::new(file.len(), base as u64, chunk0_msg_end.saturating_add(4))?;
|
||||
// The continuation chunks a chunk names are read next (see
|
||||
// `Storage::hint`).
|
||||
let hints = file.as_contiguous().is_none();
|
||||
if hints {
|
||||
for &(o, l) in &continuations {
|
||||
file.hint(o as u64, l);
|
||||
}
|
||||
}
|
||||
while let Some((cont_offset, cont_length)) = continuations.pop() {
|
||||
spans.add(cont_offset as u64, cont_length)?;
|
||||
let known = continuations.len();
|
||||
Self::parse_v2_continuation(
|
||||
file,
|
||||
cont_offset as u64,
|
||||
@@ -495,6 +520,11 @@ impl ObjectHeader {
|
||||
&mut messages,
|
||||
&mut continuations,
|
||||
)?;
|
||||
if hints {
|
||||
for &(o, l) in &continuations[known..] {
|
||||
file.hint(o as u64, l);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Ok(ObjectHeader {
|
||||
@@ -640,6 +670,11 @@ impl ObjectHeader {
|
||||
}
|
||||
}
|
||||
|
||||
/// What an object header is hinted to take before its prefix is read (see
|
||||
/// [`Storage::hint`]): the first chunk of a typical dataset's header. A
|
||||
/// longer header is read all the same.
|
||||
pub(crate) const OBJECT_HEADER_HINT_LEN: usize = 512;
|
||||
|
||||
/// Longest version-2 object header prefix: signature(4) + version(1) +
|
||||
/// flags(1) + times(16) + attribute phase change(4) + chunk-0 size(8).
|
||||
const V2_PREFIX_MAX: usize = 34;
|
||||
|
||||
Reference in New Issue
Block a user