|
|
@ -31,6 +31,10 @@ |
|
|
|
namespace dev |
|
|
|
{ |
|
|
|
|
|
|
|
/// Compile-time calculation of Log2 of constant values.
|
|
|
|
template <unsigned N> struct StaticLog2 { enum { result = 1 + StaticLog2<N/2>::result }; }; |
|
|
|
template <> struct StaticLog2<1> { enum { result = 0 }; }; |
|
|
|
|
|
|
|
extern std::random_device s_fixedHashEngine; |
|
|
|
|
|
|
|
/// Fixed-size raw-byte array container type, with an API optimised for storing hashes.
|
|
|
@ -171,18 +175,21 @@ public: |
|
|
|
|
|
|
|
template <unsigned P, unsigned M> inline FixedHash<M> bloomPart() const |
|
|
|
{ |
|
|
|
static_assert((M & (M - 1)) == 0, "M must be power-of-two"); |
|
|
|
static const unsigned c_bloomBits = M * 8; |
|
|
|
unsigned mask = c_bloomBits - 1; |
|
|
|
unsigned bloomBytes = (dev::toLog2(c_bloomBits) + 7) / 8; |
|
|
|
unsigned const c_bloomBits = M * 8; |
|
|
|
unsigned const c_mask = c_bloomBits - 1; |
|
|
|
unsigned const c_bloomBytes = (StaticLog2<c_bloomBits>::result + 7) / 8; |
|
|
|
|
|
|
|
static_assert((M & (M - 1)) == 0, "M must be power-of-two"); |
|
|
|
static_assert(P * c_bloomBytes <= N, "out of range"); |
|
|
|
|
|
|
|
FixedHash<M> ret; |
|
|
|
byte const* p = data(); |
|
|
|
for (unsigned i = 0; i < P; ++i) |
|
|
|
{ |
|
|
|
unsigned index = 0; |
|
|
|
for (unsigned j = 0; j < bloomBytes; ++j, ++p) |
|
|
|
for (unsigned j = 0; j < c_bloomBytes; ++j, ++p) |
|
|
|
index = (index << 8) | *p; |
|
|
|
index &= mask; |
|
|
|
index &= c_mask; |
|
|
|
ret[M - 1 - index / 8] |= (1 << (index % 8)); |
|
|
|
} |
|
|
|
return ret; |
|
|
|