49 #include <ndn-cxx/util/logger.hpp> 78 , maximum_size(
std::numeric_limits<unsigned int>::max())
79 , minimum_number_of_hashes(1)
80 , maximum_number_of_hashes(
std::numeric_limits<unsigned int>::max())
81 , projected_element_count(200)
82 , false_positive_probability(1.0 / projected_element_count)
83 , random_seed(0xA5A5A5A55A5A5A5AULL)
93 double min_m = std::numeric_limits<double>::infinity();
102 curr_m = numerator / denominator;
114 optp.
table_size =
static_cast<unsigned int>(min_m);
135 , projected_element_count_(0)
136 , inserted_element_count_(0)
138 , desired_false_positive_probability_(0.0)
143 , projected_element_count_(p.projected_element_count)
144 , inserted_element_count_(0)
145 , random_seed_((p.random_seed * 0xA5A5A5A5) + 1)
146 , desired_false_positive_probability_(p.false_positive_probability)
150 generate_unique_salt();
153 bit_table_.resize(static_cast<std::size_t>(raw_table_size_), 0x00);
157 double false_positive_probability)
163 double false_positive_probability,
164 const ndn::name::Component& bfName)
165 :
BloomFilter(projected_element_count, false_positive_probability)
167 std::vector<BloomFilter::cell_type>
table(bfName.value_begin(), bfName.value_end());
169 if (
table.size() != raw_table_size_) {
170 BOOST_THROW_EXCEPTION(
Error(
"Received BloomFilter cannot be decoded!"));
177 double false_positive_probability)
184 NDN_LOG_WARN(
"Bloom parameters are not correct!");
194 name.appendNumber(projected_element_count_);
195 name.appendNumber((
int)(desired_false_positive_probability_ * 1000));
196 name.append(bit_table_.begin(), bit_table_.end());
202 bit_table_.resize(static_cast<std::size_t>(raw_table_size_), 0x00);
203 inserted_element_count_ = 0;
209 std::size_t bit_index = 0;
211 for (std::size_t i = 0; i < salt_.size(); ++i)
213 compute_indices(
murmurHash3(salt_[i], key), bit_index, bit);
216 ++inserted_element_count_;
222 std::size_t bit_index = 0;
225 for (std::size_t i = 0; i < salt_.size(); ++i)
227 compute_indices(
murmurHash3(salt_[i], key), bit_index, bit);
228 if ((bit_table_[bit_index/bits_per_char] & bit_mask[bit]) != bit_mask[bit]) {
236 std::vector <BloomFilter::cell_type>
243 BloomFilter::generate_unique_salt()
251 const unsigned int predef_salt_count = 128;
252 static const bloom_type predef_salt[predef_salt_count] =
254 0xAAAAAAAA, 0x55555555, 0x33333333, 0xCCCCCCCC,
255 0x66666666, 0x99999999, 0xB5B5B5B5, 0x4B4B4B4B,
256 0xAA55AA55, 0x55335533, 0x33CC33CC, 0xCC66CC66,
257 0x66996699, 0x99B599B5, 0xB54BB54B, 0x4BAA4BAA,
258 0xAA33AA33, 0x55CC55CC, 0x33663366, 0xCC99CC99,
259 0x66B566B5, 0x994B994B, 0xB5AAB5AA, 0xAAAAAA33,
260 0x555555CC, 0x33333366, 0xCCCCCC99, 0x666666B5,
261 0x9999994B, 0xB5B5B5AA, 0xFFFFFFFF, 0xFFFF0000,
262 0xB823D5EB, 0xC1191CDF, 0xF623AEB3, 0xDB58499F,
263 0xC8D42E70, 0xB173F616, 0xA91A5967, 0xDA427D63,
264 0xB1E8A2EA, 0xF6C0D155, 0x4909FEA3, 0xA68CC6A7,
265 0xC395E782, 0xA26057EB, 0x0CD5DA28, 0x467C5492,
266 0xF15E6982, 0x61C6FAD3, 0x9615E352, 0x6E9E355A,
267 0x689B563E, 0x0C9831A8, 0x6753C18B, 0xA622689B,
268 0x8CA63C47, 0x42CC2884, 0x8E89919B, 0x6EDBD7D3,
269 0x15B6796C, 0x1D6FDFE4, 0x63FF9092, 0xE7401432,
270 0xEFFE9412, 0xAEAEDF79, 0x9F245A31, 0x83C136FC,
271 0xC3DA4A8C, 0xA5112C8C, 0x5271F491, 0x9A948DAB,
272 0xCEE59A8D, 0xB5F525AB, 0x59D13217, 0x24E7C331,
273 0x697C2103, 0x84B0A460, 0x86156DA9, 0xAEF2AC68,
274 0x23243DA5, 0x3F649643, 0x5FA495A8, 0x67710DF8,
275 0x9A6C499E, 0xDCFB0227, 0x46A43433, 0x1832B07A,
276 0xC46AFF3C, 0xB9C8FFF0, 0xC9500467, 0x34431BDF,
277 0xB652432B, 0xE367F12B, 0x427F4C1B, 0x224C006E,
278 0x2E7E5A89, 0x96F99AA5, 0x0BEB452A, 0x2FD87C39,
279 0x74B2E1FB, 0x222EFD24, 0xF357F60C, 0x440FCB1E,
280 0x8BBE030F, 0x6704DC29, 0x1144D12F, 0x948B1355,
281 0x6D8FD7E9, 0x1C11A014, 0xADD1592F, 0xFB3C712E,
282 0xFC77642F, 0xF9C4CE8C, 0x31312FB9, 0x08B0DD79,
283 0x318FA6E7, 0xC040D23D, 0xC0589AA7, 0x0CA5C075,
284 0xF874B172, 0x0CF914D5, 0x784D3280, 0x4E8CFEBC,
285 0xC569F575, 0xCDB2A091, 0x2CC016B4, 0x5C5F4421
288 if (salt_count_ <= predef_salt_count)
290 std::copy(predef_salt,
291 predef_salt + salt_count_,
292 std::back_inserter(salt_));
293 for (
unsigned int i = 0; i < salt_.size(); ++i)
295 salt_[i] = salt_[i] * salt_[(i + 3) % salt_.size()] +
static_cast<bloom_type>(random_seed_);
300 std::copy(predef_salt,predef_salt + predef_salt_count,std::back_inserter(salt_));
301 srand(static_cast<unsigned int>(random_seed_));
302 while (salt_.size() < salt_count_)
305 if (0 == current_salt)
continue;
306 if (salt_.end() == std::find(salt_.begin(), salt_.end(), current_salt))
308 salt_.push_back(current_salt);
315 BloomFilter::compute_indices(
const bloom_type& hash,
316 std::size_t& bit_index, std::size_t& bit)
const 318 bit_index = hash % table_size_;
325 auto table1 = bf1.
table();
326 auto table2 = bf2.
table();
328 if (table1.size() != table2.size()) {
332 for (
size_t i = 0; i < table1.size(); i++) {
333 if (table1[i] != table2[i]) {
343 for (
const auto& element : bf.
table()) {
344 out << unsigned(element);
void appendToName(ndn::Name &name) const
Append our bloom filter to the given name.
static const unsigned char bit_mask[bits_per_char]
unsigned int minimum_size
bool contains(const std::string &key) const
uint32_t murmurHash3(uint32_t nHashSeed, const std::vector< unsigned char > &vDataToHash)
unsigned int minimum_number_of_hashes
bool operator==(const BloomFilter &bf1, const BloomFilter &bf2)
unsigned int projected_element_count
static const std::size_t bits_per_char
unsigned int maximum_number_of_hashes
bool compute_optimal_parameters()
unsigned int number_of_hashes
void insert(const std::string &key)
std::ostream & operator<<(std::ostream &out, const BloomFilter &bf)
unsigned int maximum_size
double false_positive_probability
std::vector< cell_type > table() const
BloomParameters getParameters(unsigned int projected_element_count, double false_positive_probability)
optimal_parameters_t optimal_parameters