Write files HDF5 1.8 can read: FileWriter/FileBuilder::libver_bounds
New `LibVer` (V18, V110, V112, V114, V200, Latest) and
`libver_bounds(low, high)` on the format crate's `FileWriter` and the
facade's `FileBuilder`, as libhdf5's H5Pset_libver_bounds / h5py's
libver=(low, high). The default stays (V110, Latest), byte for byte what
was written before.
With a low bound of 1.8: superblock version 2, layout message version 3
(contiguous, compact, chunked) and a version-1 B-tree chunk index for
every chunked dataset, resizable ones included -- what libhdf5 2.x writes
under libver=('v108', 'latest'). The new chunk B-tree writer
(btree_v1_write.rs) replays H5B_insert with the H5Dbtree.c callbacks for
row-major insertion (split ratios 0.1/0.5/0.9, right keys moved as
H5D__btree_cmp3 moves them, root kept in place): its trees equal
libhdf5's node for node for 1-D/2-D/3-D, 2- and 3-level, filtered and
unfiltered datasets (libhdf5 writing without a chunk cache).
The high bound refuses, with FormatError::LibverBound before anything is
written, what needs a newer format: virtual datasets and the paged
file-space strategy (1.10), the 1.12 reference types (datatype v4),
native complex (datatype v5, HDF5 2.0), and a low bound above the high.
Tests: tools/tests/libver_v18.rs writes every writer feature under
(V18, V18), and HDF5 1.8.23's h5dump (scripts/build-hdf5-1.8.sh; skipped
when absent) dumps it exactly as h5dump 1.14 does and returns our bytes
for every numeric dataset; h5py, clawhdf5 and h5rs check --data agree;
then FileEditor grows/appends/annotates it and h5py appends, and every
reader checks again. read_harness gains --v18 and --chunk N.
Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]>
This commit is contained in:
@@ -167,6 +167,19 @@ pub enum FormatError {
|
||||
VlDataError(String),
|
||||
/// Serialization error.
|
||||
SerializationError(String),
|
||||
/// The file's library version bounds
|
||||
/// ([`FileWriter::libver_bounds`](crate::file_writer::FileWriter::libver_bounds))
|
||||
/// do not allow what was asked for: `what` needs the format of HDF5
|
||||
/// `needs` or later, and the high bound is `high` (or the low bound is
|
||||
/// above the high one, with `needs` the low bound).
|
||||
LibverBound {
|
||||
/// What cannot be written.
|
||||
what: String,
|
||||
/// The oldest release whose format holds it.
|
||||
needs: crate::libver::LibVer,
|
||||
/// The file's high bound.
|
||||
high: crate::libver::LibVer,
|
||||
},
|
||||
/// Dataset is missing data.
|
||||
DatasetMissingData,
|
||||
/// Dataset is missing shape.
|
||||
@@ -450,6 +463,13 @@ impl fmt::Display for FormatError {
|
||||
FormatError::SerializationError(msg) => {
|
||||
write!(f, "serialization error: {msg}")
|
||||
}
|
||||
FormatError::LibverBound { what, needs, high } => {
|
||||
write!(
|
||||
f,
|
||||
"{what} needs the HDF5 {needs} file format, above the high \
|
||||
library version bound ({high})"
|
||||
)
|
||||
}
|
||||
FormatError::DatasetMissingData => {
|
||||
write!(f, "dataset is missing data")
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user