FFFF bench: publish bounded v7-to-v8 migration sweep (#838) by adityamukho · Pull Request #851 · project-minigraf/minigraf · GitHub
[go: up one dir, main page]

Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

### Documentation

- **Manual migration sweep** (#838): [frozen fixtures, timings and correctness evidence](docs/benchmarks/838-migration/README.md) for native v7-to-v8 migration through 200k facts and Chromium/Firefox/WebKit through 20k facts. Includes nonmigrating native read-only open, v8 reopen and bounded post-migration cursor churn; larger browser cases and sustained pin scaling remain excluded. No production or nightly-route change.

- **Benchmark exclusions audit** (#836): [pinned enumeration and per-shape dispositions](docs/benchmarks/836-exclusions/README.md) reconcile 156 unselected native IDs, retain 110 manual row-frame cases, and distinguish linear full-prefix UDF accumulation from bounded replay. No new latency measurements or runtime changes.

- Retire tracker #383 in favor of the v3.0.0 milestone and its release gates. Ordinary/window value-handling consistency is completed by #789.
Expand Down
2 changes: 2 additions & 0 deletions CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ Minigraf is a tiny, portable **bi-temporal graph database with Datalog queries**

See `ROADMAP.md` for planned work and current direction. See `CHANGELOG.md` for completed-release history. The [#836 benchmark audit](docs/benchmarks/836-exclusions/README.md) records the 156 unselected native IDs and per-shape manual dispositions; it changes no runtime behavior or test counts.

The [#838 manual migration sweep](docs/benchmarks/838-migration/README.md) covers native v7 migration through 200k facts and Chromium/Firefox/WebKit through 20k facts, including bounded post-migration cursor churn. It changes neither nightly coverage nor the Rust test inventory; larger browser cases remain excluded.

## Core Philosophy - CRITICAL

**Before implementing ANY feature or change, you MUST assess it against the design philosophy in PHILOSOPHY.md.**
Expand Down
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,8 @@ The unreleased v3.0.0 branch supports ordinary `(avg ?score)` (#777). It skips n

The unreleased v3.0.0 branch adds bounded sliding windows such as `(avg ?salary :over (:partition-by ?dept :order-by ?hire-date :rows 2 preceding))` (#183). See the [benchmark coverage and manual-case dispositions](docs/benchmarks/836-exclusions/README.md) for the limits of nightly coverage (#836). Memory/scaling acceptance is checked separately from latency; see the [acceptance bounds and validation status](docs/benchmarks/837-acceptance-gaps.md) (#837).

The [manual v7-to-v8 migration sweep](docs/benchmarks/838-migration/README.md) (#838) measures native fixtures through 200k facts and browser fixtures through 20k facts, with separate read-only/reopen controls and bounded cursor churn. These measurements do not expand nightly coverage or establish cold-start and sustained-reader bounds.

On v3.0.0, an ascending value-only query such as `[:find ?v :where [?e :score ?v] :order-by [?v] :limit 10]` can read directly in index order and stop early when all committed `:score` history has one value kind (integer, float, or Boolean) and its source range has no pending writes. A query whose full order cannot be proved uses the existing sort (#641). Built-in `count`, `count-distinct`, `sum`, and `avg` can release completed groups when the pinned source proves their grouping order (#781). `min`/`max` also qualify when their arguments are proved Integer/Float/Boolean/nil; `sum-distinct` requires Integer/nil. A single Integer/Boolean/Float key (including mixed numeric groups) is supported. A longer effective tuple, including hidden `:with` keys, must reduce to one varying Integer/Boolean slot plus repeated occurrences and proved Integer/Boolean/nil constants. Any requested final Sort is retained for `:with`. Small grouped point queries pay proof startup cost; see the [measurements](docs/benchmarks/781-ordered-aggregate.md). Memory follows the active group and batches; distinct members within one group still grow. A limit can stop after enough emitted groups, but dropped min/max groups do not count and a retained Sort drains the input. Callbacks, `collect-set`, aggregate+window queries and unproved arguments keep full-input evaluation. When every built-in window uses the same proved nonconstant partition key, the engine can also finish and release one partition at a time. Its memory follows the largest partition plus bounded batches; one growing partition still grows. Unpartitioned windows, incompatible keys, aggregate queries, callbacks and `collect-set` keep full-input evaluation. A surrounding sort or distinct operation can still require more memory.

On the unreleased v3 branch, selective in-memory ancestor queries can use entity probes instead of reading the whole edge attribute (#723). This is a query-planning optimization; it adds no storage index or configuration.
Expand Down
1 change: 1 addition & 0 deletions ROADMAP.md
Original file line number Diff line number Diff line change
Expand Up @@ -130,6 +130,7 @@ Scope — release-gate testing and documentation:
- Long-running soak test at scale (#392; done on `v3`: `tests/soak_test.rs`, 10M facts and a 5-hour churn weekly, alternating `main` and `v3`)
- Benchmarks at 100K–10M facts and a published performance envelope (#394; on `v3`: `examples/perf_envelope.rs`, results in `docs/BENCHMARKS.md`; follow-ups #528–#532, with #532 superseded by #551's removal of repeated committed-fact net-assert; [audit and measurements](docs/benchmarks/532-net-assert-audit.md))
- Acceptance evidence for memory/scaling (#837): named-test and Linux RSS gates, nonlinear/multistratum recursion and custom chunk bounds; [validation status](docs/benchmarks/837-acceptance-gaps.md)
- Manual migration evidence (#838): native v7-to-v8 through 200k facts; Chromium/Firefox/WebKit through 20k facts, with separate read-only/reopen controls and bounded post-migration cursor churn. [Results, frozen fixtures and exclusions](docs/benchmarks/838-migration/README.md); no new nightly route or sustained-pin bound.
- Expression keyword/ref equality (#774; on `v3`): resolve literal keywords once per operator, with memory bounded by the expression. [Measurements and regression coverage](docs/benchmarks/774-expression-keywords.md); performance-only, with no v2.x backport.
- Higher storage/WAL coverage gates and branch-coverage gates (#396; on `v3`: line and branch floors per file in `coverage-thresholds.toml`, checked on every PR)
- Durability, recovery and operations guide (#398; done on `v3`: `docs/DURABILITY.md`, also on the docs site; found #535)
Expand Down
8 changes: 8 additions & 0 deletions docs/BENCHMARKS.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,14 @@

This document records reproducible local benchmark snapshots. Completed release-performance history belongs in the [CHANGELOG](../CHANGELOG.md); continuous CI history is available on [Bencher](https://bencher.dev/perf/minigraf/plots).

## Manual v7-to-v8 migration (#838, unreleased)

The [manual migration report](benchmarks/838-migration/README.md) retains frozen
v7 fixtures, native timings through 200k facts and Chromium/Firefox/WebKit timings
through 20k facts. Migration, nonmigrating read-only open, v8 reopen and bounded
post-migration cursor churn are separate operations. The report records the
larger browser exclusions; it adds no nightly coverage or sustained-reader bound.

## Nightly chunk-boundary transactions (#776 P09, unreleased)

Seven `insert_file/chunked/` cases cover G10 using the default 65,536-fact
Expand Down
7 changes: 7 additions & 0 deletions docs/TEST_COVERAGE.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,13 @@
Counts above are the current Cargo test inventory (active versus ignored),
including #777, #789, #781, #794, #795 and #837 (Linux). Verification results below identify which suites ran.

**#838 manual migration verification**: the [manual sweep](benchmarks/838-migration/README.md)
checks every fixture value and cursor snapshot before accepting timings, including
post-migration writes and reopen on native storage and three browser engines.
The 2 golden-corpus and 7 migration-matrix tests pass, alongside five standalone
Python evidence-integrity tests. These manual probes add no Rust tests to the
inventory above and do not establish crash, cold-start or sustained-pin bounds.

**#794 verification (2026-10-30)**: one added `storage::keys` unit test checks that a set's element encoding equals its elements' encodings, ordered and deduplicated by a `BTreeSet`, over 2,000 random sets of up to about 60 elements with duplicates, signed zeros, NaNs and strings up to 300 bytes, in shuffled, sorted and reversed order. It passes with both the old stable sort and the new unstable sort. The full default suite passed before merging #795 (2,038 active, 19 ignored). CI-equivalent native, browser and WASI clippy pass on Rust 1.99.1, and Rust 1.89 checks all features. The release binary is 1,260,568 bytes (3,024 smaller), below the unchanged 1,263,616-byte cap.

**#781 verification (2026-10-29)**: 24 active tests and two ignored measurement
Expand Down
6 changes: 3 additions & 3 deletions docs/bench-coverage-v3.md
Original file line number Diff line number Diff line change
Expand Up @@ -380,10 +380,10 @@ shortlist. No manual timing or release sign-off is implied by this close-out.
| --- | --- | --- |
| X01 | MANUAL / EXCLUDED registered cases | Of 583 registered native IDs, 156 are unselected: 110 `window_rows/` cases are MANUAL wider width/function/partition sweeps; four history depth-500 IDs and six retract 1k/100k/1m IDs are EXCLUDED redundant intermediate/scaling points; six pending `btree_lookup/` IDs are EXCLUDED duplicates of C01; 30 synthetic SIMD IDs are EXCLUDED experimental non-engine kernels. Exact expansions are in Appendix C. The [#836 pinned reconciliation and per-shape dispositions](benchmarks/836-exclusions/README.md) retain all exclusions. Full-prefix one-partition UDF execution stays manual but uses a linear running accumulator, not quadratic replay; the unregistered 100k UDF half-frames remain excluded for replay cost |
| X02 | ENVELOPE / acceptance, partial execution verified | [#837 evidence](benchmarks/837-acceptance/README.md): all five scheduled jobs/seven tests passed; linear recursion/INT-020, QRY-012, limit/top-k caps, default-chunk million-fact transaction and storage bounds observed. Still open: nonlinear/multistratum scaling, custom chunk bounds, explicit RSS assertion execution and future zero-test protection. These are not Bencher memory metrics; accounting has no disabled-engine control, and unlimited only disables the finite cap |
| X03 | MANUAL migration | Native migration uses one small frozen v7 fixture, not a large dictionary/scale sweep. Browser migration and migration with pinned-reader churn have no V timing; IndexedDB open/write coverage is not migration coverage |
| X04 | MANUAL binding checks | JVM/JNI, Android ART/ABI/device storage, Swift ARC/Apple storage and WASI need distinct runtime evidence/release sign-off. Options/error paths, foreign FactLog/LogWriter conversion, foreign preparation/registration latency and browser pinned-reader churn remain unmeasured. Python shared UniFFI coverage does not measure other host runtimes; no binding RSS bound is asserted |
| X03 | MANUAL migration | V retains its small native fixture. [#838 manual evidence](benchmarks/838-migration/README.md) separately measures native v7-to-v8 through 200k facts and Chromium/Firefox/WebKit through 20k facts, plus bounded post-migration cursor churn. Read-only v7 open is nonmigrating; same-context reopen is not cold startup. The 200k browser rung and sustained pin scaling remain excluded. These manual samples are not V or new nightly coverage |
| X04 | MANUAL binding checks | JVM/JNI, Android ART/ABI/device storage, Swift ARC/Apple storage and WASI need distinct runtime evidence/release sign-off. Options/error paths, foreign FactLog/LogWriter conversion, foreign preparation/registration latency and browser reader churn beyond [#838's bounded persistence case](benchmarks/838-migration/README.md) remain unmeasured. Python shared UniFFI coverage does not measure other host runtimes; no binding RSS bound is asserted |
| X05 | Unverified operational follow-ups | Accumulate numeric regression baselines for 244 native and 26 foreign IDs (all have stored v3 observations/model settings, but baseline null in V). Verify live failed-upload and repeated-alert notification delivery; successful uploads and parser/audit unit tests do not exercise it. Cron execution of the final routes is unverified here: V was a dispatch. Preserve/refresh evidence beyond the 30-day artifact retention |
| X06 | MANUAL / ENVELOPE scaling and isolation | Large 10m sorting/window/envelope sweeps, wider set cardinalities, sustained pin/quarantine/log-reader churn and sparse/repeated-ref UUID projection are outside V's fixed shortlists. Dedicated isolation of each recursive-probe optimization is unverified; representative queries do not establish per-optimization timings |
| X06 | MANUAL / ENVELOPE scaling and isolation | Large 10m sorting/window/envelope sweeps, wider set cardinalities, sustained pin/quarantine/log-reader churn and sparse/repeated-ref UUID projection are outside V's fixed shortlists. [#838](benchmarks/838-migration/README.md) measures only eight commits with one old cursor plus a short-lived cursor per commit; it establishes no sustained-pin or quarantine-memory bound. Dedicated isolation of each recursive-probe optimization is unverified; representative queries do not establish per-optimization timings |
| X07 | EXCLUDED exhaustive semantics | All numeric, bind, cross-kind join and forced-planner permutations remain correctness tests. Nightly controls select representative natural plans; broader hash controls include broader scans and keyword dynamic controls include binding/clone work |
| X08 | EXCLUDED individual failure latency | Invalid bounds/windows/binds, deliberate callback errors, corrupt-page rejection, v1–v6 refusal, heavy single-entry WAL replay and individual PRS/API/QRY codes belong to correctness testing. C08 measures a successful repair of known damage and C30 measures cross-chunk rollback; neither claims exhaustive failure timing |
| X09 | EXCLUDED unshipped/non-runtime scope | Public profiler #185, OPFS #441 and rule persistence #241 are open/unshipped at the audited revision. Proof/test/docs infrastructure and #797's study add no shipped latency path; production uuid/dist size uses separate size gates. Re-audit new production features through the release cut |
Expand Down
Loading
Loading
0