fix(format): write layout v4 chunk dimensions in the fewest bytes
libhdf5 encodes a version-4 layout's chunk dimensions in (log2(max) + 8) / 8 bytes, and HDF5 2.0.0 (h5py 3.16) refuses any other width: "stored chunk dimension encoding length does not match value calculated from chunk dimensions". The writer rounded 3 bytes up to 4, so h5py could not open a dataset we wrote with a chunk dimension from 65 536 to 16 777 215, for every chunk index (single chunk, fixed and extensible array, v2 B-tree). The three encoders now share push_v4_chunk_dims, which writes the exact width. Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]>
This commit is contained in:
@@ -515,6 +515,31 @@ fn we_write_maxshape_larger_than_shape() {
|
||||
check_we_write(&cases);
|
||||
}
|
||||
|
||||
/// A version-4 layout must encode every chunk dimension in the fewest bytes
|
||||
/// that hold the largest one, as libhdf5 does: HDF5 2.0.0 (h5py 3.16)
|
||||
/// refuses a wider encoding ("stored chunk dimension encoding length does
|
||||
/// not match value calculated from chunk dimensions"). We rounded 3 bytes
|
||||
/// up to 4, so h5py could not open any dataset we wrote with a chunk
|
||||
/// dimension from 65 536 to 16 777 215.
|
||||
#[test]
|
||||
fn we_write_chunk_dimensions_in_the_fewest_bytes() {
|
||||
const U: u64 = u64::MAX;
|
||||
let mut cases = vec![
|
||||
// Single chunk, Fixed Array, Extensible Array, v2 B-tree.
|
||||
wcase("single_70000", &[70_000], &[70_000], None),
|
||||
wcase("fa_70000", &[140_000], &[70_000], None),
|
||||
wcase("ea_70000", &[140_000], &[70_000], Some(&[U])),
|
||||
wcase("bt2_70000", &[2, 70_000], &[1, 70_000], Some(&[U, U])),
|
||||
// 2 bytes and 1 byte still, with the element size (4) the largest.
|
||||
wcase("fa_300", &[600], &[300], None),
|
||||
wcase("fa_3", &[6], &[3], None),
|
||||
];
|
||||
let mut filtered = wcase("single_70000_deflate", &[70_000], &[70_000], None);
|
||||
filtered.deflate = true;
|
||||
cases.push(filtered);
|
||||
check_we_write(&cases);
|
||||
}
|
||||
|
||||
/// More than one unlimited dimension needs a version-2 B-tree chunk index,
|
||||
/// as the library uses; an Extensible Array for `(None, None)` made libhdf5
|
||||
/// refuse the whole file ("already found unlimited dimension").
|
||||
|
||||
Reference in New Issue
Block a user