From 447494138078ab1b67c4080daa45769924d5117c Mon Sep 17 00:00:00 2001 From: Vlad Gluhovsky Date: Thu, 18 Jun 2015 15:29:05 +0200 Subject: [PATCH 1/4] BloomFilter refactoring: template class --- libwhisper/BloomFilter.cpp | 12 ++++--- libwhisper/BloomFilter.h | 65 +++++++++++++++++++++++++++++++------- 2 files changed, 62 insertions(+), 15 deletions(-) diff --git a/libwhisper/BloomFilter.cpp b/libwhisper/BloomFilter.cpp index cff69c664..9680ded66 100644 --- a/libwhisper/BloomFilter.cpp +++ b/libwhisper/BloomFilter.cpp @@ -25,9 +25,11 @@ using namespace std; using namespace dev; using namespace dev::shh; +/* static unsigned const c_mask[] = { 1, 2, 4, 8, 16, 32, 64, 128 }; -void TopicBloomFilter::addRaw(AbridgedTopic const& _h) +template +void TopicBloomFilterBase::addRaw(FixedHash const& _h) { *this |= _h; for (unsigned i = 0; i < CounterSize; ++i) @@ -40,7 +42,8 @@ void TopicBloomFilter::addRaw(AbridgedTopic const& _h) } } -void TopicBloomFilter::removeRaw(AbridgedTopic const& _h) +template +void TopicBloomFilterBase::removeRaw(FixedHash const& _h) { for (unsigned i = 0; i < CounterSize; ++i) if (isBitSet(_h, i)) @@ -53,12 +56,13 @@ void TopicBloomFilter::removeRaw(AbridgedTopic const& _h) } } -bool TopicBloomFilter::isBitSet(AbridgedTopic const& _h, unsigned _index) +template +bool TopicBloomFilterBase::isBitSet(FixedHash const& _h, unsigned _index) { unsigned iByte = _index / 8; unsigned iBit = _index % 8; return (_h[iByte] & c_mask[iBit]) != 0; } - +*/ diff --git a/libwhisper/BloomFilter.h b/libwhisper/BloomFilter.h index 0ca460805..cc236c255 100644 --- a/libwhisper/BloomFilter.h +++ b/libwhisper/BloomFilter.h @@ -28,30 +28,73 @@ namespace dev namespace shh { -class TopicBloomFilter: public AbridgedTopic +//enum { BloomSize = 4 }; + +template +class TopicBloomFilterBase: public FixedHash { public: - TopicBloomFilter() { init(); } - TopicBloomFilter(AbridgedTopic const& _h): AbridgedTopic(_h) { init(); } + TopicBloomFilterBase() { init(); } + TopicBloomFilterBase(FixedHash const& _h): FixedHash(_h) { init(); } - void addBloom(AbridgedTopic const& _h) { addRaw(_h.template bloomPart()); } - void removeBloom(AbridgedTopic const& _h) { removeRaw(_h.template bloomPart()); } - bool containsBloom(AbridgedTopic const& _h) const { return contains(_h.template bloomPart()); } + void addBloom(AbridgedTopic const& _h) { addRaw(_h.template bloomPart()); } + void removeBloom(AbridgedTopic const& _h) { removeRaw(_h.template bloomPart()); } + bool containsBloom(AbridgedTopic const& _h) const { return contains(_h.template bloomPart()); } - void addRaw(AbridgedTopic const& _h); - void removeRaw(AbridgedTopic const& _h); - bool containsRaw(AbridgedTopic const& _h) const { return contains(_h); } + void addRaw(FixedHash const& _h); + void removeRaw(FixedHash const& _h); + bool containsRaw(FixedHash const& _h) const { return contains(_h); } enum { BitsPerBloom = 3 }; private: void init() { for (unsigned i = 0; i < CounterSize; ++i) m_refCounter[i] = 0; } - static bool isBitSet(AbridgedTopic const& _h, unsigned _index); + static bool isBitSet(FixedHash const& _h, unsigned _index); - enum { CounterSize = 8 * TopicBloomFilter::size }; + enum { CounterSize = 8 * TopicBloomFilterBase::size }; std::array m_refCounter; }; +static unsigned const c_mask[8] = { 1, 2, 4, 8, 16, 32, 64, 128 }; + +template +void TopicBloomFilterBase::addRaw(FixedHash const& _h) +{ + *this |= _h; + for (unsigned i = 0; i < CounterSize; ++i) + if (isBitSet(_h, i)) + { + if (m_refCounter[i] != numeric_limits::max()) + m_refCounter[i]++; + else + BOOST_THROW_EXCEPTION(Overflow()); + } +} + +template +void TopicBloomFilterBase::removeRaw(FixedHash const& _h) +{ + for (unsigned i = 0; i < CounterSize; ++i) + if (isBitSet(_h, i)) + { + if (m_refCounter[i]) + m_refCounter[i]--; + + if (!m_refCounter[i]) + (*this)[i / 8] &= ~c_mask[i % 8]; + } +} + +template +bool TopicBloomFilterBase::isBitSet(FixedHash const& _h, unsigned _index) +{ + unsigned iByte = _index / 8; + unsigned iBit = _index % 8; + return (_h[iByte] & c_mask[iBit]) != 0; +} + +using TopicBloomFilter = TopicBloomFilterBase<4>; + } } From 7e7f4d07da299cb64d892db6dd1f40ddc43f5d01 Mon Sep 17 00:00:00 2001 From: Vlad Gluhovsky Date: Fri, 19 Jun 2015 15:44:56 +0200 Subject: [PATCH 2/4] made TopicBloomFilter a template --- libwhisper/BloomFilter.cpp | 40 --------------------------------- libwhisper/BloomFilter.h | 16 ++++++------- libwhisper/Common.cpp | 4 ++-- libwhisper/Common.h | 4 +++- test/libwhisper/bloomFilter.cpp | 24 +++++++++++--------- 5 files changed, 26 insertions(+), 62 deletions(-) diff --git a/libwhisper/BloomFilter.cpp b/libwhisper/BloomFilter.cpp index 9680ded66..554274011 100644 --- a/libwhisper/BloomFilter.cpp +++ b/libwhisper/BloomFilter.cpp @@ -25,44 +25,4 @@ using namespace std; using namespace dev; using namespace dev::shh; -/* -static unsigned const c_mask[] = { 1, 2, 4, 8, 16, 32, 64, 128 }; - -template -void TopicBloomFilterBase::addRaw(FixedHash const& _h) -{ - *this |= _h; - for (unsigned i = 0; i < CounterSize; ++i) - if (isBitSet(_h, i)) - { - if (m_refCounter[i] != numeric_limits::max()) - m_refCounter[i]++; - else - BOOST_THROW_EXCEPTION(Overflow()); - } -} - -template -void TopicBloomFilterBase::removeRaw(FixedHash const& _h) -{ - for (unsigned i = 0; i < CounterSize; ++i) - if (isBitSet(_h, i)) - { - if (m_refCounter[i]) - m_refCounter[i]--; - - if (!m_refCounter[i]) - (*this)[i / 8] &= ~c_mask[i % 8]; - } -} - -template -bool TopicBloomFilterBase::isBitSet(FixedHash const& _h, unsigned _index) -{ - unsigned iByte = _index / 8; - unsigned iBit = _index % 8; - return (_h[iByte] & c_mask[iBit]) != 0; -} - -*/ diff --git a/libwhisper/BloomFilter.h b/libwhisper/BloomFilter.h index cc236c255..393ccbfd1 100644 --- a/libwhisper/BloomFilter.h +++ b/libwhisper/BloomFilter.h @@ -28,8 +28,6 @@ namespace dev namespace shh { -//enum { BloomSize = 4 }; - template class TopicBloomFilterBase: public FixedHash { @@ -37,9 +35,9 @@ public: TopicBloomFilterBase() { init(); } TopicBloomFilterBase(FixedHash const& _h): FixedHash(_h) { init(); } - void addBloom(AbridgedTopic const& _h) { addRaw(_h.template bloomPart()); } - void removeBloom(AbridgedTopic const& _h) { removeRaw(_h.template bloomPart()); } - bool containsBloom(AbridgedTopic const& _h) const { return contains(_h.template bloomPart()); } + void addBloom(dev::shh::AbridgedTopic const& _h) { addRaw(_h.template bloomPart()); } + void removeBloom(dev::shh::AbridgedTopic const& _h) { removeRaw(_h.template bloomPart()); } + bool containsBloom(dev::shh::AbridgedTopic const& _h) const { return contains(_h.template bloomPart()); } void addRaw(FixedHash const& _h); void removeRaw(FixedHash const& _h); @@ -55,7 +53,7 @@ private: std::array m_refCounter; }; -static unsigned const c_mask[8] = { 1, 2, 4, 8, 16, 32, 64, 128 }; +static unsigned const c_powerOfTwoBitMmask[8] = { 1, 2, 4, 8, 16, 32, 64, 128 }; template void TopicBloomFilterBase::addRaw(FixedHash const& _h) @@ -81,7 +79,7 @@ void TopicBloomFilterBase::removeRaw(FixedHash const& _h) m_refCounter[i]--; if (!m_refCounter[i]) - (*this)[i / 8] &= ~c_mask[i % 8]; + (*this)[i / 8] &= ~c_powerOfTwoBitMmask[i % 8]; } } @@ -90,10 +88,10 @@ bool TopicBloomFilterBase::isBitSet(FixedHash const& _h, unsigned _index) { unsigned iByte = _index / 8; unsigned iBit = _index % 8; - return (_h[iByte] & c_mask[iBit]) != 0; + return (_h[iByte] & c_powerOfTwoBitMmask[iBit]) != 0; } -using TopicBloomFilter = TopicBloomFilterBase<4>; +using TopicBloomFilter = TopicBloomFilterBase; } } diff --git a/libwhisper/Common.cpp b/libwhisper/Common.cpp index 7f5b8ed06..32acbdd8e 100644 --- a/libwhisper/Common.cpp +++ b/libwhisper/Common.cpp @@ -95,9 +95,9 @@ TopicFilter::TopicFilter(RLP const& _r) } } -AbridgedTopic TopicFilter::exportBloom() const +FixedHash TopicFilter::exportBloom() const { - AbridgedTopic ret; + FixedHash ret; for (TopicMask const& t: m_topicMasks) for (auto const& i: t) ret |= i.first.template bloomPart(); diff --git a/libwhisper/Common.h b/libwhisper/Common.h index 07c5b3317..71435603e 100644 --- a/libwhisper/Common.h +++ b/libwhisper/Common.h @@ -59,6 +59,8 @@ enum WhisperPacket PacketCount }; +enum { TopicBloomFilterSize = 8 }; + using AbridgedTopic = FixedHash<4>; using Topic = h256; @@ -105,7 +107,7 @@ public: void streamRLP(RLPStream& _s) const { _s << m_topicMasks; } h256 sha3() const; bool matches(Envelope const& _m) const; - AbridgedTopic exportBloom() const; + FixedHash exportBloom() const; private: TopicMasks m_topicMasks; diff --git a/test/libwhisper/bloomFilter.cpp b/test/libwhisper/bloomFilter.cpp index 799c4caf6..e49473bdc 100644 --- a/test/libwhisper/bloomFilter.cpp +++ b/test/libwhisper/bloomFilter.cpp @@ -27,35 +27,39 @@ using namespace std; using namespace dev; using namespace dev::shh; -void testAddNonExisting(TopicBloomFilter& _f, AbridgedTopic const& _h) +using TopicBloomFilterShort = TopicBloomFilterBase<4>; +using TopicBloomFilterLong = TopicBloomFilterBase<8>; +using TopicBloomFilterTest = TopicBloomFilterLong; + +void testAddNonExisting(TopicBloomFilterShort& _f, AbridgedTopic const& _h) { BOOST_REQUIRE(!_f.containsRaw(_h)); _f.addRaw(_h); BOOST_REQUIRE(_f.containsRaw(_h)); } -void testRemoveExisting(TopicBloomFilter& _f, AbridgedTopic const& _h) +void testRemoveExisting(TopicBloomFilterShort& _f, AbridgedTopic const& _h) { BOOST_REQUIRE(_f.containsRaw(_h)); _f.removeRaw(_h); BOOST_REQUIRE(!_f.containsRaw(_h)); } -void testAddNonExistingBloom(TopicBloomFilter& _f, AbridgedTopic const& _h) +void testAddNonExistingBloom(TopicBloomFilterShort& _f, AbridgedTopic const& _h) { BOOST_REQUIRE(!_f.containsBloom(_h)); _f.addBloom(_h); BOOST_REQUIRE(_f.containsBloom(_h)); } -void testRemoveExistingBloom(TopicBloomFilter& _f, AbridgedTopic const& _h) +void testRemoveExistingBloom(TopicBloomFilterShort& _f, AbridgedTopic const& _h) { BOOST_REQUIRE(_f.containsBloom(_h)); _f.removeBloom(_h); BOOST_REQUIRE(!_f.containsBloom(_h)); } -int calculateExpected(TopicBloomFilter const& f, int const n) +int calculateExpected(TopicBloomFilterTest const& f, int const n) { int const m = f.size * 8; // number of bits in the bloom int const k = f.BitsPerBloom; // number of hash functions (e.g. bits set to 1 in every bloom) @@ -76,7 +80,7 @@ int calculateExpected(TopicBloomFilter const& f, int const n) return static_cast(kBitsSet * 100 + 0.5); // in percents, rounded up } -void testFalsePositiveRate(TopicBloomFilter const& f, int const inserted, Topic& x) +void testFalsePositiveRate(TopicBloomFilterTest const& f, int const inserted, Topic& x) { int const c_sampleSize = 1000; int falsePositive = 0; @@ -104,8 +108,8 @@ BOOST_AUTO_TEST_CASE(falsePositiveRate) VerbosityHolder setTemporaryLevel(10); cnote << "Testing Bloom Filter False Positive Rate..."; - TopicBloomFilter f; - Topic x(0xABCDEF); // deterministic pseudorandom value + TopicBloomFilterTest f; + Topic x(0xC0DEFEED); // deterministic pseudorandom value for (int i = 1; i < 21; ++i) { @@ -120,7 +124,7 @@ BOOST_AUTO_TEST_CASE(bloomFilterRandom) VerbosityHolder setTemporaryLevel(10); cnote << "Testing Bloom Filter matching..."; - TopicBloomFilter f; + TopicBloomFilterShort f; vector vec; Topic x(0xDEADBEEF); int const c_rounds = 4; @@ -146,7 +150,7 @@ BOOST_AUTO_TEST_CASE(bloomFilterRaw) VerbosityHolder setTemporaryLevel(10); cnote << "Testing Raw Bloom matching..."; - TopicBloomFilter f; + TopicBloomFilterShort f; AbridgedTopic b00000001(0x01); AbridgedTopic b00010000(0x10); From 7852ce4b3cecc6e4a360a8c3017a332646505fa1 Mon Sep 17 00:00:00 2001 From: Vlad Gluhovsky Date: Fri, 19 Jun 2015 16:12:23 +0200 Subject: [PATCH 3/4] explicit scope resolution added --- libwhisper/BloomFilter.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libwhisper/BloomFilter.h b/libwhisper/BloomFilter.h index 393ccbfd1..3d2ed3e12 100644 --- a/libwhisper/BloomFilter.h +++ b/libwhisper/BloomFilter.h @@ -62,7 +62,7 @@ void TopicBloomFilterBase::addRaw(FixedHash const& _h) for (unsigned i = 0; i < CounterSize; ++i) if (isBitSet(_h, i)) { - if (m_refCounter[i] != numeric_limits::max()) + if (m_refCounter[i] != std::numeric_limits::max()) m_refCounter[i]++; else BOOST_THROW_EXCEPTION(Overflow()); From 726848b0d5ba6d1e6300d33e644e44d53f3c4d55 Mon Sep 17 00:00:00 2001 From: Vlad Gluhovsky Date: Fri, 19 Jun 2015 16:24:13 +0200 Subject: [PATCH 4/4] explicit scope resolution added --- libwhisper/BloomFilter.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libwhisper/BloomFilter.h b/libwhisper/BloomFilter.h index 3d2ed3e12..157f4b011 100644 --- a/libwhisper/BloomFilter.h +++ b/libwhisper/BloomFilter.h @@ -37,11 +37,11 @@ public: void addBloom(dev::shh::AbridgedTopic const& _h) { addRaw(_h.template bloomPart()); } void removeBloom(dev::shh::AbridgedTopic const& _h) { removeRaw(_h.template bloomPart()); } - bool containsBloom(dev::shh::AbridgedTopic const& _h) const { return contains(_h.template bloomPart()); } + bool containsBloom(dev::shh::AbridgedTopic const& _h) const { return this->contains(_h.template bloomPart()); } void addRaw(FixedHash const& _h); void removeRaw(FixedHash const& _h); - bool containsRaw(FixedHash const& _h) const { return contains(_h); } + bool containsRaw(FixedHash const& _h) const { return this->contains(_h); } enum { BitsPerBloom = 3 };