Fast contiguous and concurrent reads, VL data, nested groups and links, Python bindings #15

Merged
osobh merged 41 commits from feat/p2-perf-coverage into main 2026-09-26 14:57:01 +00:00
3 changed files with 54 additions and 8 deletions
Showing only changes of commit 546fdb84fa - Show all commits
+40 -4
View File
@@ -28,19 +28,55 @@
Link Info message carries the flags, each link its order, and a dense Link Info message carries the flags, each link its order, and a dense
group a creation-order B-tree (type 6). h5py then lists members in group a creation-order B-tree (type 6). h5py then lists members in
insertion order. Attribute creation order is not tracked. insertion order. Attribute creation order is not tracked.
- A group holds at most 65 535 links (its link index is one B-tree leaf); - A group holds at most 65 535 links (its link index is one B-tree leaf),
more is an error. `GroupBuilder`'s fields changed (they were and in a group of more than 8 links (dense storage) each link message
must be at most 65 515 bytes (one fractal heap block; huge heap objects
are not written); more is an error. Measured at the limit: 65 535 links
with 100-byte names (a 7 MB heap) read in h5py, h5dump and clawhdf5, and
h5py can add to the group. `GroupBuilder`'s fields changed (they were
crate-private); `FinishedGroup` is unchanged for callers. crate-private); `FinishedGroup` is unchanged for callers.
- Files that use one level of groups and no new link kinds are laid out as - Files that use one level of groups and no new link kinds are laid out as
before: byte-identical to the writer with the Group Info fix below before: byte-identical to the writer with the Group Info fix below
(compared on simple, mixed dense/chunked/compact/external-link and paged (compared on simple, mixed dense/chunked/compact/external-link and paged
files). Tests: h5py and clawhdf5 read the same files). Tests: h5py and clawhdf5 read the same
tree (every path, attribute and value) from a 5-level file; soft, hard, tree (every path, attribute and value) from a 5-level file; soft, hard,
external and cyclic hard links; 10 000 links in one group, with and external and cyclic hard links; 10 000, 20 000 and 65 535 links in one
without creation order; libhdf5 adding and deleting links in our groups; group, with and without creation order; libhdf5 adding and deleting links
in our groups;
`h5rs check` passes and `h5rs dump` equals h5dump `h5rs check` passes and `h5rs dump` equals h5dump
(`crates/clawhdf5/tests/writer_groups_interop.rs`, (`crates/clawhdf5/tests/writer_groups_interop.rs`,
`crates/clawhdf5-tools/tests/h5rs_interop.rs`). `crates/clawhdf5-tools/tests/h5rs_interop.rs`).
- **Big dense groups and attribute sets were unreadable.** The fractal heap
holding dense links or attributes wrote every doubling-table row as
direct blocks, but past the 512 KiB the root's direct blocks hold, rows
are child indirect blocks, and libhdf5 and `h5rs check` read them as
such: a group with 20 000 links of 20-byte names was written without
error and h5py could not list it ("incorrect metadata checksum"); 150
dense attributes of up to 56 KB could not be opened. This was in 2.7.0
too. The heap writer now writes child indirect blocks, nested as deep as
needed. Found on the way: an object bigger than the next block's space
was cut off (it now goes in the first block big enough), and h5py adding
a link to a heap over 64 KiB overwrote its first block (the header's
next-block offset was 0).
- **h5py crashed adding a link to a group of more than about 47 700
links** (35 000 with creation order tracked). The link index leaf's node size gave libhdf5 room for more than
65 535 records, which overflows the leaf's 2-byte count. The node is now
capped at 65 535 records. Dense attributes use the same index builder:
more than 65 535 on one object used to be written with the count modulo
65 536, and are now an error.
- **A dense link or attribute message over 65 515 bytes** (e.g. a soft link
with a long target in a group of more than 8 links) was written cut off,
and libhdf5 could not list the group ("object overruns end of direct
block"). It is now an error.
- **Chained hard links took exponential time to resolve.** A hard-link
target going through other hard links resolved them again on every path
through them: 26 links whose targets each named the previous one twice
took 46 s. Each hard link is now resolved once, and a cycle is reported
by the link's name.
- **A dataset attribute set twice read back as its first value**, as for
groups below (h5py listed the name twice). The later value now replaces
the earlier one; a hand-set attribute named like a provenance attribute
is replaced by the computed one.
- **A group attribute set twice read back as its first value.** Setting a - **A group attribute set twice read back as its first value.** Setting a
group (or root) attribute again wrote a second attribute message with the group (or root) attribute again wrote a second attribute message with the
same name, and h5py returned the first value. The later value now replaces same name, and h5py returned the first value. The later value now replaces
+2 -1
View File
@@ -429,7 +429,8 @@ b.add_external_link("raw", "raw.h5", "/data");
b.write("groups.h5")?; b.write("groups.h5")?;
``` ```
A group holds at most 65 535 links; more is an error. A group holds at most 65 535 links; more is an error, as is a link over
65 515 bytes (a very long soft-link target) in a group of more than 8 links.
### Agent Memory ### Agent Memory
+12 -3
View File
@@ -209,11 +209,20 @@ fill-value item that did is fixed).
h5py, h5dump and `h5rs check --data` read them h5py, h5dump and `h5rs check --data` read them
(`crates/clawhdf5/tests/writer_groups_interop.rs`, (`crates/clawhdf5/tests/writer_groups_interop.rs`,
`crates/clawhdf5-tools/tests/h5rs_interop.rs`). Still missing: a group `crates/clawhdf5-tools/tests/h5rs_interop.rs`). Still missing: a group
with more than 65 535 links (its link index is one B-tree leaf) is an with more than 65 535 links, or an object with more than 65 535 dense
error, and attribute creation order is not tracked. attributes, is an error (the index is one B-tree leaf), and attribute
creation order is not tracked.
- ~~Dense link or attribute storage past 512 KiB of messages was written
unreadable (child indirect blocks of the fractal heap written as direct
blocks).~~ **Fixed 2026-09-26** (it affected 2.7.0 too): tested with
20 000 and 65 535 links and with 8 MB of dense attributes, read by
h5py, h5dump, `h5rs check` and clawhdf5, and h5py can add links to
such groups.
- ~~libhdf5 could not add a link to a group we wrote (no Group Info - ~~libhdf5 could not add a link to a group we wrote (no Group Info
message).~~ **Fixed 2026-09-26.** message).~~ **Fixed 2026-09-26.**
- Dense attribute storage for attributes over 64 KiB. - Huge fractal heap objects: in dense storage (more than 8 attributes on
an object, or more than 8 links in a group) one attribute or link
message over 65 515 bytes is an error.
- Output that HDF5 1.8 can read. - Output that HDF5 1.8 can read.
- A B-tree v2 chunk index larger than one leaf, so datasets with several - A B-tree v2 chunk index larger than one leaf, so datasets with several
unlimited dimensions are limited to 65 535 chunks. unlimited dimensions are limited to 65 535 chunks.