Replace the falsification suite with the time-series suite, under bench/ - #4
Conversation
The engine's own source, its tests, the browser reader and the design notes explained themselves by naming one application built on top: a segment was "a day index", a posting list was "what it writes", a size budget was "its client". A reader of the store should not have to know about a downstream program to understand what a run of fixed-width values is. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01F2wxgRU31dUrqaY8KwfsA2
The suite's workload was an HTTP access log: seven named fields, a day of lines, a posting per line per field. None of that is a property of the store, and it had spread -- the engine's own source and the browser reader explained themselves by naming it. The model is now an inverted index over rows: anonymous attributes on a cardinality ladder from 8 to 5,000, four-byte row ordinals, Zipf-skewed. The ladder is the part that matters and is kept exactly: three orders of magnitude of run length in one file, so a single fixture covers a run of hundreds of thousands of postings and a run of tens. `w1-daysize` is `w1-indexsize`, and its two claims are stated about an index rather than about a day of traffic. Renaming the attributes moved where they sort, and that exposed four checks that were testing the fixture's geometry rather than the reader: - W4.1 required every probe to plan a fetch, but an inline run correctly plans nothing. The non-vacuity guard moves to the probe set, and is now stronger: each shape must exercise both the block-backed and the inline path. - W5.3 required each range's reads to equal its plan. A plan names a 16 KiB checksum piece, so a walk over a piece the open already made resident reads less. Containment is the property -- never read outside the plan -- and tightness is what W5.2 and W5.6 measure. Its evidence was also identical whether it passed or failed; it now names the miss. - W6.5 required exactly one postings wave, so a shape needing none was reported as a failure rather than as a path the run did not take. Rule 3: it reports not_exercised. - The browser test's refusal check assumed range 0 was non-resident. It now probes every range and requires that one refuses. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01F2wxgRU31dUrqaY8KwfsA2
The browser suite's five experiments were not in `scripts/check.sh`, so nobody ran them and their committed records drifted from the engine. The fixture whose index they recorded at 686,506 bytes measures 1,112,132 today. `verify` was comparing claims against the old recording and reporting green. It was kept out by its own exit code: the binary exited non-zero whenever a finding failed, so a run containing a known-failing finding looked like a crashed program. In this project a recorded failure is a valid state and `verify` is what adjudicates it, so the suite now exits 0 and writes its record like every other one, and `suites` runs it. What the fresh records show, all from one cause: `Db` inlines a run up to `Options::inline_bytes` exactly as `SegmentWriter` does. Around 450 KB of a 7.4 MB fixture that these claims assumed was in blocks is in the key section. - W5.5 fails -> holds. 6.1% against a 10% bound, from 12.7%. The sparse open got smaller and the whole open it is measured against got bigger. - W5.6 holds -> fails. The worst field's plans are 1.10 of their bound, from 0.52: a key section carrying values spans more pages, so the page-boundary slack is paid over a range that outgrew the bound's per-key term. Recorded as failing rather than recalibrated. - W6.1 holds -> fails. Store and segment both open in two waves, so the contrast the claim asserts is gone. W6.2 and W6.4 still hold, so what R7.1 was built for is intact. - W6.5 was pointed at the rarest key of all, which now has no block. It takes the smallest run that did not fit inline, and holds: 65 postings, one wave, the chunks the run spans rather than the block they share. CLAUDE.md said `Store` never inlines. Three findings were built on that difference; the note now says what the code does and why to distrust it. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01F2wxgRU31dUrqaY8KwfsA2
The engine keeps the library, its tests, and the browser reader with its wasm build. The suite -- the measurement substrate, the six experiment binaries, claims.json, results, figures, the external comparators, the browser test and the plan files -- moves to supdb-bench, which carries this repository as a submodule and depends on it by path. web/build.sh now builds the reader and prints its four sizes; recording them against a budget is a claim and lives with the claims. It also asks cargo where its target directory is rather than assuming, because as a submodule the workspace root is a level up. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01F2wxgRU31dUrqaY8KwfsA2
The README is a database README: what it is, a benchmark section with the two figures and directions with claim ids, usage, and one sentence for the falsification discipline with one link. CLAUDE.md keeps the invariants a change here must not break and the shapes the bugs come in, and drops everything about profiles, claims and comparing engines -- that moved with the suite. CONTRIBUTING.md leads with the fact that the tests runnable here are not the whole gate. check.sh is build, test, lint and wasm. ci.yml keeps the platform matrix and adds a required `bench` job that clones supdb-bench, puts this checkout where the submodule would be, and runs the suite against it. It needs no secrets, so it works on fork pull requests, and it runs on pull requests and tags rather than on pushes to main. The workflows that drove the suite on the self-hosted runners move to supdb-bench with it. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01F2wxgRU31dUrqaY8KwfsA2
|
The job clones supdb-bench at There is nothing to port into this PR either: the fix lives in the other repository. bfulton/supdb-bench#1 carries the suite, and this goes green once that merges. That PR's own CI is already green on Not re-running the check — a re-run would fail identically until bench Generated by Claude Code |
There was a problem hiding this comment.
🟡 Changes recommended
Documentation/build-script messaging still references moved or removed suite artifacts (e.g., results/w3-bundle.*.json / src/bin/browser.rs), and web/build.sh needs a small robustness guard for clearer CI failures.
Once you've addressed the issues Copilot identified, you can request another Copilot review.
Pull request overview
This PR refactors supdb to be “engine + tests + browser reader” only, moving the falsification/benchmarking suite (plans, results, figures, external comparators, and related scripts) into supdb-bench, and updating docs/comments/scripts accordingly.
Changes:
- Removes the in-repo suite artifacts (plan markdown, recorded results, figure HTML, AWS runner tooling, and external comparator crate) now owned by
supdb-bench. - Simplifies the crate layout (drops workspace + bench module) and updates engine/browser-reader documentation to remove suite-specific references.
- Updates the wasm reader build script to be submodule/workspace-root aware and to emit size measurements as plain text.
File summaries
| File | Description |
|---|---|
| ycsb-plan.md | Removed (moved to supdb-bench). |
| web/worker.mjs | Updates comments to remove suite-specific naming. |
| web/test/run.sh | Removed (browser test moved to supdb-bench). |
| web/test/page.html | Removed (browser test moved to supdb-bench). |
| web/supdb.mjs | Updates comments/docs to remove suite-specific naming. |
| web/README.md | Updates prose, but still needs alignment with moved-out suite/build outputs. |
| web/build.sh | Uses cargo metadata target dir (workspace/submodule-safe) and prints size metrics. |
| walreuse-plan.md | Removed (moved to supdb-bench). |
| walfloor-plan.md | Removed (moved to supdb-bench). |
| walcrc-plan.md | Removed (moved to supdb-bench). |
| tests/segwriter.rs | Comment-only updates to remove suite-specific naming. |
| tests/blob.rs | Comment-only updates to remove suite-specific naming. |
| tailbound-plan.md | Removed (moved to supdb-bench). |
| tail-plan.md | Removed (moved to supdb-bench). |
| syncpolicy-plan.md | Removed (moved to supdb-bench). |
| src/wasmapi.rs | Updates ABI docs to remove suite-specific naming. |
| src/lib.rs | Removes bench module exposure and updates module-level commentary. |
| src/db.rs | Comment-only updates to remove suite-specific naming. |
| src/bytes.rs | Comment-only updates to remove suite-specific naming. |
| src/blob.rs | Comment-only updates to remove suite-specific naming. |
| src/bench/json.rs | Removed (bench module moved to supdb-bench). |
| shape-plan.md | Removed (moved to supdb-bench). |
| segwrite-plan.md | Removed (moved to supdb-bench). |
| segsize-plan.md | Removed (moved to supdb-bench). |
| segroute-plan.md | Removed (moved to supdb-bench). |
| sealwait-plan.md | Removed (moved to supdb-bench). |
| scripts/claimrefs.sh | Removed (suite/claims checks moved to supdb-bench). |
| scanmerge-plan.md | Removed (moved to supdb-bench). |
| scanfloor-plan.md | Removed (moved to supdb-bench). |
| results/w4-ranges.full.json | Removed (moved to supdb-bench). |
| results/w4-ranges.ci.json | Removed (moved to supdb-bench). |
| results/w3-bundle.full.json | Removed (moved to supdb-bench). |
| results/w3-bundle.ci.json | Removed (moved to supdb-bench). |
| results/w1-daysize.full.json | Removed (moved to supdb-bench). |
| results/w1-daysize.ci.json | Removed (moved to supdb-bench). |
| results/f8-checksums.full.json | Removed (moved to supdb-bench). |
| results/f8-checksums.dev.json | Removed (moved to supdb-bench). |
| results/f8-checksums.ci.json | Removed (moved to supdb-bench). |
| results/f64-indexsum.full.json | Removed (moved to supdb-bench). |
| results/f64-indexsum.ci.json | Removed (moved to supdb-bench). |
| results/f60-sealwait.full.json | Removed (moved to supdb-bench). |
| results/f60-sealwait.ci.json | Removed (moved to supdb-bench). |
| results/f48-syncpolicy.full.json | Removed (moved to supdb-bench). |
| results/f48-syncpolicy.ci.json | Removed (moved to supdb-bench). |
| results/f47-parwal.full.json | Removed (moved to supdb-bench). |
| results/f47-parwal.ci.json | Removed (moved to supdb-bench). |
| results/f45-scanfloor.full.json | Removed (moved to supdb-bench). |
| results/f45-scanfloor.ci.json | Removed (moved to supdb-bench). |
| results/f42-load.full.json | Removed (moved to supdb-bench). |
| results/f42-load.ci.json | Removed (moved to supdb-bench). |
| results/f10-pair-mph-paged-vs-mph-pagedfixed.full.json | Removed (moved to supdb-bench). |
| results/f10-pair-hash-paged-vs-hash-pagedfixed.full.json | Removed (moved to supdb-bench). |
| results/f1-outofcore.full.json | Removed (moved to supdb-bench). |
| results/c4-crash.full.json | Removed (moved to supdb-bench). |
| results/c4-crash.ci.json | Removed (moved to supdb-bench). |
| results/c1-decoders.full.json | Removed (moved to supdb-bench). |
| results/c1-decoders.ci.json | Removed (moved to supdb-bench). |
| results/apple-silicon/ext-kv-next-pair.run3.env.txt | Removed (moved to supdb-bench). |
| results/apple-silicon/ext-kv-next-pair.run2.env.txt | Removed (moved to supdb-bench). |
| results/apple-silicon/ext-kv-next-pair.run1.env.txt | Removed (moved to supdb-bench). |
| results/apple-silicon/ext-kv-durable-pair.run4-valuelog.env.txt | Removed (moved to supdb-bench). |
| results/apple-silicon/ext-kv-durable-pair.run3-valuelog.env.txt | Removed (moved to supdb-bench). |
| results/apple-silicon/ext-kv-durable-pair.run2.env.txt | Removed (moved to supdb-bench). |
| results/apple-silicon/ext-kv-buffered-read.run2.env.txt | Removed (moved to supdb-bench). |
| results/apple-silicon/ext-kv-buffered-read.run1.env.txt | Removed (moved to supdb-bench). |
| results/apple-silicon/env.run2.txt | Removed (moved to supdb-bench). |
| results/apple-silicon/env.run1.txt | Removed (moved to supdb-bench). |
| results/apple-silicon/env-durable-pair.run1.txt | Removed (moved to supdb-bench). |
| results/apple-silicon/env-buffered-pair.run2.txt | Removed (moved to supdb-bench). |
| results/apple-silicon/env-buffered-pair.run1.txt | Removed (moved to supdb-bench). |
| promote-plan.md | Removed (moved to supdb-bench). |
| profile-plan.md | Removed (moved to supdb-bench). |
| parwal-plan.md | Removed (moved to supdb-bench). |
| merge-plan.md | Removed (moved to supdb-bench). |
| madvise-plan.md | Removed (moved to supdb-bench). |
| loadlevers-plan.md | Removed (moved to supdb-bench). |
| inline-plan.md | Removed (moved to supdb-bench). |
| filter-plan.md | Removed (moved to supdb-bench). |
| figures/index.html | Removed (moved to supdb-bench). |
| figures/full/index.html | Removed (moved to supdb-bench). |
| fanout-plan.md | Removed (moved to supdb-bench). |
| drain-plan.md | Removed (moved to supdb-bench). |
| docs/engine.md | Updates wording to remove suite-specific naming. |
| dict-plan.md | Removed (moved to supdb-bench). |
| crash-plan.md | Removed (moved to supdb-bench). |
| CONTRIBUTING.md | Adds contribution workflow explaining the split and CI gating via supdb-bench. |
| compaction-plan.md | Removed (moved to supdb-bench). |
| Cargo.toml | Removes workspace + suite bins from this repo’s manifest. |
| bulkseal-plan.md | Removed (moved to supdb-bench). |
| bench/profile.sh | Removed (moved to supdb-bench). |
| bench/external/Cargo.toml | Removed (moved to supdb-bench). |
| bench/aws/reap.sh | Removed (moved to supdb-bench). |
| bench/aws/iam/setup.sh | Removed (moved to supdb-bench). |
| bench/aws/iam/bench-policy.json | Removed (moved to supdb-bench). |
| bench/aws/bootstrap.sh | Removed (moved to supdb-bench). |
| .gitignore | Updates browser-reader artifact notes (still needs alignment with moved test harness). |
| .github/workflows/runner-smoke.yml | Removed (runner workflows moved to supdb-bench). |
Review details
- Files reviewed: 91/246 changed files
- Comments generated: 2
- Review effort level: Lite
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
Cargo takes profiles from the workspace root, so the engine's `[profile.wasm]` was ignored when it was built as a submodule of supdb-bench, and the copy that had to live in the other manifest was two definitions of one thing with nothing holding them equal. The settings now travel with the only script that wants them, as --config overrides; the module comes out byte-identical. The bench job's fallback branch is gone: supdb-bench carries its own check.sh, and a missing one is a broken checkout rather than a reason to measure something else. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01F2wxgRU31dUrqaY8KwfsA2
The target directory is parsed out of `cargo metadata`; an empty parse meant the script no longer knew where it was looking, and it would have surfaced later as a missing module -- blaming the build for a failure in the question before it. It exits there instead. web/README still described build.sh as recording w3-bundle against a budget in a binary this repository no longer has, and pointed at results, claims and a browser test that moved. It describes what is here. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01F2wxgRU31dUrqaY8KwfsA2
There was a problem hiding this comment.
🟡 Changes recommended
A few updated comments/docs still refer to non-existent binaries/paths and the old web/build.sh JSON-results flow, which should be corrected to match the new engine-only layout.
Once you've addressed the issues Copilot identified, you can request another Copilot review.
Review details
- Files reviewed: 91/246 changed files
- Comments generated: 1
- Review effort level: Lite
The suite moved, and eight references to it did not. Four are in code comments and crate docs that name `results/` and `claims.json` as bare paths, which now resolve to nothing here; they name supdb-bench instead, and the two design briefs say so once in their opening rather than at every citation. The crate docs also carried two standing ratios for the durable load and the point read. A figure in the present tense is a claim about how things are, so it belongs where `verify` gates it -- the claim ids were already beside the numbers, and are now the whole of it. `.gitignore` had three rules for outputs nothing here produces: a vendor directory under a `bench/` that moved, the `results-ci`/`figures-ci` trees that `check.sh suites` wrote before that group left, and `web/test/out`. `*.dat` went with the harnesses that wrote them. What is left is the target directories, the profiler droppings and the wasm module. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01F2wxgRU31dUrqaY8KwfsA2
There was a problem hiding this comment.
🔵 Needs a closer look
It changes cross-repo CI gating and removes/migrates a large suite surface area, which can’t be fully validated from this PR alone without the paired supdb-bench merge/run.
Review details
- Files reviewed: 92/248 changed files
- Comments generated: 0 new
- Review effort level: Lite
`.localmostrc` declares every path and host a benchmark job on a self-hosted Mac may reach. Strict mode means the declaration is the whole surface, so the file is only worth reading beside the jobs it governs -- and those moved to supdb-bench with the suite they measure. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01F2wxgRU31dUrqaY8KwfsA2
There was a problem hiding this comment.
🔵 Needs a closer look
It makes large structural and CI-adjacent changes (removing the in-repo suite and shifting gates to an external repo) that should be validated with a final human review of the cross-repo integration.
Review details
- Files reviewed: 92/249 changed files
- Comments generated: 0 new
- Review effort level: Lite
|
This head — EXT.47 compares The fix cannot be ported here: the claim lives in the other repository. It is bfulton/supdb-bench#4, which pins EXT.46 and EXT.47 to Generated by Claude Code |
The suite left this repository when it was large: 183 claims, a results archive, plan files, browser tests and a launcher, and keeping the ruler out of the thing it measured seemed worth a second repository. Rewritten as a time series it is ten source files, one binary and a runs/ directory, and the second repository cost more than it guarded: a paired pull request for every change that touched both, a submodule pointer and a branch override so CI tested the right engine, and the engine's release profile silently ignored under the other workspace. bench/ is its own cargo workspace, depending on the engine by path, so the engine's build and test never pay for the comparators' C++ and its lockfile never lists them; the release profile is repeated there with the reason. A row records one sha, since one commit now names the engine and the suite that measured it. scripts/check.sh gains the `bench` group (the suite's build, test and lint, in the default set) and `quick` (one measurement, gated against bench/runs/, with the figures; not in the default set because a timing run needs the machine to itself). CI runs `bench` in the three-platform matrix and `quick` in a job of its own, and the job that cloned the other repository is gone. The three workflows that ran the suite move here with their paths adjusted, and .localmostrc returns to the root beside the jobs it governs. The documents that described two repositories describe one. Claim ids in code comments and design notes stay: they name the previous suite's claims, in the supdb-bench repository's history, and CLAUDE.md says so. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01F2wxgRU31dUrqaY8KwfsA2
There was a problem hiding this comment.
🟡 Changes recommended
The new bench build script and libclang helper have correctness/robustness issues (stale SUPDB_SHA due to insufficient rerun triggers; apt-get install without apt-get update fallback) that should be fixed before merging.
Once you've addressed the issues Copilot identified, you can request another Copilot review.
Review details
- Files reviewed: 108/267 changed files
- Comments generated: 2
- Review effort level: Lite
…tall The build script watched only .git/HEAD, which a commit on the same branch does not touch -- the branch's ref file or packed-refs changes instead -- so the sha in a row could name the previous commit. It now watches HEAD, the ref HEAD points at, and packed-refs. libclang.sh's Debian fallback ran apt-get install on whatever package lists the image had; it updates them first. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01F2wxgRU31dUrqaY8KwfsA2
There was a problem hiding this comment.
🟡 Changes recommended
The new bench build/workflow lint utilities have concrete correctness gaps (notably build-script rerun tracking against a non-existent packed-refs path, and workflow run: coverage), and should be adjusted before landing.
Once you've addressed the issues Copilot identified, you can request another Copilot review.
Review details
Suppressed comments (1)
Previously missed (1) — in code that hasn't changed since the last review.
bench/scripts/workflows.sh:56
- The script claims it checks every workflow
run:block, but the awk extractor only collects block-scalars (run: |). Most workflows here use single-linerun:entries (e.g.run: sh scripts/check.sh ...in ci.yml), so they currently bypass both the bash-parse and${{ }}-interpolation checks.
- Files reviewed: 108/267 changed files
- Comments generated: 1
- Review effort level: Lite
The previous suite's claim ids (EXT.23, F43.4, W4.1, R6.3 and the rest), its experiment names (f49, c4-crash, w1-daysize), its plan files and its results paths were cited in about two hundred places: the design brief, the index note, the crate docs, doc comments, test comments, the web reader's README and its modules, and the suite's own CLAUDE.md. The checker they pointed at is gone, and an id whose checker is gone is a pointer to nothing that comes back as a number. Each citation is rewritten so the measured fact and the reasoning stay in words and the pointer goes: "measured at full scale, the ordered load trailed LMDB" rather than an id in parentheses. Verdict vocabulary -- holds, fails, refuted, recorded as -- goes with them. Where a sentence was only a pointer it is deleted. No number in the text changed, and the only non-comment line changed is one assert message. Also from Copilot's review: the build script watches packed-refs and the branch ref only when they exist, since cargo treats a watched path that does not exist as changed on every build; and the workflow lint now checks one-line `run:` entries, which are most of them, not only block scalars. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01F2wxgRU31dUrqaY8KwfsA2
There was a problem hiding this comment.
🟡 Changes recommended
The new bench/scripts/libclang.sh Linux probe can exit successfully on a versioned libclang-*.so even though the script’s own stated failure mode requires a libclang.so, risking CI breakage unless that condition is tightened.
Once you've addressed the issues Copilot identified, you can request another Copilot review.
Review details
- Files reviewed: 106/274 changed files
- Comments generated: 2
- Review effort level: Lite
The comment claimed the release profile was the engine's settings repeated, while the engine asks for full debug info and this asks for line tables. Every setting that decides code generation is the same; the debug level differs on purpose and the comment says so. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01F2wxgRU31dUrqaY8KwfsA2
There was a problem hiding this comment.
🔵 Needs a closer look
It makes wide, repo-spanning changes to benchmarking infrastructure and CI-adjacent tooling (new bench/ workspace + removal of legacy suite artifacts), which warrants final human verification end-to-end.
Review details
- Files reviewed: 106/274 changed files
- Comments generated: 0 new
- Review effort level: Lite
A segment's head reserve holds the block table, the key section's checksum row and copies of the fence and the directory, and it has to be sized before the first key is written. A streaming caller can only guess, and both ways of guessing wrong are invisible: too small and the pieces that do not fit go after the data, costing the sparse reader a round trip, and too large and every segment carries zeroes it will never use. So a floor under the guess was wrong in both directions. `reserve::for_lengths` computes it from the key and run lengths a caller that gathered its input already has. It restates none of the layout: it plans the key section with `flatindex::plan_inline`, the call the writer makes, over placeholder keys of the caller's lengths, and takes the block table's size from a new `flatindex::block_table_len` that `encode_blocks` now allocates by. The only arithmetic here is the cut into blocks, which is the writer's rule and four lines. The answer is minimal, not merely sufficient, and a test says so by binary-searching the smallest reserve a reader can still open and seek from and holding the estimate to it. What is over is twelve bytes: the checksum row is cut on the object's pages, so its length depends on where the section lands and that depends on the answer, and it is taken at its worst alignment. `reserve::from_totals` bounds it for a caller that knows only totals. It asks for the longest key and the longest run as well, because without them there is no bound: the fence copies whole keys, and a run that does not fit closes a block early. The four pieces are returned separately, because the last is a decision. The directory copy is four bytes a key and buys a lookup that plans with no second wave; `Reserve::without_directory` prices it. `SegmentWriter::write_sorted` does the whole thing for input in hand. A test holds it to the streaming writer byte for byte. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01F2wxgRU31dUrqaY8KwfsA2
There was a problem hiding this comment.
🔵 Needs a closer look
It’s a large repo-wide suite/CI/workflow restructuring with extensive deletions and new benchmarking infrastructure that warrants final human validation beyond static review.
Review details
- Files reviewed: 106/275 changed files
- Comments generated: 0 new
- Review effort level: Lite
The batch writer took `inline_max` as a bare argument and had nowhere to put the rest, so it never called `set_compress` or `set_sync_every`. A caller asking for a compressed segment got a plain one and nothing said so -- which is the failure `SegmentOptions` refuses a compression field to avoid, reproduced one layer up. Its note names the precedent: a setting nothing reads does nothing quietly, and that is how a test came to check the plain path while claiming to check the compressed one. `SegmentWrite` carries the per-file settings, one field per setter on the writer, so the next setter's absence is a compile error here rather than a quiet default. It also carries whether the head reserve holds a copy of the hash directory, which was previously always yes: four bytes a key for a lookup that plans from the probe. Three tests. One asks the file rather than the flag -- a compressed segment of compressible values must be smaller than the plain one, and must still read back the values that went in. It fails against the bug it was written for, with the two sizes identical. One holds each setting to the streaming writer byte for byte. One pins that compression does not move the reserve, since blocks are cut on the staged payload before anything compresses it, and that is worth a file on disk rather than an argument. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01F2wxgRU31dUrqaY8KwfsA2
There was a problem hiding this comment.
🔵 Needs a closer look
It restructures and replaces the repository’s entire benchmarking/test artifact system (including new workspace + CI-facing scripts), which warrants final human verification across platforms.
Review details
- Files reviewed: 106/275 changed files
- Comments generated: 0 new
- Review effort level: Lite
The macOS runner failed the new batch-writer test on the `sync_every` arm, which is the one setting that cannot change a byte: it moves when fdatasync happens, not what is written. The cause was not the setting and not the writer. A segment's superblock records SystemTime::now() in seconds as its third field, and the FNV-1a over the fields that follows covers it, in each of the two slots -- so two writes of identical input differ in eighteen-odd bytes whenever they straddle a tick. Comparing whole files is a test that passes on a fast machine and fails on a slow one, and it did: green here, red there, on an arm where nothing about the setting touches the file. The comparisons now normalise those four words away and compare everything else, superblock offsets included, since those are what a mis-applied setting would actually move. Worth writing down for whoever measures this next: the timestamp means two builds of the same input are not the same bytes, so a segment cannot be content-addressed or cache-validated across builds. That is a property of the format rather than of this change, and nothing here depends on it either way. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01F2wxgRU31dUrqaY8KwfsA2
There was a problem hiding this comment.
🔵 Needs a closer look
The change set is a large benchmark/CI/tooling restructure with substantial deletions and new suite wiring that merits final human verification end-to-end.
Review details
- Files reviewed: 106/275 changed files
- Comments generated: 0 new
- Review effort level: Lite
Net result: the old suite — the six experiment binaries,
claims.json,results/,figures/, the external comparators, the browser test and the plan files — is gone from this repository, and the rewritten suite lives atbench/as its own cargo workspace. For your review — not merged.The history is honest about how it got here. The first commits split the old suite out to supdb-bench and pointed CI at it; the rewrite happened there (supdb-bench#6, reviewed and green); the last commit brings the rewritten suite back, because at ten source files, one binary and a
runs/directory the second repository cost more than it guarded — a paired PR for every change touching both, a submodule pointer and a branch override so CI tested the right engine, and the engine's release profile silently ignored under the other workspace.What is in bench/
bench run --scale quick|fullmeasures the two floors, then every arm over a ladder of store sizes, and writes one row of raw per-rep samples underbench/runs/<scale>/<utc>-<sha7>.json.bench gate ROWcompares a row to the last ten rows of its machine class.bench figuresdraws every figure from the latest row of each class.bench machineprints the host as a row records it.bench/DESIGN.mdis the specification.load,load-shuffled,read,scan,ycsb-A…ycsb-Fwal-floor(framed 1,000-record batches, one fdatasync each),scan-floor(one mmap sequential walk)supdb,supdb-noadvice,lmdb,rocksdb-tunedsupdb-ingest,lmdb-nosync,rocksdb-nosyncquickfullWhat this changes here
bench/is its own workspace, depending on the engine by path. The engine'scargo buildandcargo testnever pay for the comparators' C++ build and its lockfile never lists them. Cargo takes profiles from the root of the workspace being built, so the engine's release profile is repeated inbench/Cargo.tomlwith the reason.sha. One commit now names the engine and the suite that measured it.scripts/check.shgainsbench(the suite's build, test and lint; in the default set) andquick(one measurement, the gate againstbench/runs/, the figures; not in the default set because a timing run needs the machine to itself).benchin the three-platform matrix with a libclang step for bindgen, andquickin a job of its own that uploads the row and figures as artifacts. The job that cloned supdb-bench is gone. The three workflows that ran the suite move here (apple-silicondetect,quiet-bench,runner-smoke) with paths adjusted, and.localmostrcreturns to the root.fullrow is committed and drawn.CLAUDE.mdgets abench/section andbench/CLAUDE.mdcarries that side's rules.CLAUDE.mdsays so; scrubbing about two hundred of them is a separate decision.Verified
Engine:
sh scripts/check.sh build test lint, 80 tests, clippy-D warningsclean, formatted. Suite: its own build, test and lint clean, 33 tests; a smoke run writes a row with the singlesha, the gate andfiguresread it back; every workflowrun:block parses. The suite's own CI was green on all five checks at supdb-bench's head before the move, including the cold RocksDB build on macOS.🤖 Generated with Claude Code
https://claude.ai/code/session_01F2wxgRU31dUrqaY8KwfsA2