BloomFilter.cpp 1.3 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970
  1. #include "BloomFilter.h"
  2. #include "I2PEndian.h"
  3. #include <array>
  4. #include <openssl/sha.h>
  5. namespace i2p
  6. {
  7. namespace util
  8. {
  9. /** @brief decaying bloom filter implementation */
  10. class DecayingBloomFilter : public IBloomFilter
  11. {
  12. public:
  13. DecayingBloomFilter(const std::size_t size)
  14. {
  15. m_Size = size;
  16. m_Data = new uint8_t[size];
  17. }
  18. /** @brief implements IBloomFilter::~IBloomFilter */
  19. ~DecayingBloomFilter()
  20. {
  21. delete [] m_Data;
  22. }
  23. /** @brief implements IBloomFilter::Add */
  24. bool Add(const uint8_t * data, std::size_t len)
  25. {
  26. std::size_t idx;
  27. uint8_t mask;
  28. Get(data, len, idx, mask);
  29. if(m_Data[idx] & mask) return false; // filter hit
  30. m_Data[idx] |= mask;
  31. return true;
  32. }
  33. /** @brief implements IBloomFilter::Decay */
  34. void Decay()
  35. {
  36. // reset bloom filter buffer
  37. memset(m_Data, 0, m_Size);
  38. }
  39. private:
  40. /** @brief get bit index for for data */
  41. void Get(const uint8_t * data, std::size_t len, std::size_t & idx, uint8_t & bm)
  42. {
  43. bm = 1;
  44. uint8_t digest[32];
  45. // TODO: use blake2 because it's faster
  46. SHA256(data, len, digest);
  47. uint64_t i = buf64toh(digest);
  48. idx = i % m_Size;
  49. bm <<= (i % 8);
  50. }
  51. uint8_t * m_Data;
  52. std::size_t m_Size;
  53. };
  54. BloomFilterPtr BloomFilter(std::size_t capacity)
  55. {
  56. return std::make_shared<DecayingBloomFilter>(capacity);
  57. }
  58. }
  59. }