Repository navigation
bloom: drop the inserted counter from the state (new ASAPv1 kind 0x17 0x01) - #256
Merged
Merged
Conversation
… 0x01) Bloom kept a count of update calls that no membership answer reads: contains, fill_ratio and estimated_fpp read the bits, and predicted_fpp takes its distinct count from the caller. Remove the field and the inserted() accessor. Per Q-VER the payload change takes a new kind id: Bloom encodes as 0x17 0x01 with payload [words]; the retired 0x17 0x00 ([words, inserted]) still decodes, with the counter dropped, and is never encoded. The golden submodule gains the bloom_bits_* fixtures. Part of #250. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
zzylol
force-pushed
the
bloom/drop-inserted
branch
from
October 29, 2026 00:03
a7d83f1 to
b85e28f
Compare
zzylol
marked this pull request as ready for review
October 29, 2026 00:03
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.
Part of #250. Golden fixtures: ProjectASAP/sketchlib-golden-bytes#5 (merge first; the submodule pointer then moves to the merged commit).
Why
A Bloom filter answers membership, and every membership answer comes from the bits.
Bloomalso countedupdatecalls in aninsertedfield, exposed it throughinserted(), and carried it in the ASAPv1 payload. Nothing the filter answers reads it.contains,fill_ratioandestimated_fppread the bits, andpredicted_fpptakes its distinct count from the caller. The count is also not a distinct count: re-inserting a key bumps it but sets no new bit.The design decision in the umbrella issue: a count of arrivals is a separate exact aggregate, not sketch state. This PR is the Bloom part of that issue.
What
Bloom's state is the bit grid. Theinsertedfield and theinserted()accessor are removed.update,mergeandclearno longer touch a counter.0x17 0x01, with payload[words]. The retired0x17 0x00([words, inserted]) still decodes, with the counter read and dropped, and is never encoded.bloom-bits-1701(25f8077), which addsbloom_bits_regular_3x128andbloom_bits_fast_5x32.insertedcounter" note, a retired-kind note, decode rule 1), the matrix-row bound paragraph, the integer-scalar list, the KMV note that compared against Bloom'sinserted, and Q-DERIVED. Also the Bloom API page,message_pack_format.md,docs/tests.md,tests/PBT_COVERAGE.mdand CHANGELOG.Deleted public API, per the delete-unused-fields rule:
Bloom::inserted()tests/e2e/membership.rs,tests/e2e/wire.rs,tests/pbt/bloom.rs,tests/asapv1_golden.rs, unit tests)Bloom::inserted(private)inserted(),update,merge,clear,wire.rsHow
src/sketches/bloom.rs: the field and accessor are removed, along with the counter updates inupdate(both paths),mergeandclear.src/sketches/bloom/wire.rs:BloomPayloadis{ words }. The retired two-field payload is decoded as a(Vec<u64>, u64)tuple: the words are kept and the counter is dropped. No separate payload type is needed, and tests craft retired bytes by encoding a(words, inserted)tuple.from_asapv1accepts either kind id and picks the payload type by id, so each id fixes its payload length: a0x17 0x01payload that still carries a counter, or a0x17 0x00payload without one, is rejected.src/asapv1/kind.rs:BLOOMis0x17 0x01, and the newBLOOM_WITH_INSERTEDis0x17 0x00.Key code interfaces added / modified
src/sketches/bloom.rssrc/sketches/bloom/wire.rssrc/asapv1/kind.rs(crate-private; the wire ids)Wire format (
docs/asapv1_wire_format.md)0x17 0x01[words]0x17 0x00[words, inserted]The metadata (hash spec,
rows,cols,mode) is unchanged.Usage
A collector pane asks "seen this flow before?" with a Bloom filter. It keeps its arrival count separately. This was compiled and run as an integration test at
a7d83f1:Before this PR,
seen.inserted()would have returned 5, and every envelope carried that count.Before this PR
Bloomcountedupdatecalls ininserted, exposed it throughinserted(), summed it onmerge, and carried it on the wire as0x17 0x00[words, inserted].After this PR
Bloomis the bit grid alone and encodes as0x17 0x01[words]. Older0x17 0x00bytes still decode, with the counter dropped. Every membership and rate answer is unchanged. The struct is 8 bytes smaller, and each payload is one u64 field smaller.Verification
Only the tests covering the changed code, plus format and lint. Each command was run with default features and with
--features experimental, with the same pass counts unless noted:cargo test --lib bloom: 34 passed.cargo test --lib envelope: 15 passed.cargo test --test asapv1_golden: 71 passed (default), 72 passed (experimental).cargo test --test e2e -- membership:: wire:: data_input::: 56 passed (default), 57 passed (experimental).cargo test --test pbt bloom: 11 passed.cargo test --test conformance_kit bloom: 2 passed.cargo test --test capability: 3 passed (default).cargo fmt --check: clean.cargo clippy --all-targetsand--all-targets --features experimental: no warnings.bloom_envelope_structure_and_round_tripwas changed to expect0x17 0x01and failed ([23, 0]vs[23, 1]) before the change.the_retired_kind_decodes_and_re_encodes_without_the_counter: a crafted0x17 0x00envelope decodes to its words and re-encodes as the0x17 0x01envelope of the same words.each_kind_rejects_the_other_kinds_payload:0x17 0x01with a counter, and0x17 0x00without one, are both rejected.bloom_retired_fixtures_decode_to_their_bits_twins: each retired golden fixture decodes to the known grid and re-encodes as itsbloom_bits_*twin.bloom_bits_regular_3x128_matches_golden,bloom_bits_fast_5x32_matches_golden: the new fixtures decode to the known grid and round-trip.known_state_matches_goldenencodes the known grids to them.the_insert_counter_counts_calls_and_clear_returns_it_to_zerobecameclear_returns_the_filter_to_empty, andmerging_identical_geometries_sums_the_insert_countsbecamemerging_identical_geometries_unions_the_members.pbt/e2esuites, and benchmarks. CI is not run on this draft.Limitations and follow-ups
bloom-bits-1701branch (25f8077) must merge first. Then this submodule pointer moves to the merged commit.bloom/kind-1701) registersKindBloom = 0x17 0x01and keeps0x17 0x00asKindBloomWithInserted(retired), so its fixture check accepts the new golden files.Bloom::inserted()was found, so pin bumps need no code change.🤖 Generated with Claude Code