mirror of https://github.com/PurpleI2P/i2pd.git
Jeff Becker
8 years ago
4 changed files with 102 additions and 1 deletions
@ -0,0 +1,69 @@ |
|||||||
|
#include "BloomFilter.h" |
||||||
|
#include "I2PEndian.h" |
||||||
|
#include <array> |
||||||
|
#include <openssl/sha.h> |
||||||
|
|
||||||
|
namespace i2p |
||||||
|
{ |
||||||
|
namespace util |
||||||
|
{ |
||||||
|
|
||||||
|
/** @brief decaying bloom filter implementation */ |
||||||
|
class DecayingBloomFilter : public IBloomFilter |
||||||
|
{ |
||||||
|
public: |
||||||
|
|
||||||
|
DecayingBloomFilter(const std::size_t size) |
||||||
|
{ |
||||||
|
m_Size = size; |
||||||
|
m_Data = new uint8_t[size]; |
||||||
|
} |
||||||
|
|
||||||
|
/** @brief implements IBloomFilter::~IBloomFilter */ |
||||||
|
~DecayingBloomFilter() |
||||||
|
{ |
||||||
|
delete [] m_Data; |
||||||
|
} |
||||||
|
|
||||||
|
/** @brief implements IBloomFilter::Add */ |
||||||
|
bool Add(const uint8_t * data, std::size_t len) |
||||||
|
{ |
||||||
|
std::size_t idx; |
||||||
|
uint8_t mask; |
||||||
|
Get(data, len, idx, mask); |
||||||
|
if(m_Data[idx] & mask) return false; // filter hit
|
||||||
|
m_Data[idx] |= mask; |
||||||
|
return true; |
||||||
|
} |
||||||
|
|
||||||
|
/** @brief implements IBloomFilter::Decay */ |
||||||
|
void Decay() |
||||||
|
{ |
||||||
|
// reset bloom filter buffer
|
||||||
|
memset(m_Data, 0, m_Size); |
||||||
|
} |
||||||
|
|
||||||
|
private: |
||||||
|
/** @brief get bit index for for data */ |
||||||
|
void Get(const uint8_t * data, std::size_t len, std::size_t & idx, uint8_t & bm) |
||||||
|
{ |
||||||
|
bm = 1; |
||||||
|
uint8_t digest[32]; |
||||||
|
// TODO: use blake2 because it's faster
|
||||||
|
SHA256(data, len, digest); |
||||||
|
uint64_t i = buf64toh(digest); |
||||||
|
idx = i % m_Size; |
||||||
|
bm <<= (i % 8); |
||||||
|
} |
||||||
|
|
||||||
|
uint8_t * m_Data; |
||||||
|
std::size_t m_Size; |
||||||
|
}; |
||||||
|
|
||||||
|
|
||||||
|
BloomFilterPtr BloomFilter(std::size_t capacity) |
||||||
|
{ |
||||||
|
return std::make_shared<DecayingBloomFilter>(capacity); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,31 @@ |
|||||||
|
#ifndef BLOOM_FILTER_H_ |
||||||
|
#define BLOOM_FILTER_H_ |
||||||
|
#include <memory> |
||||||
|
#include <cstdint> |
||||||
|
|
||||||
|
namespace i2p |
||||||
|
{ |
||||||
|
namespace util |
||||||
|
{ |
||||||
|
|
||||||
|
/** @brief interface for bloom filter */ |
||||||
|
struct IBloomFilter |
||||||
|
{ |
||||||
|
|
||||||
|
/** @brief destructor */ |
||||||
|
virtual ~IBloomFilter(); |
||||||
|
/** @brief add entry to bloom filter, return false if filter hit otherwise return true */ |
||||||
|
virtual bool Add(const uint8_t * data, std::size_t len) = 0; |
||||||
|
/** @brief optionally decay old entries */ |
||||||
|
virtual void Decay(); |
||||||
|
}; |
||||||
|
|
||||||
|
typedef std::shared_ptr<IBloomFilter> BloomFilterPtr; |
||||||
|
|
||||||
|
/** @brief create bloom filter */ |
||||||
|
BloomFilterPtr BloomFilter(std::size_t capacity = 1024 * 8); |
||||||
|
|
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
#endif |
Loading…
Reference in new issue