Skip to content

feat(gos): CountMinSketch insert-time delta gate (T=εN/k) - #525

Merged
zzylol merged 1 commit into
mainfrom
split/pr-gos-cms
Jul 17, 2026
Merged

zzylol merged 1 commit into
mainfrom
split/pr-gos-cms

Conversation

@zzylol

@zzylol zzylol commented Jul 16, 2026

Copy link
Copy Markdown
Contributor

Part of the GOS per-family stack (base: CountSketch split/pr-gos-countsketch / #524). Converts CMS's delta gating to insert-time detect+reset (design §11). Formula T=εN/k — max-composition, no √(dw) (derivations §8.2); N read from the sketch's existing incremental per-row L1 accumulator (CM_L1(), min-across-rows), decremented on GOS resets — no new tracking field. Depends on sketchlib-go #74.

Wiring mirrors CountSketch: SetGosMode/dirty-list/wake-signal/drainGosDelta in cms.go, CMSIsotropicThreshold in gos_threshold.go, SketchTypeCountMinSketch branches in subWindowShouldEmit/subWindowMarkEmitted, factory priming at series creation, gos_delta_epsilon accepted for family=countminsketch. applyGosMode needed no change (already generic).

Known interaction with sampling PR #518 (not a blocker for THIS PR, flagged for #518's reattachment): #518 adds row-sampled insert paths (InsertWithHashSampledPerRow and ApplyAdmittedOccurrenceInsertWithHashAtRows) that bypass the GOS threshold check, so a CMS with BOTH sample_p<1/row-admission AND gos_delta_epsilon>0 would silently skip insert-time detection. Composing them needs GOS-aware sampled-insert primitives (or explicit mutual-exclusion) — #518's job when it rebases onto this stack. Estimates stay unbiased; only the GOS mechanism is lost for sampled sketches.

Test plan

  • wrapper: empty-drain→nil, wake-fires-once-and-clears, telescoping via ComputeDeltaAgainst+ApplyDelta.
  • processor: TestGOSCMSInsertWakesFlushSubWindowInterval unset, WindowDuration=1h, ConsumeMetrics alone produces a flush (no manual wakeSubWindow).
  • go build/go vet/go test clean in asap-precompute-go + processor.

🤖 Generated with Claude Code

Converts CountMinSketch to the same insert-time GOS mechanism CountSketch
already has (design-gos-unified-edge-telemetry.md §11): checks each
just-touched cell's magnitude against a closed-form threshold at insert
time instead of a periodic decode-prev-diff sub-window scan, resetting
crossed cells in place and waking the flush loop immediately.

CMS's closed form is simpler than CountSketch's: T=ε·N/k (derivations
§8.2), an L1-scale, max-composition bound with no water-filling and no
√(dw) factor (CMS's point query is a min over d cells, so staleness is
bounded by the single worst stale cell). N (current total mass) comes from
the sketch's own incrementally-tracked per-row L1 accumulator (CM_L1,
O(rows)), which sketchlib-go's InsertWithHashGOS now keeps correct under
in-place resets the same way L2 already was — sketchlib-go commit
b28a39579eeb5447284ced3cf29574ec7f33008b
(ProjectASAP/sketchlib-go@feat/gos-cms-primitive).

- asap-precompute-go/sketches/cms.go: CMSWrapper gets SetGosMode,
  gosDirty/gosWake/ConsumeWakeSignal, drainGosDelta (the ComputeDeltaAgainst
  branch that drains the dirty list instead of decoding prev), and
  GosDeltaThreshold/currentMass (CM_L1-backed).
- asap-precompute-go/sketches/gos_threshold.go: adds CMSIsotropicThreshold
  (T=ε·N/k), alongside CountSketch's F2IsotropicThreshold.
- asap-precompute-go/precompute.go: subWindowShouldEmit/subWindowMarkEmitted
  get a CountMinSketch case analogous to the existing CountSketch one
  (applyGosMode needed no change — already generic via a structural
  interface assert).
- opentelemetry-collector-contrib-patch/processor/asapedgeprocessor/
  warm_sketch.go: the CMS factory primes SetGosMode at series creation
  (subWindowEnabled's GosDeltaEpsilon decoupling was already
  family-agnostic, no change needed there).
- config_validate.go: gos_delta_epsilon now also accepts
  family=countminsketch (no emit_heap exclusion needed — CMS has no heap
  variant).
- go.mod (asapedgeprocessor): repoints the sketchlib-go replace at this
  worktree's own sketchlib-gos-cms fork (was resolving to the shared,
  unconverted /mydata/sketchlib-go checkout), mirroring
  asap-precompute-go/go.mod's existing replace.

Tests: sketchlib-go-level (gos_test.go, prior commit), wrapper-level
(cms_gos_test.go: empty-drain-nil, wake-fires-once, telescoping via
ComputeDeltaAgainst+ApplyDelta), and processor-level end-to-end
(gos_cms_test.go: ConsumeMetrics alone, with SubWindowInterval unset and
WindowDuration long, produces a flush with no manual wakeSubWindow call).

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
@zzylol
zzylol force-pushed the split/pr-gos-cms branch from 5d94521 to b26248e Compare July 17, 2026 01:16
@zzylol
zzylol changed the base branch from split/pr-gos-countsketch to main July 17, 2026 15:46
@zzylol
zzylol merged commit e2e2041 into main Jul 17, 2026
@zzylol
zzylol deleted the split/pr-gos-cms branch July 17, 2026 15:52
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant