fix(format): index every Extensible Array chunk, not just the first 244

The Extensible Array writer only filled the index block's 4 inline
elements and the 6 data blocks it addresses directly (240 elements); its
super block addresses were always undefined. Chunks from index 244 on were
written to the file but never indexed, so they read back as fill values in
our reader and in libhdf5, without an error.

The writer now lays out data blocks and super blocks for any element
count as H5EA__hdr_init sizes them, pages data blocks larger than 1024
elements (page-init bits in the owning super block), leaves blocks with no
defined element unallocated, and records real header statistics
(max_idx_set is one past the highest defined index).

Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]>
This commit is contained in:
osobh
2026-09-25 21:09:29 -05:00
co-authored by Claude Opus 5.5
parent 4a1876faf2
commit 44f5f8b5c5
3 changed files with 271 additions and 271 deletions
+5 -3
View File
@@ -503,7 +503,7 @@ fn serialize_v4_fixed_array(
/// default, `H5D_FARRAY_MAX_DBLK_PAGE_NELMTS_BITS`).
const FA_PAGE_BITS: u8 = 10;
fn push_addr(buf: &mut Vec<u8>, addr: u64, offset_size: u8) {
pub(crate) fn push_addr(buf: &mut Vec<u8>, addr: u64, offset_size: u8) {
match offset_size {
4 => buf.extend_from_slice(&(addr as u32).to_le_bytes()),
_ => buf.extend_from_slice(&addr.to_le_bytes()),
@@ -734,8 +734,9 @@ pub fn build_chunked_data_from_precompressed(
let layout_message = if use_extensible {
let ea_address = base_address + data_buf.len() as u64;
let slots: Vec<Option<WrittenChunk>> = written_chunks.iter().cloned().map(Some).collect();
let ea_bytes = ea_writer::build_extensible_array_at(
&written_chunks,
&slots,
offset_size,
length_size,
pre.has_filters,
@@ -1463,7 +1464,8 @@ mod tests {
filter_mask: 0,
},
];
let ea = ea_writer::build_extensible_array_at(&chunks, 8, 8, false, 0x2000);
let slots: Vec<_> = chunks.into_iter().map(Some).collect();
let ea = ea_writer::build_extensible_array_at(&slots, 8, 8, false, 0x2000);
assert_eq!(&ea[0..4], b"EAHD");
// Find EAIB after EAHD: 12 fixed + 6*8 stats + 8 addr + 4 checksum = 72
let aehd_size = 4 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 6 * 8 + 8 + 4;