-
Notifications
You must be signed in to change notification settings - Fork 0
feat: bloom filter integration for distributed joins #25
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from all commits
Commits
Show all changes
19 commits
Select commit
Hold shift + click to select a range
acf8695
feat: add BloomFilter class with MurmurHash3 implementation
poyrazK 576e446
feat: add BloomFilterPush RPC and ClusterManager storage
poyrazK d9a1bd8
feat: integrate bloom filter in shuffle join pipeline
poyrazK a24c986
test: add bloom filter tests and update documentation
poyrazK 5154dde
style: automated clang-format fixes
poyrazK 2481607
fix: bloom filter core implementation
poyrazK b0da5b6
fix: distributed executor, main.cpp, tests and docs
poyrazK bfd846c
style: automated clang-format fixes
poyrazK 7904cae
fix: address review feedback - bloom filter validation, hoisting, docs
poyrazK 0e2b3f6
style: automated clang-format fixes
poyrazK 3edd0c4
fix: use std::optional to avoid default-constructible BloomFilter req…
poyrazK 810e531
style: automated clang-format fixes
poyrazK 7dbff02
fix: use schema.find_column instead of redundant catalog lookup
poyrazK 52fc398
chore: retrigger CI
poyrazK 6f87a50
fix: add BloomFilterPush handler to ShuffleJoinOrchestration test
poyrazK cd533be
ci: trigger rebuild
poyrazK 4ebc007
ci: retry test
poyrazK e3ec112
ci: final retry
poyrazK 0991945
fix: skip bloom filtering when filter_data is empty
poyrazK File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
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
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
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -39,8 +39,48 @@ We addressed the gaps via the following optimizations: | |
| 2. **Pinned Page Iteration**: Modifying our `HeapTable::Iterator` to hold pages pinned across slot iteration avoids repetitive atomic checks and LRU updates per-row. | ||
| 3. **Batch Insert Mode**: Skipping single-row undo logs and exclusive locks to exploit pure in-memory bump allocation. This drove the `INSERT` speedup well past SQLite limits, as we write raw tuples uninterrupted. | ||
|
|
||
| ## 6. Future Roadmap | ||
| ## 6. Distributed Join Optimization: Bloom Filters | ||
|
|
||
| ### Problem | ||
| Distributed shuffle joins send **all tuples** across the network to partitioned nodes, even when many will never match. This causes unnecessary network traffic and buffer memory usage. | ||
|
|
||
| ### Solution: Bloom Filter Integration | ||
| Implemented bloom filters to filter tuples at the source before network transmission: | ||
| - **One-sided bloom filter**: Built from the left/build table, applied to filter the right/probe table | ||
| - **Distributed construction**: Each data node constructs its local bloom during the left/build scan phase | ||
| - **Coordinator coordination**: `BloomFilterPush` RPC broadcasts filter metadata to all nodes before the right/probe shuffle | ||
|
|
||
| ### Architecture | ||
| ``` | ||
| [Phase 1: Shuffle Left] [Phase 2: Shuffle Right] | ||
| | | | ||
| v v | ||
| Build local bloom Apply bloom filter | ||
| from join keys before buffering | ||
| | | | ||
| +---- BloomFilterPush ----->---+ | ||
| (filter metadata) | | ||
| v | ||
| Filtered tuples buffered | ||
| ``` | ||
|
|
||
| ### Key Components | ||
| | Component | Location | Purpose | | ||
| |-----------|----------|---------| | ||
| | `BloomFilter` class | `include/common/bloom_filter.hpp` | MurmurHash3-based bloom filter | | ||
| | `BloomFilterArgs` RPC | `include/network/rpc_message.hpp` | Serialization for network transfer | | ||
| | `ClusterManager` storage | `include/common/cluster_manager.hpp` | Stores bloom filter per context | | ||
| | `PushData` handler | `src/main.cpp` | Receives and buffers filtered tuples | | ||
| | `ShuffleFragment` handler | `src/main.cpp` | Applies bloom filter before sending | | ||
| | Coordinator | `src/distributed/distributed_executor.cpp` | Broadcasts filter after Phase 1 | | ||
|
coderabbitai[bot] marked this conversation as resolved.
|
||
|
|
||
|
Comment on lines
+67
to
+76
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Surround the table with blank lines to satisfy markdownlint. Add a blank line before/after the table block (MD058). Suggested patch ### Key Components
+
| Component | Location | Purpose |
|-----------|----------|---------|
| `BloomFilter` class | `include/common/bloom_filter.hpp` | MurmurHash3-based bloom filter |
| `BloomFilterArgs` RPC | `include/network/rpc_message.hpp` | Serialization for network transfer |
| `ClusterManager` storage | `include/common/cluster_manager.hpp` | Stores bloom filter per context |
| `PushData` handler | `src/main.cpp` | Receives and buffers filtered tuples |
| `ShuffleFragment` handler | `src/main.cpp` | Applies bloom filter before sending |
| Coordinator | `src/distributed/distributed_executor.cpp` | Broadcasts filter after Phase 1 |
+
### Test Coverage🧰 Tools🪛 markdownlint-cli2 (0.22.0)[warning] 68-68: Tables should be surrounded by blank lines (MD058, blanks-around-tables) 🤖 Prompt for AI Agents |
||
| ### Test Coverage | ||
| - 10 unit tests covering: BloomFilter class, BloomFilterArgs serialization, ClusterManager storage, filter application logic | ||
| - Tests located in `tests/bloom_filter_test.cpp` | ||
|
|
||
| ## 7. Future Roadmap | ||
| With the scan gap closed, our focus shifts to higher-level analytical throughput: | ||
| * **Stage 1: SIMD-Accelerated Filtering**: Utilize AVX-512/NEON instructions to filter multiple rows in a single CPU cycle. | ||
| * **Stage 2: Vectorized Execution**: Move from row-at-a-time `TupleView` to batch-at-a-time `VectorBatch` processing. | ||
| * **Stage 3: Columnar Storage**: Transition from row-oriented heap files to columnar persistence for extreme analytical scanning. | ||
| * **Stage 4: Distributed Hash Join**: Enhance the single `HashJoinOperator` with parallel partitioned hash join for multi-node execution. | ||
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
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
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
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,83 @@ | ||
| /** | ||
| * @file bloom_filter.hpp | ||
| * @brief Bloom filter implementation for distributed join optimization | ||
| */ | ||
|
|
||
| #ifndef SQL_ENGINE_COMMON_BLOOM_FILTER_HPP | ||
| #define SQL_ENGINE_COMMON_BLOOM_FILTER_HPP | ||
|
|
||
| #include <cstdint> | ||
| #include <cstring> | ||
| #include <vector> | ||
|
|
||
| #include "value.hpp" | ||
|
|
||
| namespace cloudsql { | ||
| namespace common { | ||
|
|
||
| /** | ||
| * @brief Bloom filter for probabilistic membership testing | ||
| * | ||
| * Used in distributed joins to filter tuples that cannot possibly | ||
| * match before network transmission. | ||
| */ | ||
| class BloomFilter { | ||
| public: | ||
| /** | ||
| * @brief Construct a bloom filter with expected elements and false positive rate | ||
| * @param expected_elements Number of elements expected to be inserted | ||
| * @param false_positive_rate Target false positive rate (default 0.01 = 1%) | ||
| */ | ||
| explicit BloomFilter(size_t expected_elements, double false_positive_rate = 0.01); | ||
|
|
||
| /** | ||
| * @brief Construct from serialized data | ||
| */ | ||
| BloomFilter(const uint8_t* data, size_t size); | ||
|
|
||
| /** | ||
| * @brief Insert a value into the bloom filter | ||
| */ | ||
| void insert(const Value& key); | ||
|
|
||
| /** | ||
| * @brief Check if a value might be in the bloom filter | ||
| * @return true if possibly present, false if definitely not present | ||
| */ | ||
| [[nodiscard]] bool might_contain(const Value& key) const; | ||
|
|
||
| /** | ||
| * @brief Serialize the bloom filter for network transmission | ||
| */ | ||
| [[nodiscard]] std::vector<uint8_t> serialize() const; | ||
|
|
||
| /** | ||
| * @brief Get the bit array size in bytes | ||
| */ | ||
| [[nodiscard]] size_t bit_size() const { return (num_bits_ + 7) / 8; } | ||
|
|
||
| /** | ||
| * @brief Get number of hash functions used | ||
| */ | ||
| [[nodiscard]] size_t num_hashes() const { return num_hashes_; } | ||
|
|
||
| /** | ||
| * @brief Get expected elements | ||
| */ | ||
| [[nodiscard]] size_t expected_elements() const { return expected_elements_; } | ||
|
|
||
| private: | ||
| size_t num_bits_; | ||
| size_t num_hashes_; | ||
| size_t expected_elements_; | ||
| std::vector<uint8_t> bits_; | ||
|
|
||
| size_t get_bit_position(size_t hash, size_t i) const; | ||
| size_t murmur3_hash(const Value& key) const; | ||
| size_t murmur3_hash(const uint8_t* data, size_t len, size_t seed) const; | ||
| }; | ||
|
|
||
| } // namespace common | ||
| } // namespace cloudsql | ||
|
|
||
| #endif // SQL_ENGINE_COMMON_BLOOM_FILTER_HPP |
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
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
Oops, something went wrong.
Oops, something went wrong.
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.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Add a language tag to the fenced diagram block.
The code fence is missing a language identifier, which triggers MD040.
Suggested patch
Verify each finding against the current code and only fix it if needed.
In
@docs/performance/SQLITE_COMPARISON.mdaround lines 54 - 65, The fenceddiagram block lacks a language tag (MD040); update the code fence around the
ASCII diagram (the triple-backtick block containing "[Phase 1: Shuffle Left]
[Phase 2: Shuffle Right]" and the diagram lines) to include a language
identifier such as text (e.g., ```text) so the linter recognizes the block
correctly.