Full-coverage sidecar write-back (issue #190)#195
Merged
Conversation
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_017w2BCjStojyfaTkw77BfT2
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_017w2BCjStojyfaTkw77BfT2
Member
Author
yes. this is a fifth of a second total for doing the complete cache, and is noise for workers that run in 1 to 2 minutes. |
Member
Author
fine |
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_017w2BCjStojyfaTkw77BfT2
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Closes #190.
What this does
The
inlinewrite-back path persisted only the datasets the running config touched (~48 for ATL03: 8 datasets × 6 beams), not the full granule (~1,000+). This contradicts the #163 store-design decision (full ~1,055-dataset coverage) and gives up the "build once, serve any user group" property for zero read savings (the metadata was already fetched).This makes write-back persist chunk maps for every decodable dataset in the granule, enumerated from the front-of-file metadata h5coro already cached. The read path is unchanged — it still reads only what the config needs; only what write-back persists grows.
Approach
_iter_datasets(h5obj)recursively walks the group tree via h5coro (metaOnly, attributes off), classifying each node (group vs dataset) and yielding(path, H5Dataset)— the parsed dataset handed back so its chunk map is built without a second object-header parse.build_chunk_mapis split intobuild_chunk_map(opens the dataset) +_chunk_map_from_dataset(the metadata-only assembly), so the walk reuses the same single-source primitive.full_granule_maps(h5obj, existing)widens the read-set maps to full coverage, reusing already-built maps verbatim (config datasets stay byte-identical to the read path) and mapping the rest.finish_granulecallsfull_granule_mapsbefore persisting whenwrite_back_coverage == "full"(the default).Design decisions
full;write_back_coverage: full|lazyknob added.fullis the Virtual chunk-index backends for the read path (issue #160) #163 intent. I added thelazyescape hatch (reproduces the pre-Sidecar write-back persists only the config's read set (lazy), not full ~1,055-dataset coverage #190 read-set-only manifest) because the measured build delta is materially larger than 88S offsets extraction: per-chunk byte offsets for the pinned benchmark shard (issue #158) #159 predicted (see below), so a latency-sensitive private run has a way out. Validation rejects bad values and rejects the key withoutwrite_back: true(mirrors the existingstorecoupling).dtype;datasets_from_manifestalready skips blank-dtype rows at read. This matches the consumer and keeps the manifest a complete community chunk manifest. Verified on a fixture string dataset and 13 undecodable-dtype datasets on a real granule.build_chunk_mapalready handles both (pseudo-chunk for contiguous). Confirmed on real data — both routes covered. COMPACT-layout datasets (data in the object header, no file offset) raiseValueErrorand are dropped at write: a ranged read could never serve them.Measurements (real ATL03 granule, local
~/ignore)byte_offset/nbytes/dtype), because full coverage reuses the read-set maps verbatim.Tests
atl03_mini.h5): the fixture gained datasets the config never reads — non-read chunked (delta_time) + contiguous (segment_id), a top-levelancillary_datagroup, an undecodable string, and a compact dataset. Regenerated viamake_fixture.py(h5py, offline). New/updated tests assert full coverage (22 fixture datasets vs 16 read set), spot-check non-read datasets present, string recorded with blank dtype, compact dropped; the byte-identical-manifest and interleaved-granule tests stay green (updated to full coverage).TestFullCoverageRealGranulevalidates >1000 datasets, read-set byte-identity, the one-cache-line bound, and prints the build-time delta. Gated on a local~/ignoregranule so CI skips it (lands in phase 2).Phases
write_back_coverageknob, extended fixture, hermetic tests.TestFullCoverageRealGranule).Adversarial self-review (folded)
A fresh-context review verified the walk against h5coro internals (confirmed
pathAddresseskeying, and thatearlyExit=Falsefully enumerates dense-link groups, not just the followed target). Findings folded:full_granule_mapscaught onlyValueError(compact); any other per-dataset build failure would propagate and sink the entire granule manifest, making full coverage strictly more fragile than the read path (which degrades one dataset to the h5coro decoder). Now the walk catches any per-dataset build failure (log + skip), matching read-path tolerance. New test:test_full_granule_maps_tolerates_one_bad_dataset._iter_datasetsso each node is parsed exactly once (the classification parse doubles as the group's enumeration parse) — cut the walk delta ~189 → ~150 ms.seenset of object-header addresses to bound the descent against a (non-ICESat-2) hard-link cycle.write_back_coveragewithoutwrite_backnow reports the actionable "only meaningful" message before the value range-check.Questions for review
lazyknob is the escape hatch if not. Options: (a) keepfulldefault as-is; (b) keep default but document the delta prominently; (c) investigate reusing h5coro's already-parsedmetadataTableto shave the classification parse.tests/test_lambda_build.py::TestFunctionBuild::test_function_build_succeedsfails locally becausepipcan't resolvezarr>=3.1.5for the Lambda target platform on this machine (environmental); and the repo carries pre-existing mypy errors across ~10 modules (identical onmain, including thewrite_manifest(self.store, ...)str | Nonecall I did not introduce). Flagged, not touched.🤖 Generated with Claude Code
https://claude.ai/code/session_017w2BCjStojyfaTkw77BfT2