Skip to content

feat(hydra)!: port Rust's Hydra with ASAPv1 codecs; remove proto/ and the protobuf harness - #95

Open
GordonYuanyc wants to merge 2 commits into
asapv1-only/univmonfrom
asapv1-only/hydra
Open

GordonYuanyc wants to merge 2 commits into
asapv1-only/univmonfrom
asapv1-only/hydra

Conversation

@GordonYuanyc

Copy link
Copy Markdown
Collaborator

Stacked on #94 (asapv1-only/univmon). Part of the ASAPv1-only series: Go's Hydra is replaced by a port of Rust's and gets its ASAPv1 codecs for all five counter kinds; as the last importer of the protobuf code, it also deletes proto/ and the protobuf cross-language harness.

Changed (algorithm and API — breaking)

Go's Hydra was a different algorithm (unlabelled ; subkeys, an xorshift router, a global counter). It now follows Rust's: a key schema of up to 16 labels, label:value subkeys with \, :, ; escaped, the matrix hash at seed index 6, median over rows, Rust's merge rules, and a closed HydraCounter set (KLL, Count-Min, Count Sketch, HLL, UnivMon). An independent reviewer's scratch Rust + Go programs produced byte-identical envelopes after real Update streams for Count-Min, Count Sketch, HLL and UnivMon across packed-64, packed-128, per-row and non-power-of-two grids; queries match.

  • Removed API: HydraConfig, HydraDimension, MultiHeadHydra and its types, Pair, UpdateJob/ParallelUpdate, NewHydraWithDimensions, UpdateValue/UpdateWithHash/UpdateWithInput, GetCardinality/GetEntropy, TopK/SetTopKEnabled, the gob and portable formats. NewHydra(rows, cols, schema, counter) and the query methods changed signature.

Added

  • MarshalASAPv1 / UnmarshalASAPv1 (kinds 0x07 0x00–0x07 0x04); cells go through each counter's own payload hooks. All five Hydra fixtures pass CheckGolden.
  • An idle UnivMon grid decodes with the receiver's key type; mismatches name both Go key types.

Removed

  • The whole proto/ tree (no importers left) and tests/cross_language/ (it only exercised Hydra's protobuf path); go mod tidy (glog dropped; protobuf stays indirect via prometheus).

Notes / open questions

  • KLL cells: Rust's Hydra KLL cell is the §3.3 payload read by the compact decoder; Go writes the same payload from its dynamic-layout KLL and enforces the compact capacity bound. After compaction, items inside a level ≥1 can be in a different (spec-allowed) order than Rust's, so Go bytes re-encoded by Rust may differ.
  • Count Sketch cells with non-power-of-two counter_cols are rejected (Go CountSketch limitation; documented, tested).
  • KLL CDF.Quantile in Go returns the fraction strictly below x, Rust at-or-below; tracked separately.
  • The Hydra KLL counter takes float64 inputs only and has no seeded constructor.

Verification (Go 1.24.9)

go build, go vet, gofmt, go test ./..., go mod tidy -diff clean. Known flake: TestKLL_Reset_SubsequentInserts. Implemented and reviewed by separate agents; review findings are addressed in the second commit.

🤖 Generated with Claude Code

GordonYuanyc and others added 2 commits October 2, 2026 04:20
Hydra is a rows x cols grid of counters over a schema of named key columns.
Update takes one value per column and fans the record out into its 2^D - 1
subpopulations, each encoded as escaped label:value pairs joined by ";" and
placed by the matrix hash at seed index 6; QueryKey constrains any non-empty
subset of the columns and returns the median of the rows. Grids with equal
dimensions, counter variant and schema merge cell by cell. Counters are
Count-Min, Count Sketch (i32, fast), HyperLogLog (P14 Ertl-MLE), KLL (f64)
and UnivMon[K].

MarshalASAPv1 / UnmarshalASAPv1 encode the grid as kinds 0x07 0x00 to
0x07 0x04 and match the hydra_kll, hydra_cm, hydra_cs, hydra_hll and
hydra_univmon fixtures. Cells encode and decode through their counters'
own codecs and payload hooks. KLL gains K and M accessors.

A UnivMon cell keyed by string takes a value with no bytes by its Hash in
hex.

Removes HydraConfig, the global counter, TopK / SetTopKEnabled,
UpdateValue / UpdateWithInput / UpdateWithHash, ParallelUpdate,
MultiHeadHydra, the gob SerializeToBytes / DeserializeHydraFromBytes pair,
portable.go, the whole proto/ tree (no package imports it any more) and
tests/cross_language, whose only producer was hydra.pb.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
UnmarshalASAPv1 into a UnivMon grid keeps that grid's key type: an idle
grid, whose counter_key_type is "u64", decodes into it, and a grid whose
heap keys are of another type fails with an error naming both. A fresh
Hydra still takes the type counter_key_type names. Merge names both Go key
types when UnivMon grids differ in them.

A Hydra Count Sketch grid whose counter_cols is not a power of two fails to
decode with an error saying so.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
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