pub struct EditSession { /* private fields */ }Expand description
An open HDF5 file being edited in place.
Mirror the file in memory and keep a writable handle; every mutation is
applied to both so the on-disk file stays consistent. Stage additions with
create_dataset / create_group,
value overwrites with write_dataset, and group
attribute edits with set_group_attr /
remove_group_attr, then apply them with
commit.
§Example
use hdf5_pure::{AttrValue, EditSession};
let mut session = EditSession::open("existing.h5")?;
session.create_group("run2");
session.set_group_attr("run2", "kind", AttrValue::AsciiString("trial".into()));
session
.create_dataset("run2/signal")
.with_f64_data(&[1.0, 2.0, 3.0]);
session.commit()?;Implementations§
Source§impl EditSession
impl EditSession
Sourcepub fn open<P: AsRef<Path>>(path: P) -> Result<Self, Error>
pub fn open<P: AsRef<Path>>(path: P) -> Result<Self, Error>
Open an existing HDF5 file for in-place editing.
Reads the file into memory and retains a read/write handle. Takes an
exclusive OS advisory lock so the file cannot be opened concurrently by
another writer or reader; the lock is released automatically when the
session is dropped or the process exits (including on a crash). Fails with
Error::FileLocked if the file is already locked, or
Error::EditUnsupported if the file is not a supported target (see the
module docs for the exact requirements). To control or disable
locking, use open_with_locking or set
HDF5_USE_FILE_LOCKING=FALSE.
Sourcepub fn open_with_locking<P: AsRef<Path>>(
path: P,
locking: FileLocking,
) -> Result<Self, Error>
pub fn open_with_locking<P: AsRef<Path>>( path: P, locking: FileLocking, ) -> Result<Self, Error>
Open an existing HDF5 file for in-place editing, choosing the file-locking
policy explicitly. See open and FileLocking.
Sourcepub fn create_dataset(&mut self, path: &str) -> &mut DatasetBuilder
pub fn create_dataset(&mut self, path: &str) -> &mut DatasetBuilder
Stage a new dataset, added on the next commit. The
argument is the full path of the dataset; everything before the last
component names the parent group, which must exist (or be created in this
session). Returns the DatasetBuilder — the same builder used by
FileBuilder — to configure data, shape, and
attributes.
The dataset may be contiguous or chunked, and chunked datasets may be
filtered (with_deflate, with_shuffle, with_fletcher32,
with_scale_offset, with_zfp) and/or extensible (with_maxshape). An
empty (zero-element) contiguous dataset is supported (chunking one is
not), a provenance dataset (with_provenance) is supported, and a
contiguous dataset may carry variable-length attributes, a
variable-length-string payload (with_vlen_strings), or path-resolved
object-reference elements (with_path_references; chunking any of
these is not supported — see the module docs for the
path-resolution rule and what still stays unsupported (dense
attributes)).
Sourcepub fn write_dataset(&mut self, path: &str) -> &mut DatasetBuilder
pub fn write_dataset(&mut self, path: &str) -> &mut DatasetBuilder
Stage an in-place overwrite of an existing dataset’s values (the HDF5
H5Dwrite whole-dataset write), applied on the next
commit. path is the full path of a dataset that must
already exist; the returned DatasetBuilder — the same builder used by
create_dataset — supplies the replacement data.
This is a value overwrite, not a reshape or retype: the new data’s
datatype and shape must match the on-disk dataset’s exactly (byte-for-byte
after serialization, so endianness and compound layout must agree), or
commit reports Error::EditUnsupported. Contiguous, compact, and
chunked (including filtered) datasets are all supported; the dataset’s
existing chunk geometry, filter pipeline, and chunk index are taken from the
on-disk header (a builder that itself requests chunking/filtering is refused
as “not a value overwrite”). A chunk index this engine cannot enumerate (a
version-2 B-tree) is refused. Partial / sub-region writes are out of scope —
the whole dataset is replaced.
When the new data is the same length as the existing contiguous data block (the common case), the bytes are written straight into that block: no object header is rewritten and the superblock root is not flipped, so the commit’s linearization point is the synced data write itself. A chunked dataset is handled the same way when every (re-encoded) chunk is the same byte length as the slot it replaces — an unfiltered overwrite (chunk sizes are fixed by the unchanged shape) or a filtered one whose re-encoded chunks match — so it too writes straight into the existing chunk slots. When the length differs (a resized contiguous block, or a filtered chunk that no longer fits), the dataset’s storage is rebuilt at end-of-file (or in reusable freed space), the old extent is freed, the data-layout message is repointed, the object header is rewritten, and the parent group’s link is patched — exactly like an addition relocates the path up to the root. A relocating overwrite moves the object header, so it is refused unless the dataset has a single hard link.
Sourcepub fn create_group(&mut self, path: &str)
pub fn create_group(&mut self, path: &str)
Stage a new (empty) group at path, created on the next
commit. The parent must already exist or be created in
the same session; populate the group with datasets via
create_dataset using a path under it.
Sourcepub fn set_group_attr(
&mut self,
path: &str,
name: &str,
value: AttrValue,
) -> &mut Self
pub fn set_group_attr( &mut self, path: &str, name: &str, value: AttrValue, ) -> &mut Self
Stage an attribute add or replacement on a group, applied on the next
commit.
path names the group to edit; "" or "/" names the root group. The
group may already exist or may be created earlier in the same session
with create_group. Attributes — fixed-size or
variable-length (AttrValue::VarLenAsciiArray) — are stored compactly in
the rebuilt group header; an edit that would exceed the compact-attribute
limit, or a group using dense (fractal-heap) attribute storage, is
refused before any file bytes are changed.
Sourcepub fn remove_group_attr(&mut self, path: &str, name: &str) -> &mut Self
pub fn remove_group_attr(&mut self, path: &str, name: &str) -> &mut Self
Stage removal of a compact attribute from a group, applied on the next
commit.
path names the group to edit; "" or "/" names the root group. The
named attribute must exist in the committed group state after any earlier
staged attribute operations for the same group have been applied.
Sourcepub fn delete(&mut self, path: &str)
pub fn delete(&mut self, path: &str)
Stage removal of the link at path (the HDF5 H5Ldelete), applied on the
next commit. The link’s object — and, for a group, its
whole subtree — becomes unreachable. The bytes it occupied are returned to
this session’s free list (issue #21): a later commit reuses them for new
objects instead of growing the file, and if a freed run reaches
end-of-file the file is truncated. Contiguous and chunked datasets (their
chunk index and chunk data blocks) and whole group subtrees are all
reclaimed. Reclaim is best-effort — an object whose blocks this engine
cannot enumerate exhaustively (variable-length global-heap storage, dense
attribute/link heaps, a version 2 B-tree chunk index) is left as dead
bytes rather than risk freeing a region that is still in use. Freed space is
reused within the open session; for a file created with
H5Pset_file_space_strategy(persist = true) it is also recorded on disk so
it survives reopen (see the module docs), otherwise it is forgotten
on close. After reuse, an object reference to a deleted object may resolve
to an unrelated object (deleting a referenced object is undefined in HDF5).
The path must exist. A deletion may not overlap another staged change in
the same commit (e.g. delete /a while adding /a/b); split such
edits into separate commits. The link’s parent group must itself be
editable in place (compact links, single-chunk header); the target being
removed has no such restriction.
Sourcepub fn copy(&mut self, src: &str, dst: &str)
pub fn copy(&mut self, src: &str, dst: &str)
Stage a deep copy of the object at src to a new link at dst (the HDF5
H5Ocopy), applied on the next commit. The source — a
dataset or a whole group subtree — is duplicated: fresh copies of every
object’s data and header are written, internal links and the contiguous
data address are repointed to the copies, and a link named by dst’s last
component is added to dst’s parent group. The original is untouched.
The copy reflects the file’s on-disk state at commit time. src must
exist and dst must not (and may not lie inside src). A chunked (and
filtered) dataset is copied with its chunk payloads and filter pipeline
preserved byte-for-byte (the index is rebuilt at the new location, so a
source using a B-tree-v1 or implicit index is reproduced with an equivalent
v4 index). The source subtree must otherwise be copyable in place: compact
links and attributes, single-chunk headers, and a chunk index this engine
can enumerate (a version-2 B-tree, or a sparse/unallocated chunk grid, is
refused) — otherwise commit reports Error::EditUnsupported.
Sourcepub fn copy_from(
&mut self,
source: &File,
src: &str,
dst: &str,
) -> Result<(), Error>
pub fn copy_from( &mut self, source: &File, src: &str, dst: &str, ) -> Result<(), Error>
Stage a deep copy of the object at src in another open file source to a
new link at dst in this file — a cross-file HDF5 H5Ocopy — applied on
the next commit. Like copy but the source
lives in a separate, independently-opened File reader
rather than the file being edited.
The source — a dataset or a whole group subtree — is duplicated faithfully:
fresh, byte-identical copies of every object’s header and data are appended
to this file, internal links repointed, and a link named by dst’s last
component added to dst’s parent group (which must already exist or be
created earlier in this session). Both files are left otherwise untouched;
the destination only changes on commit.
Unlike the same-file copy, the source is read eagerly
here (the source borrow need not outlive the call), so this returns
Result: the source subtree is resolved, validated, and read out before
returning, and only an already-validated copy is queued for commit.
§Errors
Returns Error::EditUnsupported if the copy cannot be reproduced exactly
in another file. Because the copy is byte-for-byte verbatim, anything that
embeds a source-file absolute address is refused (it would dangle here):
variable-length or reference datasets and attributes (including a
chunked dataset whose elements are variable-length or references, whose
chunk payloads embed such addresses), and any shared header message (a
committed datatype, or an SOHM-shared dataspace, fill value, or filter
pipeline). As with copy a chunked/filtered source is copied
with its chunk payloads and pipeline preserved (index rebuilt at the new
location); the source must use compact links and attributes, single-chunk
version-2 headers, and a chunk index this engine can enumerate (a
version-2 B-tree, or a sparse chunk grid, is refused). The
source must be a buffered file (File::open or
File::from_bytes, not
open_streaming) using 8-byte offsets and no
userblock, and src must exist in it and not be the root group.
Sourcepub fn commit(&mut self) -> Result<(), Error>
pub fn commit(&mut self) -> Result<(), Error>
Apply all staged additions and deletions to the file in place and flush.
Appends each new dataset (its data — a contiguous blob, or the chunk data
and index for a chunked/filtered dataset — plus its object header) and
each new group, then appends rewritten object headers for every touched
group and its ancestors up to the root (omitting any deleted links), then
repoints the superblock at the new root. On success the staged set is
cleared and the session can be reused. On any Error::EditUnsupported
the file on disk is left untouched: the checks that raise it — including
each dataset’s filter-pipeline and chunk-geometry validation — all run
before the first byte is written. Should a later step fail mid-apply (an
I/O error, or a residual build error), the superblock — repointed last —
still names the prior root, so the file stays valid and the appended bytes
are unreferenced slack.