Inside Bitcoin
Opening the selected file…
Inside Bitcoin
Opening the selected file…
The code behind the network, with room to understand it.
Release published 2026-10-28 · Snapshot fetched 2026-11-01. Latest stable release at fetch time; development branches and Git history are excluded. Only the selected code window and visible folders load here.
1// Copyright (c) 2012 The LevelDB Authors. All rights reserved.2// Use of this source code is governed by a BSD-style license that can be3// found in the LICENSE file. See the AUTHORS file for names of contributors.5#include "leveldb/filter_policy.h"7#include "util/coding.h"8#include "util/logging.h"9#include "util/testharness.h"10#include "util/testutil.h"12namespace leveldb {14static const int kVerbose = 1;16static Slice Key(int i, char* buffer) {17EncodeFixed32(buffer, i);18return Slice(buffer, sizeof(uint32_t));19}21class BloomTest {22public:23BloomTest() : policy_(NewBloomFilterPolicy(10)) {}25~BloomTest() { delete policy_; }27void Reset() {28keys_.clear();29filter_.clear();30}32void Add(const Slice& s) { keys_.push_back(s.ToString()); }34void Build() {35std::vector<Slice> key_slices;36for (size_t i = 0; i < keys_.size(); i++) {37key_slices.push_back(Slice(keys_[i]));38}39filter_.clear();40policy_->CreateFilter(&key_slices[0], static_cast<int>(key_slices.size()),41&filter_);42keys_.clear();43if (kVerbose >= 2) DumpFilter();44}46size_t FilterSize() const { return filter_.size(); }48void DumpFilter() {49fprintf(stderr, "F(");50for (size_t i = 0; i + 1 < filter_.size(); i++) {51const unsigned int c = static_cast<unsigned int>(filter_[i]);52for (int j = 0; j < 8; j++) {53fprintf(stderr, "%c", (c & (1 << j)) ? '1' : '.');54}55}56fprintf(stderr, ")\n");57}59bool Matches(const Slice& s) {60if (!keys_.empty()) {61Build();62}63return policy_->KeyMayMatch(s, filter_);64}66double FalsePositiveRate() {67char buffer[sizeof(int)];68int result = 0;69for (int i = 0; i < 10000; i++) {70if (Matches(Key(i + 1000000000, buffer))) {71result++;72}73}74return result / 10000.0;75}77private:78const FilterPolicy* policy_;79std::string filter_;80std::vector<std::string> keys_;81};83TEST(BloomTest, EmptyFilter) {84ASSERT_TRUE(!Matches("hello"));85ASSERT_TRUE(!Matches("world"));86}88TEST(BloomTest, Small) {89Add("hello");90Add("world");91ASSERT_TRUE(Matches("hello"));92ASSERT_TRUE(Matches("world"));93ASSERT_TRUE(!Matches("x"));94ASSERT_TRUE(!Matches("foo"));95}97static int NextLength(int length) {98if (length < 10) {99length += 1;100} else if (length < 100) {101length += 10;102} else if (length < 1000) {103length += 100;104} else {105length += 1000;106}107return length;108}110TEST(BloomTest, VaryingLengths) {111char buffer[sizeof(int)];113// Count number of filters that significantly exceed the false positive rate114int mediocre_filters = 0;115int good_filters = 0;117for (int length = 1; length <= 10000; length = NextLength(length)) {118Reset();119for (int i = 0; i < length; i++) {120Add(Key(i, buffer));121}122Build();124ASSERT_LE(FilterSize(), static_cast<size_t>((length * 10 / 8) + 40))125<< length;127// All added keys must match128for (int i = 0; i < length; i++) {129ASSERT_TRUE(Matches(Key(i, buffer)))130<< "Length " << length << "; key " << i;131}133// Check false positive rate134double rate = FalsePositiveRate();135if (kVerbose >= 1) {136fprintf(stderr, "False positives: %5.2f%% @ length = %6d ; bytes = %6d\n",137rate * 100.0, length, static_cast<int>(FilterSize()));138}139ASSERT_LE(rate, 0.02); // Must not be over 2%140if (rate > 0.0125)141mediocre_filters++; // Allowed, but not too often142else143good_filters++;144}145if (kVerbose >= 1) {146fprintf(stderr, "Filters: %d good, %d mediocre\n", good_filters,147mediocre_filters);148}149ASSERT_LE(mediocre_filters, good_filters / 5);150}152// Different bits-per-byte154} // namespace leveldb156int main(int argc, char** argv) { return leveldb::test::RunAllTests(); }
Independent explanations by MyBitcoinExplorer. Not affiliated with or endorsed by Bitcoin Core. Guides are educational and do not replace the source or its tests.
Bitcoin Core source © its contributors, distributed under the MIT license. Original notices and bundled third-party licenses are retained in the source tree.