Conversation
flamboh
added this pull request to stack #113
September 25, 2026 10:48
Replace address_structure_stats with address_maad_stats: one rowid row per scope, side and measure with REAL dimensions, INTEGER metadata, and tau, tau_sd and spectrum as little-endian f32 blobs. The q grid is stored once in maad_q_grid. Verify checks blob lengths against the grid and spectrum presence per measure; compare checks f32 arrays element-wise within the MAAD tolerance. Bumps the product schema to 7 and the MAAD contract to 6.
Routes read address_maad_stats and decode tau, tau_sd and spectrum blobs (Uint8Array, ArrayBuffer or D1 number[]) with the q grid from maad_q_grid. Migration 0006 drops address_structure_stats for the rebuilt product.
flamboh
force-pushed
the
maad/07-compact-storage
branch
from
September 27, 2026 05:17
9d9a6b7 to
08c62c1
Compare
This was referenced Sep 27, 2026
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.
Note
🤖 Claude Opus 5.5 on behalf of Oliver
ELI5
MAAD results used to be saved as big JSON text, 7 rows per time bucket. Now each measure gets one row of packed 32-bit number arrays, so a day of data shrinks from ~660 MB to ~70 MB. The charts show the same numbers.
Why
After the rest of this stack, MAAD JSON took up 92% of each day's database. A 390-day reprocess would be ~257 GB, and parsing that JSON was the main cost of the chart routes. A design study on a real day compared compact JSON, typed columns, f64/f32/f16 blobs and several index layouts. f32 blobs in a rowid table won: they were 12.6× smaller, and their rounding error stays far below MAAD's own sd. Decimal rounding and f16 were rejected because 22% of sd values are below 1e-3.
What changes
address_maad_statsreplacesaddress_structure_stats. It has one row per scope, side and measure, with:d0/d1/d2tau,tau_sdandspectrumas little-endian f32 BLOBs.spectrumholds interleaved (α, f) pairs of variable length: zero-length means computed but empty, and NULL means not computed (packets/bytes).(granularity, bucket_start)index.maad_q_gridstores the q grid once per IP version.value as f32. The product schema moves to 7 and the MAAD contract to 6, which needs a fresh product DB.0006, all identical):taumust be a non-empty BLOB of whole f32 values.tau_sdmust have the same type and length astau.spectrummust be a BLOB of whole (α, f) pairs.q_countis enforced byverifyand by the API instead.verifychecks blob lengths against the grid and spectrum presence per measure.extractcopiesmaad_q_grid.comparechecks d-values and curves element by element. It also requires identicalmaad_q_gridrows for every IP version whose curves both databases store in the window. A grid that is missing or different on either side makes the result incompatible, and the report lists those versions inmaad_q_grid.mismatched_ip_versions.decodeF32, which acceptsUint8Array,ArrayBufferor D1'snumber[]. Response shapes are unchanged. A non-NULL curve must have a grid, andtau/tau_sdmust each hold exactlyq_countvalues. A misaligned blob or an odd spectrum is also rejected. Any of these returns the route's 500 database error instead of a partial or empty chart.Review path
netflow-db pipeline, then runverifywith all--require-*flags. Expected: OK.measure=packetson a spectrum route still returns 400.compareon the rebuilt DB against a copy of itself, then again afterUPDATE maad_q_grid SET q_step = 0.25on the copy. Expected: the first is compatible, and the second exits nonzero withmismatched_ip_versions: [4, …].UPDATE maad_q_grid SET q_count = q_count + 1and open a structure chart. Expected: the route returns 500 ("Database query failed" / "Failed to get structure statistics") and no chart is drawn.Deployment and decisions
0003/0005are therefore not restructured: on that path their intermediate table copies run against an empty DB.0006has not been applied anywhere, so its CHECKs were edited in place rather than added in a new migration. Applying0006to a populated legacy D1 would drop the old MAAD table without converting it.comparebetween different builds may need--maad-absolute-tolerance ≈ 1e-6, because values can round to neighbouring f32s.Verification
bun run format,bun run lint,bun run typecheck,cargo fmt --check, clippy-D warnings,test:dbandtest:web.q_countmismatch, missing or shorttau_sd, odd spectrum.compareon a changed q_min, a changed q_step, a deleted grid row and a dropped grid table.test:e2epasses on the restacked branch (9 tests), using the shared local schema fixture from feat: classify endpoint locality and filter by traffic direction #108.verifyOK.Made by Claude Opus 5.5 (with Opus 5.5 subagents) via Claude Code.