Repository navigation
Conversation
…APIs Pin eb04e7f (release 0.4.0) instead of planner-pin/sketch-library-fixes. WeightedFrequency wraps main's f64 CountMinSketchWithHeap / CountSketchWithHeap keyed by TupleKey bytes, with executor-side weight checks and per-update heap rescoring until sketchlib #245 is released. KLL, KMV, CMS and heap memory charges use the library's memory_bytes. Remove the never-built HydraKLL accumulator. Closes #785
Contributor
Author
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.
Closes #785
Why
The workspace pinned
asap_sketchlibto the private branchplanner-pin/sketch-library-fixes(3f44cf1c). That branch is an old main plus open PRs, so the Planner could not take a sketchlib fix without staying on a private branch. Sketchlib main 0.4.0 (eb04e7f) now holds those fixes (#242). It also makes ASAPv1 the only serialization (#241), renames types (#239, #240), and adds f64 Count-Min and Count Sketch with candidate heaps andTupleKeykeys (#232, #237). On main, KLL also allocates its item buffer lazily, which is the main CPU and memory win for quantile queries.What
Cargo.toml/Cargo.lockpinasap_sketchlib0.4.0 ateb04e7f.prost,bincode,serde-big-arrayandxxhash-rustleave the lock file.CountMinSketch,KllSketch,DdSketch,HllSketch,HydraKllSketch) are replaced by main's native sketches.WeightedFrequency(CMS / Count Sketch with heap, and plain Count Sketch at heap capacity 0) is now an adapter over main'sCountMinSketchWithHeap<Vector2D<f64>, RegularPath>/CountSketchWithHeap<…>. Items are keyed by their canonicalTupleKeybytes. Sketchlib'sWeightedFrequencykernel is gone.memory_byteswhere it exists: KLL, KMV, plain Count-Min, and the heap sketches. The KLL4,608 + 32·kformula is removed. The shared-state charging rule is unchanged: stored states a query reads are not charged again.HydraKllSketchAccumulatorandHydraKllAccumulatorUpdaterare deleted. Nothing built them, and their library type is gone. Hydra-KLL is out of scope.How
check_weight,try_update_weighted) is released. The executor also keeps every counter finite: it tracks the summed magnitude of every weight added or merged in. Since no counter can exceed that sum, an update or merge that would push the sum pastf64::MAXis refused with the state unchanged. The Planner'sCountMinWeightsNotProvenNonNegativerule keeps its meaning, because Count-Min still rejects negative inputs at validation.TopKHeap::update_owned, which never evicts) before it offers the updated key. This costs O(heap_size · depth) per update, the same as the old kernel. When QueryExpr: merge BinaryOp into Compare/Arithmetic (Instance 2 of #220) #245'srescore_heapis released it can replace this loop. Merges use main's merge, which re-estimates both heaps' candidates.DdSketch::get_value_at_quantiletakes the nearest rank⌈q·n⌉, clamped to[min, max]. The executor answered with the lower order statistic at rank⌊q·(n−1)⌋, the bucket representativeγ^i(1+α). To keep answers equal,DDSketchAccumulator::quantilereads that rank from the stores main exposes (positive_store_counts,negative_store_counts,zero_count).quantile_interpolated, which the two integration tests of the checked-ratio rule used, moves next to it. The bucket mapping (⌊ln v / ln γ⌋) is the same in both versions.impl_hll_registers!and wraps them in one enum.Key code interfaces added / modified
crates/executor/src/summary_kernels/weighted_frequency.rscrates/executor/src/summary_kernels/dd_sketch.rscrates/executor/src/summary_kernels/hll_sketch.rscrates/executor/src/summary_kernels/count_min_sketch.rs,datasketches_kll.rs,univmon.rs,hydra_kll.rs(removed)Usage. A PromQL
topk by (service) (2, sum_over_time(m[5m]))withAccuracyTarget::max_error(0.01).failure_probability(0.01)reaches this PR when plan selection gets a at aCountSketchWithHeap { width: 7500, depth: 85, heap_size: 50 }raw-sample summary.precompute_raw_samples::raw_sample_summaries_compile_and_match_their_kernelscompiles that DAG and executes it. The keyed build callsWeightedFrequency::new(CountSketch, 7500, 85, 50)and thenupdate(&[Utf8(item)], weight)per sample.keyed_evaluationreadsrows(2), and the test checks that every item's score equals its exact total.Before this PR
3f44cf1c.WeightedFrequencykernel and the legacy portable wrappers.4,608 + 32·k, about 11 kB at k = 200) whatever the stream.After this PR
StateColumnUpdaterparity test,runtime_install, and every planner-layering example.Changed or relaxed expectations
stored_pane_memory_limit.rs: each KLL state now charges its lazily grown buffer, about 0.7 kB with the old 1 sample per series. The panes now take 1,000 samples per series, so each KLL fills its buffer (about 5.6 kB). The limits, and what each test proves, are unchanged; the size comments are updated.deployment.rs,state_column_updater.rs,row_reference: state fingerprints and cell comparisons readWeightedFrequency::counters()androws()instead of the kernel's serde form, which is gone.promql_numeric_regressions.rs: the CMS/CS weight check uses main's f64CountMinSketch/CountSketch. Both DDSketch interpolation tests useDDSketchAccumulator::quantile_interpolated.univmon.rstest:init_univmon/fast_insert/freebecomenew/update_weighted_terminal/clear.Answer changes and deviations
estimate()returnsusize, so the executor's distinct count is now rounded down to an integer (by less than 1). The register updates and the estimator formula are the same. No test changed.bincodekey bytes, both in output order and in eviction. Now output ties are ordered byTupleKeybytes, and a new key that ties the heap minimum is not admitted (main's heap admits strictly larger counts). This differs only for exactly tied scores; no test changed.TupleKeybytes with main's per-row seeds instead ofbincodebytes withxxh64(2·row). The same answers hold where keys do not collide, and the same bounds hold where they do.rows ≤ MATRIX_MAX_ROWScheck on weighted frequency. Move the asap_sketchlib pin to a released sketchlib main #785 asked for it, but plan selection sizes Count Sketch heaps from the binomial median tail:topk … max_error(0.01).failure_probability(0.01)gets a atdepth: 85, andnative_count_sketch_dimensions_are_not_packed_wire_dimensionsbuilds depth 55. With the check, the executor refused those planner-chosen plans (precompute_raw_sampleslost itsCountSketchWithHeapfixture). Past 20 rows, main derives each row's seed asSEED_LIST[i % 20]·(i/20+1) + i/20, anddeep_heap_sketch_rows_hash_independently(25 rows) still shows independent rows. The cost is that a state past 20 rows has no ASAPv1 encoding, which the executor does not use. Needs a decision: keep this, or cap the Planner's sizing at 20 rows.univmon::check_shape) and the Planner (hash_independent). Main's in-memoryUnivMon::check_shapedropped it, but its ASAPv1 encoder still refuses more than 20 rows, so the accept set is unchanged.Follow-ups
logical-asap-optimization/src/accuracy/estimators/*.rs): this PR only re-points the citations.univmon.rsnow citesdocs/api/api_univmon.mdandestimate_l2/estimate_cardinality, andMAX_LAYERSreadsUNIVMON_MAX_LAYERS(19, unchanged). Main's estimator bodies match the pinned ones line for line except for renames and one change:estimate_g_sumnow returns early on an empty sketch only whencount_every_keyis false. A full check of each bound against main's docs, and of the dependency on sketchlib feat: rewrite uniqExact to COUNT(DISTINCT ...) #221 (UnivMon reworked to follow the paper), is left for a follow-up.plan-selectionstill sizes KLL by its maximum item buffer (kll_items); its docs say "allocates up front", which is now "grows up to". Cost model 1 is unchanged on purpose.get_value_at_quantile(an answer change), or add a rank read upstream and dropvalue_at_rank.Hydra::query_group_total, so a group total can be enabled (the capability check and comments still say Hydra lacks it).Verification
cargo test --workspace --lockedat2dff6b98a2c294b9b8b33c106784604449b38376: 1,766 passed, 0 failed, 34 ignored (150 test binaries), including the executor parity tests,state_column_updater,stored_pane_memory_limit,runtime_installandplanner_layering_example1–4.cargo check -p asap-planner --tests --lockedpasses.