Browse Source

Merge branch 'develop' of github.com:ethereum/cpp-ethereum into develop

cl-refactor
Gav Wood 9 years ago
parent
commit
583f391562
  1. 36
      libwhisper/BloomFilter.cpp
  2. 63
      libwhisper/BloomFilter.h
  3. 4
      libwhisper/Common.cpp
  4. 4
      libwhisper/Common.h
  5. 24
      test/libwhisper/bloomFilter.cpp

36
libwhisper/BloomFilter.cpp

@ -25,40 +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 };
void TopicBloomFilter::addRaw(AbridgedTopic const& _h)
{
*this |= _h;
for (unsigned i = 0; i < CounterSize; ++i)
if (isBitSet(_h, i))
{
if (m_refCounter[i] != numeric_limits<uint16_t>::max())
m_refCounter[i]++;
else
BOOST_THROW_EXCEPTION(Overflow());
}
}
void TopicBloomFilter::removeRaw(AbridgedTopic 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];
}
}
bool TopicBloomFilter::isBitSet(AbridgedTopic const& _h, unsigned _index)
{
unsigned iByte = _index / 8;
unsigned iBit = _index % 8;
return (_h[iByte] & c_mask[iBit]) != 0;
}

63
libwhisper/BloomFilter.h

@ -28,30 +28,71 @@ namespace dev
namespace shh
{
class TopicBloomFilter: public AbridgedTopic
template <unsigned N>
class TopicBloomFilterBase: public FixedHash<N>
{
public:
TopicBloomFilter() { init(); }
TopicBloomFilter(AbridgedTopic const& _h): AbridgedTopic(_h) { init(); }
TopicBloomFilterBase() { init(); }
TopicBloomFilterBase(FixedHash<N> const& _h): FixedHash<N>(_h) { init(); }
void addBloom(AbridgedTopic const& _h) { addRaw(_h.template bloomPart<BitsPerBloom, 4>()); }
void removeBloom(AbridgedTopic const& _h) { removeRaw(_h.template bloomPart<BitsPerBloom, 4>()); }
bool containsBloom(AbridgedTopic const& _h) const { return contains(_h.template bloomPart<BitsPerBloom, 4>()); }
void addBloom(dev::shh::AbridgedTopic const& _h) { addRaw(_h.template bloomPart<BitsPerBloom, N>()); }
void removeBloom(dev::shh::AbridgedTopic const& _h) { removeRaw(_h.template bloomPart<BitsPerBloom, N>()); }
bool containsBloom(dev::shh::AbridgedTopic const& _h) const { return this->contains(_h.template bloomPart<BitsPerBloom, N>()); }
void addRaw(AbridgedTopic const& _h);
void removeRaw(AbridgedTopic const& _h);
bool containsRaw(AbridgedTopic const& _h) const { return contains(_h); }
void addRaw(FixedHash<N> const& _h);
void removeRaw(FixedHash<N> const& _h);
bool containsRaw(FixedHash<N> const& _h) const { return this->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<N> const& _h, unsigned _index);
enum { CounterSize = 8 * TopicBloomFilter::size };
enum { CounterSize = 8 * TopicBloomFilterBase::size };
std::array<uint16_t, CounterSize> m_refCounter;
};
static unsigned const c_powerOfTwoBitMmask[8] = { 1, 2, 4, 8, 16, 32, 64, 128 };
template <unsigned N>
void TopicBloomFilterBase<N>::addRaw(FixedHash<N> const& _h)
{
*this |= _h;
for (unsigned i = 0; i < CounterSize; ++i)
if (isBitSet(_h, i))
{
if (m_refCounter[i] != std::numeric_limits<uint16_t>::max())
m_refCounter[i]++;
else
BOOST_THROW_EXCEPTION(Overflow());
}
}
template <unsigned N>
void TopicBloomFilterBase<N>::removeRaw(FixedHash<N> 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_powerOfTwoBitMmask[i % 8];
}
}
template <unsigned N>
bool TopicBloomFilterBase<N>::isBitSet(FixedHash<N> const& _h, unsigned _index)
{
unsigned iByte = _index / 8;
unsigned iBit = _index % 8;
return (_h[iByte] & c_powerOfTwoBitMmask[iBit]) != 0;
}
using TopicBloomFilter = TopicBloomFilterBase<TopicBloomFilterSize>;
}
}

4
libwhisper/Common.cpp

@ -95,9 +95,9 @@ TopicFilter::TopicFilter(RLP const& _r)
}
}
AbridgedTopic TopicFilter::exportBloom() const
FixedHash<TopicBloomFilter::size> TopicFilter::exportBloom() const
{
AbridgedTopic ret;
FixedHash<TopicBloomFilter::size> ret;
for (TopicMask const& t: m_topicMasks)
for (auto const& i: t)
ret |= i.first.template bloomPart<TopicBloomFilter::BitsPerBloom, TopicBloomFilter::size>();

4
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<TopicBloomFilterSize> exportBloom() const;
private:
TopicMasks m_topicMasks;

24
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<int>(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<AbridgedTopic> 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);

Loading…
Cancel
Save