Implement missing CounterVector functions.

This commit is contained in:
Matthias Vallentin 2013-07-21 22:41:48 +02:00
parent fd2e155d1a
commit 79a2e4b5d5
2 changed files with 73 additions and 8 deletions

View file

@ -1,5 +1,6 @@
#include "CounterVector.h"
#include <limits>
#include "BitVector.h"
#include "Serializer.h"
@ -15,23 +16,66 @@ CounterVector::~CounterVector()
bool CounterVector::Increment(size_type cell, count_type value)
{
// TODO
assert(! "not yet implemented");
assert(cell < Size());
assert(value != 0);
size_t lsb = cell * width_;
if (value >= Max())
{
bool r = false;
for (size_t i = 0; i < width_; ++i)
if (! (*bits_)[lsb + i])
{
bits_->Set(lsb + i);
if (! r)
r = true;
}
return r;
}
bool carry = false;
for (size_t i = 0; i < width_; ++i)
{
bool b1 = (*bits_)[lsb + i];
bool b2 = value & (1 << i);
(*bits_)[lsb + i] ^= b2 != carry; // bit1 ^ bit2 ^ carry
carry = carry ? b1 || b2 : b1 && b2;
}
if (! carry)
return true;
for (size_t i = 0; i < width_; ++i)
bits_->Set(lsb + i);
return false;
}
bool CounterVector::Decrement(size_type cell, count_type value)
{
// TODO
assert(! "not yet implemented");
return false;
assert(cell < Size());
size_t lsb = cell * width_;
bool success;
while (value --> 0)
{
success = false;
for (size_t i = lsb; i < lsb + width_; ++i)
if ((*bits_)[i])
{
bits_->Reset(i);
while (i && i > lsb)
bits_->Set(--i);
success = true;
break;
}
}
return success;
}
CounterVector::count_type CounterVector::Count(size_type cell) const
{
// TODO
assert(! "not yet implemented");
return 0;
assert(cell < Size());
size_t cnt = 0, order = 1;
size_t lsb = cell * width_;
for (size_t i = lsb; i < lsb + width_; ++i, order <<= 1)
if ((*bits_)[i])
cnt |= order;
return cnt;
}
CounterVector::size_type CounterVector::Size() const
@ -39,6 +83,12 @@ CounterVector::size_type CounterVector::Size() const
return bits_->Blocks() / width_;
}
size_t CounterVector::Max() const
{
return std::numeric_limits<size_t>::max()
>> (std::numeric_limits<size_t>::digits - width_);
}
bool CounterVector::Serialize(SerialInfo* info) const
{
return SerialObj::Serialize(info);

View file

@ -19,6 +19,8 @@ public:
* @param width The number of bits that each cell occupies.
*
* @param cells The number of cells in the bitvector.
*
* @pre `cells > 0 && width > 0`
*/
CounterVector(size_t width, size_t cells = 1024);
@ -32,6 +34,8 @@ public:
* @param value The value to add to the current counter in *cell*.
*
* @return `true` if adding *value* to the counter in *cell* succeeded.
*
* @pre `cell < Size()`
*/
bool Increment(size_type cell, count_type value);
@ -43,6 +47,8 @@ public:
* @param value The value to subtract from the current counter in *cell*.
*
* @return `true` if subtracting *value* from the counter in *cell* succeeded.
*
* @pre `cell < Size()`
*/
bool Decrement(size_type cell, count_type value);
@ -52,6 +58,8 @@ public:
* @param cell The cell index to retrieve the count for.
*
* @return The counter associated with *cell*.
*
* @pre `cell < Size()`
*/
count_type Count(size_type cell) const;
@ -62,6 +70,13 @@ public:
*/
size_type Size() const;
/**
* Computes the maximum counter value.
*
* @return The maximum counter value based on the width.
*/
size_t Max() const;
bool Serialize(SerialInfo* info) const;
static CounterVector* Unserialize(UnserialInfo* info);