Performance Feature: Unlock concurrent read scaling with mutable-segment Bloom filtering#163
Merged
Merged
Conversation
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.
Summary
This PR unlocks concurrent read scaling by adding a production-ready Bloom filter to mutable and frozen in-memory segments.
Negative lookups can now bypass the B+tree entirely instead of entering its synchronized read path. This matters across the whole LSM read pipeline: lookups commonly probe several segments before finding a key, and most of those probes are misses.
The result is dramatically better parallel read and query scaling while preserving strong single-thread performance.
What Changed
MutableSegmentBloomFilterBitsPerItem.80–640disables the filterIKeyHasher<TKey>for comparer-compatible hashing.Memory<byte>.Memory<byte>keys.Concurrency Design
The filter uses three probes contained within one 64-bit word:
Interlocked.Or.Volatile.Read.The allocation is rounded to a power of two, keeping lookup indexing inexpensive. With the default one-million-item mutable segment and eight bits per item, the filter occupies approximately 1 MiB.
Performance
On the current 1M-profile Windows reference workload:
The complete P16 workload finished its measured phases in 10.6 seconds, compared with 56.8 seconds at P1.
These numbers demonstrate the branch’s parallel scaling rather than a controlled before/after comparison.
Compatibility
Known key types receive an appropriate hasher automatically.
Custom key types must provide an
IKeyHasher<TKey>. Keys considered equal by the configured comparer must always produce the same hash code. Custom hashers must also be deterministic and safe for concurrent use.The Bloom filter can be disabled when required:
Verification
Memory<byte>content-equivalence coverage