Skip to content
Snippets Groups Projects
Commit 948c9795 authored by Alvaro Herrera's avatar Alvaro Herrera
Browse files

Add two HyperLogLog functions

New functions initHyperLogLogError() and freeHyperLogLog() simplify
using this module from elsewhere.

Author: Tomáš Vondra
Review: Peter Geoghegan
parent 9ff60273
Branches
Tags
No related merge requests found
......@@ -56,7 +56,7 @@
static inline uint8 rho(uint32 x, uint8 b);
/*
* Initialize HyperLogLog track state
* Initialize HyperLogLog track state, by bit width
*
* bwidth is bit width (so register size will be 2 to the power of bwidth).
* Must be between 4 and 16 inclusive.
......@@ -107,6 +107,52 @@ initHyperLogLog(hyperLogLogState *cState, uint8 bwidth)
cState->alphaMM = alpha * cState->nRegisters * cState->nRegisters;
}
/*
* Initialize HyperLogLog track state, by error rate
*
* Instead of specifying bwidth (number of bits used for addressing the
* register), this method allows sizing the counter for particular error
* rate using a simple formula from the paper:
*
* e = 1.04 / sqrt(m)
*
* where 'm' is the number of registers, i.e. (2^bwidth). The method
* finds the lowest bwidth with 'e' below the requested error rate, and
* then uses it to initialize the counter.
*
* As bwidth has to be between 4 and 16, the worst possible error rate
* is between ~25% (bwidth=4) and 0.4% (bwidth=16).
*/
void
initHyperLogLogError(hyperLogLogState *cState, double error)
{
uint8 bwidth = 4;
while (bwidth < 16)
{
double m = (Size) 1 << bwidth;
if (1.04 / sqrt(m) < error)
break;
bwidth++;
}
initHyperLogLog(cState, bwidth);
}
/*
* Free HyperLogLog track state
*
* Releases allocated resources, but not the state itself (in case it's not
* allocated by palloc).
*/
void
freeHyperLogLog(hyperLogLogState *cState)
{
Assert(cState->hashesArr != NULL);
pfree(cState->hashesArr);
}
/*
* Adds element to the estimator, from caller-supplied hash.
*
......
......@@ -60,8 +60,10 @@ typedef struct hyperLogLogState
} hyperLogLogState;
extern void initHyperLogLog(hyperLogLogState *cState, uint8 bwidth);
extern void initHyperLogLogError(hyperLogLogState *cState, double error);
extern void addHyperLogLog(hyperLogLogState *cState, uint32 hash);
extern double estimateHyperLogLog(hyperLogLogState *cState);
extern void mergeHyperLogLog(hyperLogLogState *cState, const hyperLogLogState *oState);
extern void freeHyperLogLog(hyperLogLogState *cState);
#endif /* HYPERLOGLOG_H */
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment