Coverage Report

Created: 2025-06-10 13:21

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/bitcoin/src/leveldb/util/bloom.cc
Line
Count
Source
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 be
3
// found in the LICENSE file. See the AUTHORS file for names of contributors.
4
5
#include "leveldb/filter_policy.h"
6
7
#include "leveldb/slice.h"
8
#include "util/hash.h"
9
10
namespace leveldb {
11
12
namespace {
13
11.7k
static uint32_t BloomHash(const Slice& key) {
14
11.7k
  return Hash(key.data(), key.size(), 0xbc9f1d34);
15
11.7k
}
16
17
class BloomFilterPolicy : public FilterPolicy {
18
 public:
19
33.2k
  explicit BloomFilterPolicy(int bits_per_key) : bits_per_key_(bits_per_key) {
20
    // We intentionally round down to reduce probing cost a little bit
21
33.2k
    k_ = static_cast<size_t>(bits_per_key * 0.69);  // 0.69 =~ ln(2)
22
33.2k
    if (k_ < 1) k_ = 1;
  Branch (22:9): [True: 0, False: 33.2k]
23
33.2k
    if (k_ > 30) k_ = 30;
  Branch (23:9): [True: 0, False: 33.2k]
24
33.2k
  }
25
26
48
  const char* Name() const override { return "leveldb.BuiltinBloomFilter2"; }
27
28
625
  void CreateFilter(const Slice* keys, int n, std::string* dst) const override {
29
    // Compute bloom filter size (in both bits and bytes)
30
625
    size_t bits = n * bits_per_key_;
31
32
    // For small n, we can see a very high false positive rate.  Fix it
33
    // by enforcing a minimum bloom filter length.
34
625
    if (bits < 64) bits = 64;
  Branch (34:9): [True: 1, False: 624]
35
36
625
    size_t bytes = (bits + 7) / 8;
37
625
    bits = bytes * 8;
38
39
625
    const size_t init_size = dst->size();
40
625
    dst->resize(init_size + bytes, 0);
41
625
    dst->push_back(static_cast<char>(k_));  // Remember # of probes in filter
42
625
    char* array = &(*dst)[init_size];
43
12.3k
    for (int i = 0; i < n; i++) {
  Branch (43:21): [True: 11.7k, False: 625]
44
      // Use double-hashing to generate a sequence of hash values.
45
      // See analysis in [Kirsch,Mitzenmacher 2006].
46
11.7k
      uint32_t h = BloomHash(keys[i]);
47
11.7k
      const uint32_t delta = (h >> 17) | (h << 15);  // Rotate right 17 bits
48
82.1k
      for (size_t j = 0; j < k_; j++) {
  Branch (48:26): [True: 70.4k, False: 11.7k]
49
70.4k
        const uint32_t bitpos = h % bits;
50
70.4k
        array[bitpos / 8] |= (1 << (bitpos % 8));
51
70.4k
        h += delta;
52
70.4k
      }
53
11.7k
    }
54
625
  }
55
56
5
  bool KeyMayMatch(const Slice& key, const Slice& bloom_filter) const override {
57
5
    const size_t len = bloom_filter.size();
58
5
    if (len < 2) return false;
  Branch (58:9): [True: 0, False: 5]
59
60
5
    const char* array = bloom_filter.data();
61
5
    const size_t bits = (len - 1) * 8;
62
63
    // Use the encoded k so that we can read filters generated by
64
    // bloom filters created using different parameters.
65
5
    const size_t k = array[len - 1];
66
5
    if (k > 30) {
  Branch (66:9): [True: 0, False: 5]
67
      // Reserved for potentially new encodings for short bloom filters.
68
      // Consider it a match.
69
0
      return true;
70
0
    }
71
72
5
    uint32_t h = BloomHash(key);
73
5
    const uint32_t delta = (h >> 17) | (h << 15);  // Rotate right 17 bits
74
35
    for (size_t j = 0; j < k; j++) {
  Branch (74:24): [True: 30, False: 5]
75
30
      const uint32_t bitpos = h % bits;
76
30
      if ((array[bitpos / 8] & (1 << (bitpos % 8))) == 0) return false;
  Branch (76:11): [True: 0, False: 30]
77
30
      h += delta;
78
30
    }
79
5
    return true;
80
5
  }
81
82
 private:
83
  size_t bits_per_key_;
84
  size_t k_;
85
};
86
}  // namespace
87
88
33.2k
const FilterPolicy* NewBloomFilterPolicy(int bits_per_key) {
89
33.2k
  return new BloomFilterPolicy(bits_per_key);
90
33.2k
}
91
92
}  // namespace leveldb