v0.7.0
Changelog: https://github.com/stephenberry/hdf5-pure/blob/v0.7.0/CHANGELOG.md
Added
- SWMR (single-writer / multiple-reader) support for one-dimensional, unlimited, Extensible-Array-indexed datasets (#17).
- Refreshing reader.
File::open_swmr(path)retains a live file handle andFile::refresh()re-reads data appended by a concurrent writer, then re-parses the superblock; datasets fetched after a refresh observe the appended chunks and the extended dimension. Interoperates as a consumer of files written by the reference C library or h5py in SWMR mode. - In-place append writer.
SwmrWriter::open(path)opens an existing latest-format file (created by this crate, the C library, or h5py), sets the superblock SWMR-write flag, andappend_i32/append_f64/append_rawappend chunks to an unlimited dataset in place: each chunk is written at end-of-file, its address stored into the next free chunk-index slot, the index grown by appending new data blocks, super blocks, and paged data blocks only when a block boundary is crossed (never relocating existing data), and the dataspace dimension, array-header counts, and superblock end-of-file patched. Writes are ordered child-before-parent (raw data → superblock end-of-file → chunk-index count → dataspace dimension) with anfsyncbarrier after each phase, so an interrupted append or a concurrent reader only ever observes a consistent prefix; the reader bounds chunk reads by the published count and dimension to ignore slots a writer wrote ahead of the commit. Growth is unbounded (super blocks and paged data blocks past 131060 chunks are allocated incrementally).close()clears the SWMR flag;SwmrWriter::clear_swmr_flag(path)recovers a file left flagged by a crashed writer. Reopening a file after a writer crashed mid-append rolls forward from the last committed length (the dataspace dimension), overwriting any chunks a previous writer wrote but never committed, so a recovered append never leaves a gap or resurfaces uncommitted data. - Verified interop. Cross-checked against the reference C library in both directions (hdf5-pure appends → C reads; C creates → hdf5-pure appends → C reads) across the inline, direct-block, super-block, and paged ranges, and end-to-end with h5py: h5py opens the file with
swmr=Trueand reads hdf5-pure's appended data while the writer holds it open. - Current subset: unfiltered datasets, chunk-aligned appends, a single unlimited dimension, and no userblock. Unsupported targets (a filtered dataset, a non-rank-1 or non-Extensible-Array dataset, or a non-latest-format v0/v1 superblock) are rejected up front with a specific
Error::SwmrAppendUnsupported(reason)and the file is left unmodified, rather than producing an inconsistent file. An append that fails partway (including an underlying I/O error) never publishes the new length, so a reader still sees the prior consistent prefix. SWMR read/append require thestdfilesystem and are unavailable on the in-memory/WASM path.
- Refreshing reader.
Changed
- The public
ErrorandFormatErrorenums are now#[non_exhaustive]. Downstream code that matches them must include a wildcard (_ =>) arm. This is a one-time break that makes every future variant addition non-breaking; constructing andmatches!-testing existing variants is unaffected.
Fixed
- Extensible Array chunk index (used for chunked datasets with one unlimited dimension): reading a dataset with more than 20 chunks along the unlimited axis silently returned wrong data, and writing more than 244 chunks silently dropped the excess. The reader's data-block size progression did not match the HDF5 format (it diverged past the inline elements plus the first data block), and the writer never emitted super blocks or paged data blocks. Reader and writer now share a single block-size geometry derived from the array's creation parameters; the writer emits super blocks and, above 131060 chunks, paged data blocks; and the array header statistics match the reference C library byte-for-byte. Verified against the reference C HDF5 library in both directions across the inline, direct-block, super-block, and paged ranges. Found while implementing SWMR support (#17).