Browse Source

Bloom Filter introduced

cl-refactor
Vlad Gluhovsky 10 years ago
parent
commit
c925b2936b
  1. 71
      libwhisper/BloomFilter.cpp
  2. 73
      libwhisper/BloomFilter.h
  3. 133
      test/libwhisper/bloomFilter.cpp

71
libwhisper/BloomFilter.cpp

@ -0,0 +1,71 @@
/*
This file is part of cpp-ethereum.
cpp-ethereum is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
cpp-ethereum is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with cpp-ethereum. If not, see <http://www.gnu.org/licenses/>.
*/
/** @file BloomFilter.cpp
* @author Vladislav Gluhovsky <vlad@ethdev.com>
* @date June 2015
*/
#include "BloomFilter.h"
using namespace std;
using namespace dev;
using namespace dev::shh;
bool BloomFilter::matches(AbridgedTopic const& _t) const
{
static unsigned const c_PerfectMatch = ~unsigned(0);
unsigned topic = AbridgedTopic::Arith(_t).convert_to<unsigned>();
unsigned matchingBits = m_filter & topic;
matchingBits |= ~topic;
return (c_PerfectMatch == matchingBits);
}
void SharedBloomFilter::add(AbridgedTopic const& _t)
{
unsigned const topic = AbridgedTopic::Arith(_t).convert_to<unsigned>();
m_filter |= topic;
unsigned nextBit = 1;
for (unsigned i = 0; i < ArrSize; ++i, nextBit <<= 1)
if (topic & nextBit)
if (m_refCounter[i] != numeric_limits<unsigned short>::max())
m_refCounter[i]++;
//else: overflow
// in order to encounter overflow, you have to set 65536 filters simultaneously.
// we assume, it will never happen.
}
void SharedBloomFilter::remove(AbridgedTopic const& _t)
{
unsigned const topic = AbridgedTopic::Arith(_t).convert_to<unsigned>();
unsigned nextBit = 1;
for (unsigned i = 0; i < ArrSize; ++i, nextBit <<= 1)
if (topic & nextBit)
{
if (m_refCounter[i])
m_refCounter[i]--;
if (!m_refCounter[i])
m_filter &= ~nextBit;
}
}

73
libwhisper/BloomFilter.h

@ -0,0 +1,73 @@
/*
This file is part of cpp-ethereum.
cpp-ethereum is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
cpp-ethereum is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with cpp-ethereum. If not, see <http://www.gnu.org/licenses/>.
*/
/** @file BloomFilter.h
* @author Vladislav Gluhovsky <vlad@ethdev.com>
* @date June 2015
*/
#pragma once
#include "Common.h"
namespace dev
{
namespace shh
{
class BloomFilter
{
public:
virtual ~BloomFilter() {}
BloomFilter(): m_filter(0) {}
BloomFilter(unsigned _i): m_filter(_i) {}
BloomFilter(AbridgedTopic const& _t): m_filter(AbridgedTopic::Arith(_t).convert_to<unsigned>()) {}
bool matches(AbridgedTopic const& _t) const;
virtual void add(AbridgedTopic const& _t) { m_filter |= AbridgedTopic::Arith(_t).convert_to<unsigned>(); }
virtual void remove(AbridgedTopic const& ) {} // not implemented in this class, use derived class instead.
protected:
unsigned m_filter;
};
class SharedBloomFilter: public BloomFilter
{
public:
virtual ~SharedBloomFilter() {}
SharedBloomFilter() { init(); }
SharedBloomFilter(unsigned _i): BloomFilter(_i) { init(); }
SharedBloomFilter(AbridgedTopic const& _t): BloomFilter(_t) { init(); }
void add(AbridgedTopic const& _t) override;
void remove(AbridgedTopic const& _t) override;
protected:
void init() { for (unsigned i = 0; i < ArrSize; ++i) m_refCounter[i] = 0; }
private:
enum { ArrSize = 8 * AbridgedTopic::size };
unsigned short m_refCounter[ArrSize];
};
}
}

133
test/libwhisper/bloomFilter.cpp

