feat(intchunk): cold INT best-of-N lossless value chunk codec - #434
Merged
Merged
Conversation
Standalone cold-tier raw-value chunk codec from the holistic-compression
design (§1.2-1.4 + §8). Per-series-per-block best-of-N picks the smallest
of three all-lossless candidates:
GORILLA_XOR (tag 0) lossless float64 via prometheus/tsdb/chunkenc XOR;
always valid, the fallback for true high-precision floats.
INT_FOR_DELTA (tag 1) float->int64 via decimal scale exp, FOR(base),
delta, fixed-width bit-pack. For gauges.
INT_FOR_DOD (tag 2) same scale+FOR but delta-of-delta. For counters/
monotonic and the timestamp column.
The load-bearing tryScaleToInt64 guard only emits an INT_* candidate when
float->int64->float round-trips BIT-EXACTLY at the chosen scale (decode
divides by the decimal-exact 10^e, never a rounded reciprocal); otherwise
only Gorilla is offered. Overflow chunk-cut: a residual exceeding the
integer width ends the chunk and re-bases (the cold drift->re-base).
Chunk header per §1.2: codec_tag u8, n_samples uvarint, timestamps as
t0 + delta-of-delta varints; INT tags add scale_exp i8, base zigzag-varint,
first_residual. Each chunk is self-contained and independently decodable.
Tests cover lossless round-trip (gauges/counters/high-precision floats/
constants/irregular ts/negatives), best-of-N picks the smallest valid
candidate, the exactness guard rejects 15+ sig-digit floats (=> Gorilla),
overflow produces multiple decodable chunks, and a randomized fuzz pass.
A bits/sample benchmark (set INTCHUNK_BENCH_DIR) confirms the verdict:
on the real Serf datasets INT beats Gorilla ~2.2x avg on fixed-decimal
(up to 3.6x) while best-of-N falls back to Gorilla on genuine float32-
derived series (Motor-temp, Air-pressure).
NOT wired into the agent encoder or merger; integration (agent encode +
decode-on-read StoreAPI + shared-ts) is the follow-up PR6/PR7.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Add two INT sub-codecs that store the FOR delta / delta-of-delta residual stream as per-residual zigzag varints instead of a single fixed bit width: INT_FOR_DELTA_VARINT (tag 3) FOR+delta, variable-length residuals INT_FOR_DOD_VARINT (tag 4) FOR delta-of-delta, variable-length residuals Both reuse the existing residual transform, header, and overflow chunk-cut; only the trailing residual stream differs. Best-of-N now tries fixed-width AND varint for both delta and delta-of-delta and keeps the smallest valid candidate, so a block with near-uniform residuals takes the tight fixed width while a skewed block (most deltas tiny, a few large) takes varints and avoids paying the block's widest residual on every sample. The fixed tags are unchanged; decode dispatches on the tag and each chunk stays self-contained. All codecs remain bit-exact lossless and the decimal- exactness guard still rejects non-exact INT (=> Gorilla). Round-trip and best-of-N tests cover the new tags, including the varint overflow cut and a skewed-residual block where varint beats fixed width and best-of-N picks it. On the Serf datasets the per-block pick lifts the fixed-decimal aggregate from ~2.2x to ~2.3x vs Gorilla (several series now win with a varint codec) with no regression where fixed width is optimal. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
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.
Summary
Implements PR5 of the holistic-compression design (DESIGN.md §1.2-1.4 + §8): a standalone, lossless cold-tier raw-value chunk codec at
asap-gorilla-go/intchunk/. This is a self-contained library + tests + benchmark only. It is not wired into the agent encoder or the merger — integration (agent encode + decode-on-read StoreAPI + shared-ts) is the follow-up PR6/PR7.Codec
Per-series-per-block best-of-N, all three candidates lossless; the smallest wins:
GORILLA_XORprometheus/tsdb/chunkencXOR (Gorilla). Always valid; fallback for true high-precision floats.INT_FOR_DELTAINT_FOR_DODDecimal-exactness guard (
tryScaleToInt64) — the load-bearing trap-avoider: an INT_* candidate is only produced whenfloat→int64→floatround-trips bit-exactly at the chosen scale. Decode divides by the decimal-exact10^e(never a rounded reciprocal — using a reciprocal multiply wrongly rejected most fixed-decimal series and inflated the exponent). Otherwise only Gorilla is offered.Overflow chunk-cut (§1.4/§3 drift→re-base): a residual exceeding the integer width ends the chunk and starts a fresh one with a new base; each chunk is self-contained / independently decodable.
Header (§1.2):
codec_tag:u8,n_samples:uvarint, timestamps ast0+ delta-of-delta varints; INT tags addscale_exp:i8,base:zigzag-varint,first_residual.API surface
Files:
codec.go(header/tags/varint/zigzag/bit-pack),scale.go(exactness guard),intchunk.go(INT codecs + ts column + overflow cut),gorilla.go(XOR wrapper),bestofn.go(driver),codec_test.go,bench_test.go. Only new dep used ischunkenc(already transitive viaprometheus/prometheus);go.mod/go.sumunchanged.Benchmark (block=1000, real Serf datasets — bits/sample)
Class roll-up verdict: fixed-decimal gor/int ≈ 2.22× → INT wins; high-precision float → Gorilla wins (best-of-N correctly falls back). The simpler FOR+fixed-width pack lands ~2.2-3.6× vs the design's VM-adaptive ~4.8× target, which is the deliberately-simple §1.3 tradeoff. Micro-bench: encode ~194 ns/sample, decode ~52 ns/sample.
Test plan
go test ./...green (wholeasap-gorilla-gomodule)go vet/gofmtcleanINTCHUNK_BENCH_DIR=/path/to/per-series-json go test ./intchunk/ -run TestBenchmarkBitsPerSample -v(data lives outside the repo; test self-skips when unset)NOTE: no integration and no deploy — follow-up PR6/PR7.
🤖 Generated with Claude Code