mem-ruby: Define BloomFilter namespace

Define a BloomFilter namespace and put all BloomFilter related
code in it.

As a side effect the BloomFilter classes have been renamed to
remove the "BloomFilter" suffix.

Change-Id: I3ee8cc225bf3b820e561c3e25a6bf38e0012e3a8
Signed-off-by: Daniel R. Carvalho <odanrc@yahoo.com.br>
Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/18874
Reviewed-by: Nikos Nikoleris <nikos.nikoleris@arm.com>
Maintainer: Nikos Nikoleris <nikos.nikoleris@arm.com>
Tested-by: kokoro <noreply+kokoro@google.com>
This commit is contained in:
Daniel R. Carvalho
2019-05-11 17:37:18 +02:00
committed by Daniel Carvalho
parent d4df04c493
commit 09281876a7
14 changed files with 185 additions and 128 deletions

View File

@@ -36,10 +36,12 @@
#include "base/intmath.hh"
#include "base/types.hh"
#include "params/AbstractBloomFilter.hh"
#include "params/BloomFilterBase.hh"
#include "sim/sim_object.hh"
class AbstractBloomFilter : public SimObject
namespace BloomFilter {
class Base : public SimObject
{
protected:
/** Number of LSB bits to ignore from the the addresses. */
@@ -58,13 +60,13 @@ class AbstractBloomFilter : public SimObject
/**
* Create and clear the filter.
*/
AbstractBloomFilter(const AbstractBloomFilterParams* p)
Base(const BloomFilterBaseParams* p)
: SimObject(p), offsetBits(p->offset_bits), filter(p->size),
sizeBits(floorLog2(p->size)), setThreshold(p->threshold)
{
clear();
}
virtual ~AbstractBloomFilter() {};
virtual ~Base() {};
/**
* Clear the filter by resetting all values.
@@ -83,7 +85,7 @@ class AbstractBloomFilter : public SimObject
* @param other The other bloom filter to merge with.
*/
virtual void
merge(const AbstractBloomFilter* other)
merge(const Base* other)
{
assert(filter.size() == other->filter.size());
for (int i = 0; i < filter.size(); ++i){
@@ -144,4 +146,6 @@ class AbstractBloomFilter : public SimObject
}
};
} // namespace BloomFilter
#endif // __MEM_RUBY_FILTERS_ABSTRACTBLOOMFILTER_HH__

View File

@@ -30,10 +30,12 @@
#include "base/bitfield.hh"
#include "base/logging.hh"
#include "params/BlockBloomFilter.hh"
#include "params/BloomFilterBlock.hh"
BlockBloomFilter::BlockBloomFilter(const BlockBloomFilterParams* p)
: AbstractBloomFilter(p), masksLSBs(p->masks_lsbs),
namespace BloomFilter {
Block::Block(const BloomFilterBlockParams* p)
: Base(p), masksLSBs(p->masks_lsbs),
masksSizes(p->masks_sizes)
{
fatal_if(masksLSBs.size() != masksSizes.size(),
@@ -51,30 +53,30 @@ BlockBloomFilter::BlockBloomFilter(const BlockBloomFilterParams* p)
}
}
BlockBloomFilter::~BlockBloomFilter()
Block::~Block()
{
}
void
BlockBloomFilter::set(Addr addr)
Block::set(Addr addr)
{
filter[hash(addr)] = 1;
}
void
BlockBloomFilter::unset(Addr addr)
Block::unset(Addr addr)
{
filter[hash(addr)] = 0;
}
int
BlockBloomFilter::getCount(Addr addr) const
Block::getCount(Addr addr) const
{
return filter[hash(addr)];
}
int
BlockBloomFilter::hash(Addr addr) const
Block::hash(Addr addr) const
{
Addr hashed_addr = 0;
for (int i = 0; i < masksLSBs.size(); i++) {
@@ -86,8 +88,11 @@ BlockBloomFilter::hash(Addr addr) const
return hashed_addr;
}
BlockBloomFilter*
BlockBloomFilterParams::create()
} // namespace BloomFilter
BloomFilter::Block*
BloomFilterBlockParams::create()
{
return new BlockBloomFilter(this);
return new BloomFilter::Block(this);
}

View File

@@ -33,17 +33,19 @@
#include "mem/ruby/filters/AbstractBloomFilter.hh"
struct BlockBloomFilterParams;
struct BloomFilterBlockParams;
namespace BloomFilter {
/**
* Simple deletable (with false negatives) bloom filter that extracts
* bitfields of an address to use as indexes of the filter vector.
*/
class BlockBloomFilter : public AbstractBloomFilter
class Block : public Base
{
public:
BlockBloomFilter(const BlockBloomFilterParams* p);
~BlockBloomFilter();
Block(const BloomFilterBlockParams* p);
~Block();
void set(Addr addr) override;
void unset(Addr addr) override;
@@ -65,4 +67,6 @@ class BlockBloomFilter : public AbstractBloomFilter
std::vector<unsigned> masksSizes;
};
} // namespace BloomFilter
#endif // __MEM_RUBY_FILTERS_BLOCKBLOOMFILTER_HH__

View File

@@ -30,10 +30,11 @@ from m5.params import *
from m5.proxy import *
from m5.SimObject import SimObject
class AbstractBloomFilter(SimObject):
type = 'AbstractBloomFilter'
class BloomFilterBase(SimObject):
type = 'BloomFilterBase'
abstract = True
cxx_header = "mem/ruby/filters/AbstractBloomFilter.hh"
cxx_class = 'BloomFilter::Base'
size = Param.Int(4096, "Number of entries in the filter")
@@ -43,9 +44,9 @@ class AbstractBloomFilter(SimObject):
# Most of the filters are booleans, and thus saturate on 1
threshold = Param.Int(1, "Value at which an entry is considered as set")
class BlockBloomFilter(AbstractBloomFilter):
type = 'BlockBloomFilter'
cxx_class = 'BlockBloomFilter'
class BloomFilterBlock(BloomFilterBase):
type = 'BloomFilterBlock'
cxx_class = 'BloomFilter::Block'
cxx_header = "mem/ruby/filters/BlockBloomFilter.hh"
masks_lsbs = VectorParam.Unsigned([Self.offset_bits,
@@ -53,14 +54,14 @@ class BlockBloomFilter(AbstractBloomFilter):
masks_sizes = VectorParam.Unsigned([Self.offset_bits, Self.offset_bits],
"Size, in number of bits, of each mask")
class BulkBloomFilter(AbstractBloomFilter):
type = 'BulkBloomFilter'
cxx_class = 'BulkBloomFilter'
class BloomFilterBulk(BloomFilterBase):
type = 'BloomFilterBulk'
cxx_class = 'BloomFilter::Bulk'
cxx_header = "mem/ruby/filters/BulkBloomFilter.hh"
class LSB_CountingBloomFilter(AbstractBloomFilter):
type = 'LSB_CountingBloomFilter'
cxx_class = 'LSB_CountingBloomFilter'
class BloomFilterLSBCounting(BloomFilterBase):
type = 'BloomFilterLSBCounting'
cxx_class = 'BloomFilter::LSBCounting'
cxx_header = "mem/ruby/filters/LSB_CountingBloomFilter.hh"
# By default use 4-bit saturating counters
@@ -69,9 +70,9 @@ class LSB_CountingBloomFilter(AbstractBloomFilter):
# We assume that isSet will return true only when the counter saturates
threshold = Self.max_value
class MultiBitSelBloomFilter(AbstractBloomFilter):
type = 'MultiBitSelBloomFilter'
cxx_class = 'MultiBitSelBloomFilter'
class BloomFilterMultiBitSel(BloomFilterBase):
type = 'BloomFilterMultiBitSel'
cxx_class = 'BloomFilter::MultiBitSel'
cxx_header = "mem/ruby/filters/MultiBitSelBloomFilter.hh"
num_hashes = Param.Int(4, "Number of hashes")
@@ -79,14 +80,14 @@ class MultiBitSelBloomFilter(AbstractBloomFilter):
skip_bits = Param.Int(2, "Offset from block number")
is_parallel = Param.Bool(False, "Whether hashing is done in parallel")
class H3BloomFilter(MultiBitSelBloomFilter):
type = 'H3BloomFilter'
cxx_class = 'H3BloomFilter'
class BloomFilterH3(BloomFilterMultiBitSel):
type = 'BloomFilterH3'
cxx_class = 'BloomFilter::H3'
cxx_header = "mem/ruby/filters/H3BloomFilter.hh"
class MultiGrainBloomFilter(AbstractBloomFilter):
type = 'MultiGrainBloomFilter'
cxx_class = 'MultiGrainBloomFilter'
class BloomFilterMultiGrain(BloomFilterBase):
type = 'BloomFilterMultiGrain'
cxx_class = 'BloomFilter::MultiGrain'
cxx_header = "mem/ruby/filters/MultiGrainBloomFilter.hh"
# The base filter should not be used, since this filter is the combination
@@ -94,9 +95,9 @@ class MultiGrainBloomFilter(AbstractBloomFilter):
size = 1
# By default there are two sub-filters that hash sequential bitfields
filters = VectorParam.AbstractBloomFilter([
BlockBloomFilter(size = 4096, masks_lsbs = [6, 12]),
BlockBloomFilter(size = 1024, masks_lsbs = [18, 24])],
filters = VectorParam.BloomFilterBase([
BloomFilterBlock(size = 4096, masks_lsbs = [6, 12]),
BloomFilterBlock(size = 1024, masks_lsbs = [18, 24])],
"Sub-filters to be combined")
# By default match this with the number of sub-filters

View File

@@ -31,19 +31,21 @@
#include <limits>
#include "base/bitfield.hh"
#include "params/BulkBloomFilter.hh"
#include "params/BloomFilterBulk.hh"
BulkBloomFilter::BulkBloomFilter(const BulkBloomFilterParams* p)
: AbstractBloomFilter(p), sectorBits(sizeBits - 1)
namespace BloomFilter {
Bulk::Bulk(const BloomFilterBulkParams* p)
: Base(p), sectorBits(sizeBits - 1)
{
}
BulkBloomFilter::~BulkBloomFilter()
Bulk::~Bulk()
{
}
void
BulkBloomFilter::set(Addr addr)
Bulk::set(Addr addr)
{
// c0 contains the cache index bits
int c0 = bits(addr, offsetBits + sectorBits - 1, offsetBits);
@@ -61,7 +63,7 @@ BulkBloomFilter::set(Addr addr)
}
bool
BulkBloomFilter::isSet(Addr addr) const
Bulk::isSet(Addr addr) const
{
// c0 contains the cache index bits
const int filter_size = filter.size();
@@ -117,14 +119,14 @@ BulkBloomFilter::isSet(Addr addr) const
}
int
BulkBloomFilter::getCount(Addr addr) const
Bulk::getCount(Addr addr) const
{
// TODO as in the multi-hashed filters
return 0;
}
Addr
BulkBloomFilter::hash(Addr addr) const
Bulk::hash(Addr addr) const
{
// permutes the original address bits according to Table 5
Addr part1 = bits(addr, offsetBits + 6, offsetBits),
@@ -152,8 +154,11 @@ BulkBloomFilter::hash(Addr addr) const
return result;
}
BulkBloomFilter*
BulkBloomFilterParams::create()
} // namespace BloomFilter
BloomFilter::Bulk*
BloomFilterBulkParams::create()
{
return new BulkBloomFilter(this);
return new BloomFilter::Bulk(this);
}

View File

@@ -33,17 +33,19 @@
#include "mem/ruby/filters/AbstractBloomFilter.hh"
struct BulkBloomFilterParams;
struct BloomFilterBulkParams;
namespace BloomFilter {
/**
* Implementation of the bloom filter, as described in "Bulk Disambiguation of
* Speculative Threads in Multiprocessors", by Ceze, Luis, et al.
*/
class BulkBloomFilter : public AbstractBloomFilter
class Bulk : public Base
{
public:
BulkBloomFilter(const BulkBloomFilterParams* p);
~BulkBloomFilter();
Bulk(const BloomFilterBulkParams* p);
~Bulk();
void set(Addr addr) override;
@@ -58,4 +60,6 @@ class BulkBloomFilter : public AbstractBloomFilter
const int sectorBits;
};
} // namespace BloomFilter
#endif // __MEM_RUBY_FILTERS_BULKBLOOMFILTER_HH__

View File

@@ -32,9 +32,11 @@
#include "base/logging.hh"
#include "base/bitfield.hh"
#include "params/H3BloomFilter.hh"
#include "params/BloomFilterH3.hh"
static int H3[64][16] = {
namespace BloomFilter {
static int H3Matrix[64][16] = {
{ 33268410, 395488709, 311024285, 456111753,
181495008, 119997521, 220697869, 433891432,
755927921, 515226970, 719448198, 349842774,
@@ -356,18 +358,18 @@ static int H3[64][16] = {
394261773, 848616745, 15446017, 517723271, },
};
H3BloomFilter::H3BloomFilter(const H3BloomFilterParams* p)
: MultiBitSelBloomFilter(p)
H3::H3(const BloomFilterH3Params* p)
: MultiBitSel(p)
{
fatal_if(numHashes > 16, "There are only 16 H3 functions implemented.");
}
H3BloomFilter::~H3BloomFilter()
H3::~H3()
{
}
int
H3BloomFilter::hash(Addr addr, int hash_number) const
H3::hash(Addr addr, int hash_number) const
{
uint64_t val =
bits(addr, std::numeric_limits<Addr>::digits - 1, offsetBits);
@@ -375,7 +377,7 @@ H3BloomFilter::hash(Addr addr, int hash_number) const
for (int i = 0; (i < 64) && val; i++, val >>= 1) {
if (val & 1) {
result ^= H3[i][hash_number];
result ^= H3Matrix[i][hash_number];
}
}
@@ -386,8 +388,11 @@ H3BloomFilter::hash(Addr addr, int hash_number) const
}
}
H3BloomFilter*
H3BloomFilterParams::create()
} // namespace BloomFilter
BloomFilter::H3*
BloomFilterH3Params::create()
{
return new H3BloomFilter(this);
return new BloomFilter::H3(this);
}

View File

@@ -31,20 +31,24 @@
#include "mem/ruby/filters/MultiBitSelBloomFilter.hh"
struct H3BloomFilterParams;
struct BloomFilterH3Params;
namespace BloomFilter {
/**
* Implementation of the bloom filter as described in "Implementing Signatures
* for Transactional Memory", by Sanchez, Daniel, et al.
*/
class H3BloomFilter : public MultiBitSelBloomFilter
class H3 : public MultiBitSel
{
public:
H3BloomFilter(const H3BloomFilterParams* p);
~H3BloomFilter();
H3(const BloomFilterH3Params* p);
~H3();
protected:
int hash(Addr addr, int hash_number) const override;
};
} // namespace BloomFilter
#endif // __MEM_RUBY_FILTERS_H3BLOOMFILTER_HH__

View File

@@ -29,22 +29,24 @@
#include "mem/ruby/filters/LSB_CountingBloomFilter.hh"
#include "base/bitfield.hh"
#include "params/LSB_CountingBloomFilter.hh"
#include "params/BloomFilterLSBCounting.hh"
LSB_CountingBloomFilter::LSB_CountingBloomFilter(
const LSB_CountingBloomFilterParams* p)
: AbstractBloomFilter(p), maxValue(p->max_value)
namespace BloomFilter {
LSBCounting::LSBCounting(
const BloomFilterLSBCountingParams* p)
: Base(p), maxValue(p->max_value)
{
}
LSB_CountingBloomFilter::~LSB_CountingBloomFilter()
LSBCounting::~LSBCounting()
{
}
void
LSB_CountingBloomFilter::merge(const AbstractBloomFilter* other)
LSBCounting::merge(const Base* other)
{
auto* cast_other = static_cast<const LSB_CountingBloomFilter*>(other);
auto* cast_other = static_cast<const LSBCounting*>(other);
assert(filter.size() == cast_other->filter.size());
for (int i = 0; i < filter.size(); ++i){
if (filter[i] < maxValue - cast_other->filter[i]) {
@@ -56,7 +58,7 @@ LSB_CountingBloomFilter::merge(const AbstractBloomFilter* other)
}
void
LSB_CountingBloomFilter::set(Addr addr)
LSBCounting::set(Addr addr)
{
const int i = hash(addr);
if (filter[i] < maxValue)
@@ -64,7 +66,7 @@ LSB_CountingBloomFilter::set(Addr addr)
}
void
LSB_CountingBloomFilter::unset(Addr addr)
LSBCounting::unset(Addr addr)
{
const int i = hash(addr);
if (filter[i] > 0)
@@ -72,19 +74,22 @@ LSB_CountingBloomFilter::unset(Addr addr)
}
int
LSB_CountingBloomFilter::getCount(Addr addr) const
LSBCounting::getCount(Addr addr) const
{
return filter[hash(addr)];
}
int
LSB_CountingBloomFilter::hash(Addr addr) const
LSBCounting::hash(Addr addr) const
{
return bits(addr, offsetBits + sizeBits - 1, offsetBits);
}
LSB_CountingBloomFilter*
LSB_CountingBloomFilterParams::create()
} // namespace BloomFilter
BloomFilter::LSBCounting*
BloomFilterLSBCountingParams::create()
{
return new LSB_CountingBloomFilter(this);
return new BloomFilter::LSBCounting(this);
}

View File

@@ -31,15 +31,17 @@
#include "mem/ruby/filters/AbstractBloomFilter.hh"
struct LSB_CountingBloomFilterParams;
struct BloomFilterLSBCountingParams;
class LSB_CountingBloomFilter : public AbstractBloomFilter
namespace BloomFilter {
class LSBCounting : public Base
{
public:
LSB_CountingBloomFilter(const LSB_CountingBloomFilterParams* p);
~LSB_CountingBloomFilter();
LSBCounting(const BloomFilterLSBCountingParams* p);
~LSBCounting();
void merge(const AbstractBloomFilter* other) override;
void merge(const Base* other) override;
void set(Addr addr) override;
void unset(Addr addr) override;
@@ -52,4 +54,6 @@ class LSB_CountingBloomFilter : public AbstractBloomFilter
const int maxValue;
};
} // namespace BloomFilter
#endif //__MEM_RUBY_FILTERS_LSB_COUNTINGBLOOMFILTER_HH__

View File

@@ -32,11 +32,12 @@
#include "base/bitfield.hh"
#include "base/logging.hh"
#include "params/MultiBitSelBloomFilter.hh"
#include "params/BloomFilterMultiBitSel.hh"
MultiBitSelBloomFilter::MultiBitSelBloomFilter(
const MultiBitSelBloomFilterParams* p)
: AbstractBloomFilter(p), numHashes(p->num_hashes),
namespace BloomFilter {
MultiBitSel::MultiBitSel(const BloomFilterMultiBitSelParams* p)
: Base(p), numHashes(p->num_hashes),
parFilterSize(p->size / numHashes),
isParallel(p->is_parallel), skipBits(p->skip_bits)
{
@@ -46,12 +47,12 @@ MultiBitSelBloomFilter::MultiBitSelBloomFilter(
}
}
MultiBitSelBloomFilter::~MultiBitSelBloomFilter()
MultiBitSel::~MultiBitSel()
{
}
void
MultiBitSelBloomFilter::set(Addr addr)
MultiBitSel::set(Addr addr)
{
for (int i = 0; i < numHashes; i++) {
int idx = hash(addr, i);
@@ -60,7 +61,7 @@ MultiBitSelBloomFilter::set(Addr addr)
}
int
MultiBitSelBloomFilter::getCount(Addr addr) const
MultiBitSel::getCount(Addr addr) const
{
int count = 0;
for (int i=0; i < numHashes; i++) {
@@ -70,7 +71,7 @@ MultiBitSelBloomFilter::getCount(Addr addr) const
}
int
MultiBitSelBloomFilter::hash(Addr addr, int hash_number) const
MultiBitSel::hash(Addr addr, int hash_number) const
{
uint64_t value = bits(addr, std::numeric_limits<Addr>::digits - 1,
offsetBits) >> skipBits;
@@ -92,8 +93,11 @@ MultiBitSelBloomFilter::hash(Addr addr, int hash_number) const
}
}
MultiBitSelBloomFilter*
MultiBitSelBloomFilterParams::create()
} // namespace BloomFilter
BloomFilter::MultiBitSel*
BloomFilterMultiBitSelParams::create()
{
return new MultiBitSelBloomFilter(this);
return new BloomFilter::MultiBitSel(this);
}

View File

@@ -31,17 +31,19 @@
#include "mem/ruby/filters/AbstractBloomFilter.hh"
struct MultiBitSelBloomFilterParams;
struct BloomFilterMultiBitSelParams;
namespace BloomFilter {
/**
* The MultiBitSel Bloom Filter associates an address to multiple entries
* through the use of multiple hash functions.
*/
class MultiBitSelBloomFilter : public AbstractBloomFilter
class MultiBitSel : public Base
{
public:
MultiBitSelBloomFilter(const MultiBitSelBloomFilterParams* p);
~MultiBitSelBloomFilter();
MultiBitSel(const BloomFilterMultiBitSelParams* p);
~MultiBitSel();
void set(Addr addr) override;
int getCount(Addr addr) const override;
@@ -72,4 +74,6 @@ class MultiBitSelBloomFilter : public AbstractBloomFilter
const int skipBits;
};
} // namespace BloomFilter
#endif // __MEM_RUBY_FILTERS_MULTIBITSELBLOOMFILTER_HH__

View File

@@ -29,20 +29,21 @@
#include "mem/ruby/filters/MultiGrainBloomFilter.hh"
#include "base/logging.hh"
#include "params/MultiGrainBloomFilter.hh"
#include "params/BloomFilterMultiGrain.hh"
MultiGrainBloomFilter::MultiGrainBloomFilter(
const MultiGrainBloomFilterParams* p)
: AbstractBloomFilter(p), filters(p->filters)
namespace BloomFilter {
MultiGrain::MultiGrain(const BloomFilterMultiGrainParams* p)
: Base(p), filters(p->filters)
{
}
MultiGrainBloomFilter::~MultiGrainBloomFilter()
MultiGrain::~MultiGrain()
{
}
void
MultiGrainBloomFilter::clear()
MultiGrain::clear()
{
for (auto& sub_filter : filters) {
sub_filter->clear();
@@ -50,9 +51,9 @@ MultiGrainBloomFilter::clear()
}
void
MultiGrainBloomFilter::merge(const AbstractBloomFilter* other)
MultiGrain::merge(const Base* other)
{
auto* cast_other = static_cast<const MultiGrainBloomFilter*>(other);
auto* cast_other = static_cast<const MultiGrain*>(other);
assert(filters.size() == cast_other->filters.size());
for (int i = 0; i < filters.size(); ++i){
filters[i]->merge(cast_other->filters[i]);
@@ -60,7 +61,7 @@ MultiGrainBloomFilter::merge(const AbstractBloomFilter* other)
}
void
MultiGrainBloomFilter::set(Addr addr)
MultiGrain::set(Addr addr)
{
for (auto& sub_filter : filters) {
sub_filter->set(addr);
@@ -68,7 +69,7 @@ MultiGrainBloomFilter::set(Addr addr)
}
void
MultiGrainBloomFilter::unset(Addr addr)
MultiGrain::unset(Addr addr)
{
for (auto& sub_filter : filters) {
sub_filter->unset(addr);
@@ -76,7 +77,7 @@ MultiGrainBloomFilter::unset(Addr addr)
}
bool
MultiGrainBloomFilter::isSet(Addr addr) const
MultiGrain::isSet(Addr addr) const
{
int count = 0;
for (const auto& sub_filter : filters) {
@@ -88,7 +89,7 @@ MultiGrainBloomFilter::isSet(Addr addr) const
}
int
MultiGrainBloomFilter::getCount(Addr addr) const
MultiGrain::getCount(Addr addr) const
{
int count = 0;
for (const auto& sub_filter : filters) {
@@ -98,7 +99,7 @@ MultiGrainBloomFilter::getCount(Addr addr) const
}
int
MultiGrainBloomFilter::getTotalCount() const
MultiGrain::getTotalCount() const
{
int count = 0;
for (const auto& sub_filter : filters) {
@@ -107,8 +108,11 @@ MultiGrainBloomFilter::getTotalCount() const
return count;
}
MultiGrainBloomFilter*
MultiGrainBloomFilterParams::create()
} // namespace BloomFilter
BloomFilter::MultiGrain*
BloomFilterMultiGrainParams::create()
{
return new MultiGrainBloomFilter(this);
return new BloomFilter::MultiGrain(this);
}

View File

@@ -33,31 +33,35 @@
#include "mem/ruby/filters/AbstractBloomFilter.hh"
struct MultiGrainBloomFilterParams;
struct BloomFilterMultiGrainParams;
namespace BloomFilter {
/**
* This BloomFilter has multiple sub-filters, each with its own hashing
* functionality. The results of the operations are the results of applying
* them to each sub-filter.
*/
class MultiGrainBloomFilter : public AbstractBloomFilter
class MultiGrain : public Base
{
public:
MultiGrainBloomFilter(const MultiGrainBloomFilterParams* p);
~MultiGrainBloomFilter();
MultiGrain(const BloomFilterMultiGrainParams* p);
~MultiGrain();
void clear() override;
void set(Addr addr) override;
void unset(Addr addr) override;
void merge(const AbstractBloomFilter* other) override;
void merge(const Base* other) override;
bool isSet(Addr addr) const override;
int getCount(Addr addr) const override;
int getTotalCount() const override;
private:
/** Sub-filters used by this filter. */
std::vector<AbstractBloomFilter*> filters;
std::vector<Base*> filters;
};
} // namespace BloomFilter
#endif // __MEM_RUBY_FILTERS_MULTIGRAINBLOOMFILTER_HH__