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 @@
@@ -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 @@
@@ -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