1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40
|
#include "stdafx.h"
#include <math.h>
#include "ApproximateCounter.h"
using namespace std;
ApproximateCounter::ApproximateCounter()
{
buckets.resize(BUCKETS);
}
void ApproximateCounter::add(_uint64 value)
{
_uint64 h = hash(value);
unsigned bucket = (unsigned) h % BUCKETS;
unsigned rest = (unsigned)(h >> SHIFT);
unsigned long firstZero;
if (rest == 0) {
firstZero = 64 - SHIFT;
} else {
CountTrailingZeroes(rest, firstZero);
}
buckets[bucket] |= (1LL << firstZero);
}
unsigned ApproximateCounter::getCount()
{
double s = 0;
for (int i = 0; i < BUCKETS; i++) {
_uint64 r = 0;
while (r < 64 && (buckets[i] & (1LL << r)) != 0) {
r++;
}
s += r;
}
return (unsigned) (BUCKETS / 0.77351 * pow(2, s / BUCKETS));
}
|