5 #include "bloom_filter_math.h"
7 namespace cachemere::policy::detail {
9 template<
typename ItemHash>
11 : m_cardinality{cardinality},
12 m_filter(optimal_filter_size(cardinality), 0),
13 m_nb_hashes{optimal_nb_of_hash_functions(cardinality, m_filter.size())}
21 std::vector<size_t> indices;
22 indices.reserve(m_nb_hashes);
24 uint32_t minimum_val = std::numeric_limits<uint32_t>::max();
27 for (
size_t i = 0; i < m_nb_hashes; ++i) {
28 const size_t idx = mixer();
29 assert(idx < m_filter.size());
31 indices.push_back(idx);
32 minimum_val = std::min(m_filter[idx], minimum_val);
36 const uint8_t is_zero_increment = minimum_val == 0 ? 1 : 0;
37 for (
const size_t idx : indices) {
38 if (m_filter[idx] == minimum_val) {
43 m_nb_nonzero += is_zero_increment;
50 std::fill(m_filter.begin(), m_filter.end(), 0);
56 for (
auto& counter : m_filter) {
66 assert(m_nb_hashes > 0);
70 uint32_t minimum_val = std::numeric_limits<uint32_t>::max();
71 for (
size_t i = 0; i < m_nb_hashes; ++i) {
72 const size_t idx = mixer();
73 assert(idx < m_filter.size());
75 minimum_val = std::min(m_filter[idx], minimum_val);
93 return m_filter.size() *
sizeof(uint32_t) +
sizeof(m_cardinality) +
sizeof(m_nb_hashes) +
sizeof(m_nb_nonzero);
98 assert(m_filter.size() > 0);
99 return static_cast<double>(m_nb_nonzero) /
static_cast<double>(m_filter.size());