Add UnivMon-Q and correct UnivMon - #81
Merged
Merged
Conversation
Contributor
Author
Performance versus UnivMonQuick benchmark: 250K observations, 12 levels, width 2,048, depth 5.
UnivMon-Q was approximately 18× faster to update and merge than terminal UnivMon. At equal candidate capacity, it used about 43% less memory. Query latency
Preparing the reusable query view costs 388 µs. A complete multi-metric batch takes approximately 389 µs, compared with 292 µs for standard UnivMon and 862 µs for terminal UnivMon. Standard UnivMon remains best for isolated universal queries. UnivMon-Q provides much faster ingestion and merging, while prepared views amortize reconstruction across F0/F2/F3/entropy/heavy-hitter/rank/quantile/CDF queries. Accuracy snapshot
Results are workload- and machine-dependent; the benchmark is included for reproducibility. |
GordonYuanyc
approved these changes
Aug 4, 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.
Fixed UnivMon bugs
This PR first corrects several correctness and merge issues in the existing UnivMon implementations:
Missing per-layer L2 updates: Standard
insertdid not correctly maintain CountSketch/L2 state at every sampled logical layer.Incomplete Joltik update path:
fast_insertdid not fully implement terminal-stratum storage with logical-layer reconstruction at query time.Unsafe update-mode mixing: A sketch could mix standard and terminal-only updates, producing state that neither query algorithm could interpret correctly.
Negative terminal updates: Terminal-only reconstruction assumes insertion-only streams, but negative weights were previously accepted.
Stale candidate frequencies: Queries used counts stored in heavy-hitter heaps instead of re-estimating candidates from current CountSketch counters.
Incorrect merge candidate counts: Merges combined candidate metadata without consistently re-estimating frequencies from the merged counter state.
Stale merged L2 norms: CountL2HH cached row norms were not recomputed after counter arrays were merged.
Incorrect stream-weight accounting: UnivMon merge and experimental window paths could omit or double-count aggregate stream weight.
Fixed cardinality cutoff: Cardinality used a fixed heavy-item cutoff instead of a threshold derived from L2 and candidate capacity.
Unknown candidate completeness: The implementation did not track when bounded heavy-hitter storage had evicted identities, making zero-threshold estimation unsafe.
Empty entropy behavior: Entropy on an empty sketch did not consistently return zero.
Legacy-state handling: Older MessagePack states lacked update-mode and candidate-completeness fields and required normalization during decoding.
The corrected implementation now maintains distinct standard and terminal update modes, reconstructs logical terminal layers at query time, refreshes candidate estimates from counters, and performs merge reconstruction from the combined state.
Summary
This PR also adds
UnivMonQ, a mergeable universal sketch that combines frequency-vector metrics with ordered queries.UnivMon-Q supports:
Exact observation count, minimum, and maximum
Point-frequency estimation
F0, F2, and F3
Generic compatible g-sum queries
Shannon entropy
Heavy hitters
Rank, CDF, and quantile queries
Compatible merges and tumbling windows
Native MessagePack serialization
Pluggable hashing
UnivMon-Q construction
Updates use a Joltik-style terminal-stratum layout:
One 128-bit hash is split into CountSketch bucket/sign fields, terminal-level selection, and ordered-sample priority.
Each observation updates only one physical CountSketch layer.
Logical UnivMon levels are reconstructed during queries.
A coordinated bottom-k residual sample provides ordered distribution coverage.
Bounded candidate summaries recover heavy values.
This keeps the update and merge paths substantially cheaper than maintaining every logical layer.
Query API
The direct API includes:
For multi-metric query batches, callers can reconstruct query state once:
The prepared view shares candidate recovery, logical hierarchy reconstruction, F2 thresholds, and CDF construction across queries.
Query-performance improvements
The optimized reconstruction:
Hashes and estimates each retained candidate once.
Scans each physical CountSketch once for F2 thresholds.
Constructs suffix top-k sets incrementally.
Reuses recovered frequencies across arbitrary g-sums.
Builds one CDF for batched rank and quantile queries.
Avoids rebuilding the complete hierarchy for every metric in a query batch.
On the included 250,000-element synthetic benchmark with 64 candidates:
Results are workload- and machine-dependent; the benchmark is included for reproducibility rather than as a universal performance guarantee.
Accuracy snapshot
For the same synthetic workload:
All constructions recovered the four true heavy hitters.
UnivMon-Q F2 relative error was below 0.01%.
UnivMon-Q F3 relative error was approximately 0.02%.
The memory-matched UnivMon-Q configuration achieved:
F0 error: 8.73%
Entropy error: 1.51%
p50 error: 0.32%
p90 error: 0.32%
p99 error: 0.33%
Compatibility
UnivMon-Q is currently marked
Unstable.It does not yet have an ASAPv1 cross-language kind identifier.
Its native serialization uses a validated MessagePack DTO.
Compatible merges require identical dimensions, seed, counter width, ordered-sample configuration, and hasher type.
Existing UnivMon decoding normalizes legacy states without the new update-mode and candidate-completeness fields.
Validation
550 library tests passed.
All integration-test suites passed.
20 documentation tests passed.
cargo clippy --all-targets --all-features -- -D warningspassed.Formatting and diff checks passed.
Included examples
examples/quantile_univmon_q.rsexamples/compare_univmon_q.rs