@ -0,0 +1,133 @@
/*
This file is part of cpp-ethereum.
cpp-ethereum is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
cpp-ethereum is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with cpp-ethereum. If not, see <http://www.gnu.org/licenses/>.
*/
/** @file whisperMessage.cpp
* @author Vladislav Gluhovsky <vlad@ethdev.com>
* @date June 2015
*/
#include <boost/test/unit_test.hpp>
#include <libwhisper/BloomFilter.h>
using namespace std;
using namespace dev;
using namespace dev::shh;
BOOST_AUTO_TEST_SUITE(bloomFilter)
BOOST_AUTO_TEST_CASE(match)
{
VerbosityHolder setTemporaryLevel(10);
cnote << "Testing Bloom Filter matching...";
SharedBloomFilter f;
unsigned b00000001 = 0x01;
unsigned b00010000 = 0x10;
unsigned b00011000 = 0x18;
unsigned b00110000 = 0x30;
unsigned b00110010 = 0x32;
unsigned b00111000 = 0x38;
unsigned b00000110 = 0x06;
unsigned b00110110 = 0x36;
unsigned b00110111 = 0x37;
BOOST_REQUIRE(!f.matches(AbridgedTopic(b00000001)));
f.add(AbridgedTopic(b00000001));
BOOST_REQUIRE(!f.matches(AbridgedTopic(b00010000)));
f.add(AbridgedTopic(b00010000));
BOOST_REQUIRE(!f.matches(AbridgedTopic(b00011000)));
f.add(AbridgedTopic(b00011000));
BOOST_REQUIRE(!f.matches(AbridgedTopic(b00110000)));
f.add(AbridgedTopic(b00110000));
BOOST_REQUIRE(f.matches(AbridgedTopic(b00111000)));
BOOST_REQUIRE(!f.matches(AbridgedTopic(b00110010)));
f.add(AbridgedTopic(b00110010));
BOOST_REQUIRE(!f.matches(AbridgedTopic(b00000110)));
f.add(AbridgedTopic(b00000110));
BOOST_REQUIRE(f.matches(AbridgedTopic(b00110110)));
BOOST_REQUIRE(f.matches(AbridgedTopic(b00110111)));
f.remove(AbridgedTopic(b00000001));
f.remove(AbridgedTopic(b00000001));
f.remove(AbridgedTopic(b00000001));
BOOST_REQUIRE(!f.matches(AbridgedTopic(b00000001)));
BOOST_REQUIRE(f.matches(AbridgedTopic(b00010000)));
BOOST_REQUIRE(f.matches(AbridgedTopic(b00011000)));
BOOST_REQUIRE(f.matches(AbridgedTopic(b00110000)));
BOOST_REQUIRE(f.matches(AbridgedTopic(b00110010)));
BOOST_REQUIRE(f.matches(AbridgedTopic(b00111000)));
BOOST_REQUIRE(f.matches(AbridgedTopic(b00000110)));
BOOST_REQUIRE(f.matches(AbridgedTopic(b00110110)));
BOOST_REQUIRE(!f.matches(AbridgedTopic(b00110111)));
f.remove(AbridgedTopic(b00010000));
BOOST_REQUIRE(!f.matches(AbridgedTopic(b00000001)));
BOOST_REQUIRE(f.matches(AbridgedTopic(b00010000)));
BOOST_REQUIRE(f.matches(AbridgedTopic(b00011000)));
BOOST_REQUIRE(f.matches(AbridgedTopic(b00110000)));
BOOST_REQUIRE(f.matches(AbridgedTopic(b00110010)));
BOOST_REQUIRE(f.matches(AbridgedTopic(b00111000)));
BOOST_REQUIRE(f.matches(AbridgedTopic(b00000110)));
BOOST_REQUIRE(f.matches(AbridgedTopic(b00110110)));
BOOST_REQUIRE(!f.matches(AbridgedTopic(b00110111)));
f.remove(AbridgedTopic(b00111000));
BOOST_REQUIRE(!f.matches(AbridgedTopic(b00000001)));
BOOST_REQUIRE(f.matches(AbridgedTopic(b00010000)));
BOOST_REQUIRE(!f.matches(AbridgedTopic(b00011000)));
BOOST_REQUIRE(f.matches(AbridgedTopic(b00110000)));
BOOST_REQUIRE(f.matches(AbridgedTopic(b00110010)));
BOOST_REQUIRE(!f.matches(AbridgedTopic(b00111000)));
BOOST_REQUIRE(f.matches(AbridgedTopic(b00000110)));
BOOST_REQUIRE(f.matches(AbridgedTopic(b00110110)));
BOOST_REQUIRE(!f.matches(AbridgedTopic(b00110111)));
f.add(AbridgedTopic(b00000001));
BOOST_REQUIRE(f.matches(AbridgedTopic(b00000001)));
BOOST_REQUIRE(f.matches(AbridgedTopic(b00010000)));
BOOST_REQUIRE(!f.matches(AbridgedTopic(b00011000)));
BOOST_REQUIRE(f.matches(AbridgedTopic(b00110000)));
BOOST_REQUIRE(f.matches(AbridgedTopic(b00110010)));
BOOST_REQUIRE(!f.matches(AbridgedTopic(b00111000)));
BOOST_REQUIRE(f.matches(AbridgedTopic(b00000110)));
BOOST_REQUIRE(f.matches(AbridgedTopic(b00110110)));
BOOST_REQUIRE(f.matches(AbridgedTopic(b00110111)));
f.remove(AbridgedTopic(b00110111));
BOOST_REQUIRE(!f.matches(AbridgedTopic(b00000001)));
BOOST_REQUIRE(f.matches(AbridgedTopic(b00010000)));
BOOST_REQUIRE(!f.matches(AbridgedTopic(b00011000)));
BOOST_REQUIRE(!f.matches(AbridgedTopic(b00110000)));
BOOST_REQUIRE(!f.matches(AbridgedTopic(b00110010)));
BOOST_REQUIRE(!f.matches(AbridgedTopic(b00111000)));
BOOST_REQUIRE(!f.matches(AbridgedTopic(b00000110)));
BOOST_REQUIRE(!f.matches(AbridgedTopic(b00110110)));
BOOST_REQUIRE(!f.matches(AbridgedTopic(b00110111)));
f.remove(AbridgedTopic(b00110111));
BOOST_REQUIRE(!f.matches(AbridgedTopic(b00000001)));
BOOST_REQUIRE(!f.matches(AbridgedTopic(b00010000)));
BOOST_REQUIRE(!f.matches(AbridgedTopic(b00011000)));
BOOST_REQUIRE(!f.matches(AbridgedTopic(b00110000)));
BOOST_REQUIRE(!f.matches(AbridgedTopic(b00110010)));
BOOST_REQUIRE(!f.matches(AbridgedTopic(b00111000)));
BOOST_REQUIRE(!f.matches(AbridgedTopic(b00000110)));
BOOST_REQUIRE(!f.matches(AbridgedTopic(b00110110)));
BOOST_REQUIRE(!f.matches(AbridgedTopic(b00110111)));
}
BOOST_AUTO_TEST_SUITE_END()
Loading…
Cancel
Save