pub struct H5FileOptions { /* private fields */ }Expand description
Builder controlling how an H5File is opened.
The default policy follows the HDF5 C library: an exclusive lock is
acquired for write-mode opens and a shared lock for read-mode opens,
honoring the HDF5_USE_FILE_LOCKING environment variable. Calling
Self::locking overrides the env-var value.
Implementations§
Source§impl H5FileOptions
impl H5FileOptions
Sourcepub fn locking(self, policy: FileLocking) -> Self
pub fn locking(self, policy: FileLocking) -> Self
Override the locking policy. Bypasses the HDF5_USE_FILE_LOCKING
environment variable for the resulting open call.
Sourcepub fn no_locking(self) -> Self
pub fn no_locking(self) -> Self
Disable OS-level file locking entirely (equivalent to
HDF5_USE_FILE_LOCKING=FALSE). Under the mmap feature such an open
reads through the descriptor rather than a map, which is taken only
under the shared lock, so a zero-copy view of it is refused.
Sourcepub fn best_effort_locking(self) -> Self
pub fn best_effort_locking(self) -> Self
Try to acquire the lock but do not fail if the filesystem rejects it
(equivalent to HDF5_USE_FILE_LOCKING=BEST_EFFORT).
Sourcepub fn elink_prefix(self, prefix: impl Into<String>) -> Self
pub fn elink_prefix(self, prefix: impl Into<String>) -> Self
H5Pset_elink_prefix (H5Plapl.c:923): a directory the target file
of an external link is looked for under, after HDF5_EXT_PREFIX and
before the linking file’s own directory — step 3 of
H5F_prefix_open_file’s order (H5Fint.c:938-950).
Unlike DatasetAccess::virtual_prefix, this
one is not shadowed by its environment variable and gets no
${ORIGIN} expansion: H5L__extern_traverse peeks the property
verbatim and hands it straight to the search (H5Lexternal.c:210-215),
with no H5D__build_file_prefix step in between. Measured against
libhdf5 1.14.6 and 2.0.0: with HDF5_EXT_PREFIX naming a directory
that has no target, this property still resolves it, while the same
arrangement for a virtual source does not; and a ${ORIGIN} written
here stays a literal directory name.
§Where this lives, and why not on the call
libhdf5 keeps it in a link access property list, an argument every
H5*_by_name call carries. Here it is a property of the open,
because that is the narrowest scope this crate can honour: a reader
resolves each external link’s file name once and then holds that
answer for its own life, so a prefix passed per call could not change
a name another call had already resolved. Making it file-scoped also
keeps it with the one other cross-file policy libhdf5 takes from a
property list and applies to every file a path touches — the locking
mode — and, like that one, it propagates down a chain of links, which
is what a lapl does upstream (measured: a two-hop chain resolves its
second hop under the prefix given at the first).
Read-side only: nothing the writer does traverses an external link.
Sourcepub fn track_order(self, track: bool) -> Self
pub fn track_order(self, track: bool) -> Self
Create the file’s root group with creation-order tracking, and make
that the policy for objects created in it — h5py’s
File(path, "w", track_order=True).
Only create reads this; opening an existing file
takes the policy from the root group already on disk. Change it for
later objects with H5File::set_track_order.
Sourcepub fn track_times(self, track: bool) -> Self
pub fn track_times(self, track: bool) -> Self
Create the file’s root group recording its times, and make that the
policy for objects created in it — H5Pset_obj_track_times, h5py’s
File(path, "w", track_times=True).
An object recording times keeps the ones its header version can hold:
four in a version-2 header’s prefix, one modification time in a
version-1 dataset’s H5O_MTIME_NEW message, and none at all in a
version-1 group or committed datatype, which have nowhere to put one.
Off unless this says otherwise — h5py’s default, not libhdf5’s. h5py’s
high-level API passes track_times=False for every object it makes
(_hl/files.py:189, _hl/dataset.py:39, _hl/group.py:42), while a
bare creation property list leaves it on (H5O_CRT_OHDR_FLAGS_DEF is
H5O_HDR_STORE_TIMES, H5Opkg.h:74), which is what h5py.h5d.create
and libhdf5’s own C API get.
Only create reads this; the root group of an existing
file was made under whatever created it. Change it for later objects
with H5File::set_track_times.
Sourcepub fn libver(self, libver: LibverBound) -> Self
pub fn libver(self, libver: LibverBound) -> Self
Create the file under a library-version low bound — h5py’s
File(path, "w", libver=("v108", "v108")), libhdf5’s
H5Pset_libver_bounds low argument.
The bound decides the superblock version the file is written with
(LibverBound::superblock_version) as well as the message versions
of the objects created in it, so unlike
H5File::set_libver_bound — which only reaches objects created
after the call — it applies to the file itself.
LibverBound::Earliest asks for the whole classic generation, the
file libhdf5 writes at H5F_LIBVER_EARLIEST: a version-0 superblock,
a symbol-table root group, version-1 object headers, symbol-table
subgroups and the version-1 B-tree chunk index. Such a file is
readable by libhdf5 1.6, and correspondingly gives up everything
newer — SWMR (crate::swmr) and virtual datasets are refused in
it, and a chunk larger than 4 GiB does not fit its index key.
LibverBound::V18 asks for the file libhdf5 writes at
H5F_LIBVER_V18: a version-2 superblock over link-message groups and
version-2 object headers, but still the version-3 data layout message
and so still the version-1 B-tree chunk index — H5O_layout_ver_bounds
does not reach version 4 until V110, and the v1.10 indexes live in
nothing older. SWMR is refused in such a file: its status flags need a
version-3 superblock, which this bound’s row does not reach.
Not calling this at all is not the same as asking for Earliest,
nor for V18: the default file has the version-2 superblock and
link-message groups of the v1.8 bound over the v1.10 chunk indexes,
which no single bound describes.
Only create reads this; an existing file keeps the
superblock it already has.
use rust_hdf5::{H5File, LibverBound};
let file = H5File::options()
.libver(LibverBound::V110)
.create("v110.h5")
.unwrap();Sourcepub fn userblock(self, size: u64) -> Self
pub fn userblock(self, size: u64) -> Self
Reserve size bytes in front of the superblock for the application’s
own use — h5py’s File(path, "w", userblock_size=512), libhdf5’s
H5Pset_userblock.
The block is the file’s first size bytes and belongs to whoever
writes it: an executable header, a checksum, a provenance record. HDF5
itself only skips it — the superblock and every address in the file are
based at size, and a reader finds the superblock by looking at offset
0 and then at MIN_USERBLOCK doubled
repeatedly, which is why the size must be zero (no block) or a power of
two of at least that many bytes. create reports any
other size as an error; it is not rounded up.
This crate writes the block zero-filled and never reads it back, so
filling it is a plain write to the front of the file after
H5File::close.
use rust_hdf5::H5File;
let file = H5File::options().userblock(512).create("prefixed.h5").unwrap();
assert_eq!(file.userblock_size(), 512);Create the file with shared object header messages — libhdf5’s
H5Pset_shared_mesg_nindexes + H5Pset_shared_mesg_index +
H5Pset_shared_mesg_phase_change, which h5py exposes no binding for.
A message class covered by an index is written once into a
shared-message fractal heap, and every object header that would have
held that exact body holds a pointer to it instead. indexes gives
one (message types, minimum message size) pair per index, where the
type mask is built from
type_flag; list_max and
btree_min are the file-wide counts at which an index changes between
list and v2 B-tree form.
Only create reads this, and it refuses a
configuration libhdf5 would refuse: more than eight indexes, an index
covering no type, or thresholds that overlap.
use rust_hdf5::{H5File, format::sohm::type_flag};
use rust_hdf5::format::messages::{MSG_ATTRIBUTE, MSG_DATASPACE, MSG_DATATYPE};
let types = type_flag(MSG_DATATYPE).unwrap()
| type_flag(MSG_DATASPACE).unwrap()
| type_flag(MSG_ATTRIBUTE).unwrap();
let file = H5File::options()
.shared_messages(&[(types, 0)], 50, 40)
.create("sohm.h5")
.unwrap();Sourcepub fn file_space(
self,
strategy: FileSpaceStrategy,
persist: bool,
threshold: u64,
) -> Self
pub fn file_space( self, strategy: FileSpaceStrategy, persist: bool, threshold: u64, ) -> Self
Create the file under a file-space handling strategy — libhdf5’s
H5Pset_file_space_strategy, h5py’s File(..., fs_strategy=..., fs_persist=..., fs_threshold=...).
strategy picks how released space is reused:
FileSpaceStrategy::FsmAggr keeps free-space managers and the
metadata/raw-data aggregators (the library default),
FileSpaceStrategy::Aggr the aggregators alone, and
FileSpaceStrategy::None neither, so every allocation comes from the
end of the file. FileSpaceStrategy::Page allocates on file-space
page boundaries instead, packing everything smaller than a page into
pages of its own kind; file_space_page_size
sets how big those pages are.
persist writes the free-space managers into the file on close, so a
later session — this crate or libhdf5 — finds the space this one
released instead of appending past it. threshold is the smallest
section a manager records; anything smaller is space the file leaks
rather than tracks. Both are ignored for the two strategies that have
no managers, exactly as H5P__set_file_space_strategy ignores them.
Only create reads this. A file that already exists
declares its own strategy in its superblock extension, and this crate
honours what it finds there.
use rust_hdf5::{FileSpaceStrategy, H5File};
let file = H5File::options()
.file_space(FileSpaceStrategy::FsmAggr, true, 1)
.create("persisting.h5")
.unwrap();Sourcepub fn file_space_page_size(self, size: u64) -> Self
pub fn file_space_page_size(self, size: u64) -> Self
H5Pset_file_space_page_size, h5py’s File(..., fs_page_size=...).
The file-space page is the unit FileSpaceStrategy::Page allocates
in: a request smaller than one page is packed into a page holding only
that kind of data, and a larger one is page-aligned. size is between
512 (H5F_FILE_SPACE_PAGE_SIZE_MIN) and 1 GiB — no power of two
required — and anything outside that is refused by
create, as H5Pset_file_space_page_size refuses it.
Setting it is enough on its own to give the file a file-space info
message, because the page size is one of the four properties
H5F__super_init compares against the library defaults. Under any
other strategy that is all it does: the file records the size and
allocates without it.
Only create reads this. A reopened file keeps the
page size its own message carries.
use rust_hdf5::{FileSpaceStrategy, H5File};
let file = H5File::options()
.file_space(FileSpaceStrategy::Page, true, 1)
.file_space_page_size(8192)
.create("paged.h5")
.unwrap();Sourcepub fn create<P: AsRef<Path>>(self, path: P) -> Result<H5File>
pub fn create<P: AsRef<Path>>(self, path: P) -> Result<H5File>
Create a new HDF5 file at path with the configured options.