chore: cleanup pass — remove empty types stub, implement superblock v4, reconcile plan docs
- Remove clawhdf5-types (empty 1-line stub crate; type defs already live in
clawhdf5-format). Update workspace Cargo.toml and CLAUDE.md accordingly.
- Implement HDF5 superblock v4 (page-buffer mode) read and write support in
clawhdf5-format: Superblock::parse_v4, page_size field, v4 serialize
branch, and FileWriter::with_page_size. This was the one task left
unimplemented from docs/superpowers/plans/2026-06-29-format-write-extensions.md.
- Reconcile the three docs/superpowers/plans/*.md docs (filter codecs,
format write extensions, MPI-IO VOL) against actual shipped code: they
were pre-work plans for d6c4d4f (2026-06-30) committed to git late on
2026-08-03 with all checkboxes still unchecked. Mark completed tasks done
and add a status note so they read as historical records, not open work.
- Refresh ROADMAP.md's "What's Next" section against current repo state.
Co-Authored-By: Claude Sonnet 5 <[email protected]>
This commit is contained in:
co-authored by
Claude Sonnet 5
parent
b1fc23e975
commit
6b1ea450f5
@@ -932,6 +932,8 @@ pub struct FileWriter {
|
||||
alignment_threshold: usize,
|
||||
/// Global alignment boundary in bytes (0 = disabled).
|
||||
alignment_bytes: usize,
|
||||
/// Page size for page-buffer mode. When set, a v4 superblock is written.
|
||||
page_size: Option<u32>,
|
||||
}
|
||||
|
||||
impl Default for FileWriter {
|
||||
@@ -948,6 +950,7 @@ impl FileWriter {
|
||||
groups: Vec::new(),
|
||||
alignment_threshold: 0,
|
||||
alignment_bytes: 0,
|
||||
page_size: None,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -961,6 +964,14 @@ impl FileWriter {
|
||||
self
|
||||
}
|
||||
|
||||
/// Enable page-buffer mode with the given page size. Writing this causes
|
||||
/// the file to be written with a v4 superblock (page_size field) instead
|
||||
/// of the default v3.
|
||||
pub fn with_page_size(&mut self, page_size: u32) -> &mut Self {
|
||||
self.page_size = Some(page_size);
|
||||
self
|
||||
}
|
||||
|
||||
pub fn create_group(&mut self, name: &str) -> GroupBuilder {
|
||||
GroupBuilder::new(name)
|
||||
}
|
||||
@@ -979,6 +990,7 @@ impl FileWriter {
|
||||
}
|
||||
|
||||
pub fn finish(self) -> Result<Vec<u8>, FormatError> {
|
||||
let page_size = self.page_size;
|
||||
struct DsFlat {
|
||||
name: String,
|
||||
dt: Datatype,
|
||||
@@ -1271,8 +1283,14 @@ impl FileWriter {
|
||||
let actual_ds_oh_sizes: Vec<usize> = dummy_blobs.iter().map(|b| b.oh_bytes.len()).collect();
|
||||
|
||||
// Pass 2: compute real addresses
|
||||
let root_group_addr = SUPERBLOCK_SIZE as u64;
|
||||
let mut cursor2 = SUPERBLOCK_SIZE + root_oh_size;
|
||||
// v4 superblocks add a 4-byte page_size field before the checksum.
|
||||
let superblock_size = if page_size.is_some() {
|
||||
SUPERBLOCK_SIZE + 4
|
||||
} else {
|
||||
SUPERBLOCK_SIZE
|
||||
};
|
||||
let root_group_addr = superblock_size as u64;
|
||||
let mut cursor2 = superblock_size + root_oh_size;
|
||||
|
||||
// Each group is laid out as: object header, then (if dense) its link
|
||||
// blob, then (if dense) its attribute blob. Link blobs are sized with
|
||||
@@ -1445,7 +1463,7 @@ impl FileWriter {
|
||||
let mut buf = Vec::with_capacity(cursor2);
|
||||
|
||||
let sb = Superblock {
|
||||
version: 3,
|
||||
version: if page_size.is_some() { 4 } else { 3 },
|
||||
offset_size: OFFSET_SIZE,
|
||||
length_size: LENGTH_SIZE,
|
||||
base_address: 0,
|
||||
@@ -1459,6 +1477,7 @@ impl FileWriter {
|
||||
consistency_flags: 0,
|
||||
superblock_extension_address: Some(u64::MAX),
|
||||
checksum: None,
|
||||
page_size,
|
||||
};
|
||||
buf.extend_from_slice(&sb.serialize());
|
||||
|
||||
@@ -2100,4 +2119,29 @@ mod tests {
|
||||
other => panic!("expected External link, got {other:?}"),
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn file_writer_v4_superblock() {
|
||||
let mut fw = FileWriter::new();
|
||||
fw.with_page_size(4096);
|
||||
fw.create_dataset("data").with_f64_data(&[1.0, 2.0]);
|
||||
let bytes = fw.finish().unwrap();
|
||||
|
||||
let sig = signature::find_signature(&bytes).unwrap();
|
||||
let sb = Superblock::parse(&bytes, sig).unwrap();
|
||||
assert_eq!(sb.version, 4, "expected superblock v4");
|
||||
assert_eq!(sb.page_size, Some(4096));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn file_writer_default_superblock_is_v3() {
|
||||
let mut fw = FileWriter::new();
|
||||
fw.create_dataset("data").with_f64_data(&[1.0, 2.0]);
|
||||
let bytes = fw.finish().unwrap();
|
||||
|
||||
let sig = signature::find_signature(&bytes).unwrap();
|
||||
let sb = Superblock::parse(&bytes, sig).unwrap();
|
||||
assert_eq!(sb.version, 3);
|
||||
assert_eq!(sb.page_size, None);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user