mirror of
https://github.com/PurpleI2P/i2pd
synced 2024-11-10 08:00:38 +03:00
Merge pull request #733 from majestrate/bloom-filter
add simple bloomfilter implementation
This commit is contained in:
commit
ad5f890a1e
69
BloomFilter.cpp
Normal file
69
BloomFilter.cpp
Normal file
@ -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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
31
BloomFilter.h
Normal file
31
BloomFilter.h
Normal file
@ -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
|
@ -26,6 +26,7 @@ set ( CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake_modules" )
|
|||||||
set ( CMAKE_SOURCE_DIR ".." )
|
set ( CMAKE_SOURCE_DIR ".." )
|
||||||
|
|
||||||
set (LIBI2PD_SRC
|
set (LIBI2PD_SRC
|
||||||
|
"${CMAKE_SOURCE_DIR}/BloomFilter.cpp"
|
||||||
"${CMAKE_SOURCE_DIR}/Config.cpp"
|
"${CMAKE_SOURCE_DIR}/Config.cpp"
|
||||||
"${CMAKE_SOURCE_DIR}/Crypto.cpp"
|
"${CMAKE_SOURCE_DIR}/Crypto.cpp"
|
||||||
"${CMAKE_SOURCE_DIR}/Garlic.cpp"
|
"${CMAKE_SOURCE_DIR}/Garlic.cpp"
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
LIB_SRC = \
|
LIB_SRC = \
|
||||||
Gzip.cpp Crypto.cpp Datagram.cpp Garlic.cpp I2NPProtocol.cpp LeaseSet.cpp \
|
BloomFilter.cpp Gzip.cpp Crypto.cpp Datagram.cpp Garlic.cpp I2NPProtocol.cpp LeaseSet.cpp \
|
||||||
Log.cpp NTCPSession.cpp NetDb.cpp NetDbRequests.cpp Profiling.cpp \
|
Log.cpp NTCPSession.cpp NetDb.cpp NetDbRequests.cpp Profiling.cpp \
|
||||||
Reseed.cpp RouterContext.cpp RouterInfo.cpp Signature.cpp SSU.cpp \
|
Reseed.cpp RouterContext.cpp RouterInfo.cpp Signature.cpp SSU.cpp \
|
||||||
SSUSession.cpp SSUData.cpp Streaming.cpp Identity.cpp TransitTunnel.cpp \
|
SSUSession.cpp SSUData.cpp Streaming.cpp Identity.cpp TransitTunnel.cpp \
|
||||||
|
Loading…
Reference in New Issue
Block a user