Support emptiness check on Bloom filters.

This commit is contained in:
Matthias Vallentin 2013-07-24 13:18:19 +02:00
parent 5736aef440
commit 5769c32f1e
9 changed files with 53 additions and 0 deletions

View file

@ -583,6 +583,11 @@ void BloomFilterVal::Clear()
bloom_filter->Clear(); bloom_filter->Clear();
} }
bool BloomFilterVal::Empty() const
{
return bloom_filter->Empty();
}
BloomFilterVal* BloomFilterVal::Merge(const BloomFilterVal* x, BloomFilterVal* BloomFilterVal::Merge(const BloomFilterVal* x,
const BloomFilterVal* y) const BloomFilterVal* y)
{ {

View file

@ -126,6 +126,7 @@ public:
void Add(const Val* val); void Add(const Val* val);
size_t Count(const Val* val) const; size_t Count(const Val* val) const;
void Clear(); void Clear();
bool Empty() const;
static BloomFilterVal* Merge(const BloomFilterVal* x, static BloomFilterVal* Merge(const BloomFilterVal* x,
const BloomFilterVal* y); const BloomFilterVal* y);

View file

@ -463,6 +463,14 @@ bool BitVector::Empty() const
return bits.empty(); return bits.empty();
} }
bool BitVector::AllZero() const
{
for ( size_t i = 0; i < bits.size(); ++i )
if ( bits[i] )
return false;
return true;
}
BitVector::size_type BitVector::FindFirst() const BitVector::size_type BitVector::FindFirst() const
{ {
return find_from(0); return find_from(0);

View file

@ -253,6 +253,12 @@ public:
*/ */
bool Empty() const; bool Empty() const;
/**
* Checks whether all bits are 0.
* @return `true` iff all bits in all blocks are 0.
*/
bool AllZero() const;
/** /**
* Finds the bit position of of the first 1-bit. * Finds the bit position of of the first 1-bit.
* @return The position of the first bit that equals to one or `npos` if no * @return The position of the first bit that equals to one or `npos` if no

View file

@ -74,6 +74,11 @@ size_t BasicBloomFilter::K(size_t cells, size_t capacity)
return std::ceil(frac * std::log(2)); return std::ceil(frac * std::log(2));
} }
bool BasicBloomFilter::Empty() const
{
return bits->AllZero();
}
void BasicBloomFilter::Clear() void BasicBloomFilter::Clear()
{ {
bits->Clear(); bits->Clear();
@ -167,6 +172,11 @@ CountingBloomFilter::CountingBloomFilter(const Hasher* hasher,
cells = new CounterVector(width, arg_cells); cells = new CounterVector(width, arg_cells);
} }
bool CountingBloomFilter::Empty() const
{
return cells->AllZero();
}
void CountingBloomFilter::Clear() void CountingBloomFilter::Clear()
{ {
cells->Clear(); cells->Clear();

View file

@ -47,6 +47,13 @@ public:
return CountImpl((*hasher)(x)); return CountImpl((*hasher)(x));
} }
/**
* Checks whether the Bloom filter is empty.
*
* @return `true` if the Bloom filter contains no elements.
*/
virtual bool Empty() const = 0;
/** /**
* Removes all elements, i.e., resets all bits in the underlying bit vector. * Removes all elements, i.e., resets all bits in the underlying bit vector.
*/ */
@ -169,6 +176,7 @@ public:
static size_t K(size_t cells, size_t capacity); static size_t K(size_t cells, size_t capacity);
// Overridden from BloomFilter. // Overridden from BloomFilter.
virtual bool Empty() const;
virtual void Clear(); virtual void Clear();
virtual bool Merge(const BloomFilter* other); virtual bool Merge(const BloomFilter* other);
virtual BasicBloomFilter* Clone() const; virtual BasicBloomFilter* Clone() const;
@ -207,6 +215,7 @@ public:
CountingBloomFilter(const Hasher* hasher, size_t cells, size_t width); CountingBloomFilter(const Hasher* hasher, size_t cells, size_t width);
// Overridden from BloomFilter. // Overridden from BloomFilter.
virtual bool Empty() const;
virtual void Clear(); virtual void Clear();
virtual bool Merge(const BloomFilter* other); virtual bool Merge(const BloomFilter* other);
virtual CountingBloomFilter* Clone() const; virtual CountingBloomFilter* Clone() const;

View file

@ -70,6 +70,11 @@ bool CounterVector::Decrement(size_type cell, count_type value)
return carry; return carry;
} }
bool CounterVector::AllZero() const
{
return bits->AllZero();
}
void CounterVector::Clear() void CounterVector::Clear()
{ {
bits->Clear(); bits->Clear();

View file

@ -77,6 +77,12 @@ public:
*/ */
count_type Count(size_type cell) const; count_type Count(size_type cell) const;
/**
* Checks whether all counters are 0.
* @return `true` iff all counters have the value 0.
*/
bool AllZero() const;
/** /**
* Sets all counters to 0. * Sets all counters to 0.
*/ */

View file

@ -109,6 +109,9 @@ function bloomfilter_lookup%(bf: opaque of bloomfilter, x: any%): count
%{ %{
const BloomFilterVal* bfv = static_cast<const BloomFilterVal*>(bf); const BloomFilterVal* bfv = static_cast<const BloomFilterVal*>(bf);
if ( bfv->Empty() )
return new Val(0, TYPE_COUNT);
if ( ! bfv->Type() ) if ( ! bfv->Type() )
reporter->Error("cannot perform lookup on untyped Bloom filter"); reporter->Error("cannot perform lookup on untyped Bloom filter");