Skip to main content

H5FileOptions

Struct H5FileOptions 

Source
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

Source

pub fn new() -> Self

Construct a fresh options builder with default settings.

Source

pub fn locking(self, policy: FileLocking) -> Self

Override the locking policy. Bypasses the HDF5_USE_FILE_LOCKING environment variable for the resulting open call.

Source

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.

Source

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).

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.

Source

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.

Source

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.

Source

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();
Source

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);
Source

pub fn shared_messages( self, indexes: &[(u16, u32)], list_max: u16, btree_min: u16, ) -> Self

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();
Source

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();
Source

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();
Source

pub fn create<P: AsRef<Path>>(self, path: P) -> Result<H5File>

Create a new HDF5 file at path with the configured options.

Source

pub fn open<P: AsRef<Path>>(self, path: P) -> Result<H5File>

Open an existing HDF5 file for reading with the configured options.

Source

pub fn open_rw<P: AsRef<Path>>(self, path: P) -> Result<H5File>

Open an existing HDF5 file for read/write with the configured options.

Trait Implementations§

Source§

impl Clone for H5FileOptions

Source§

fn clone(&self) -> Self

Returns a duplicate of the value. Read more
1.0.0 (const: unstable) · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl Debug for H5FileOptions

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl Default for H5FileOptions

Source§

fn default() -> Self

Returns the “default value” for a type. Read more

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T, S> SimdFrom<T, S> for T
where S: Simd,

Source§

fn simd_from(_simd: S, value: T) -> T

Source§

impl<F, T, S> SimdInto<T, S> for F
where T: SimdFrom<F, S>, S: Simd,

Source§

fn simd_into(self, simd: S) -> T

Source§

impl<T> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = !

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, !>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.