Create HyperLogLog objects with sparse encoding.

This commit is contained in:
antirez 2014-04-12 10:56:11 +02:00
parent 1fc04a6221
commit a79386b1af

View File

@ -905,19 +905,37 @@ uint64_t hllCount(struct hllhdr *hdr) {
/* ========================== HyperLogLog commands ========================== */ /* ========================== HyperLogLog commands ========================== */
/* An HyperLogLog object is a string with space for 16k 6-bit integers, /* Create an HLL object. We always create the HLL using sparse encoding.
* a cached 64 bit cardinality value, and a 4 byte "magic" and additional * This will be upgraded to the dense representation as needed. */
* 4 bytes for version reserved for future use. */
robj *createHLLObject(void) { robj *createHLLObject(void) {
robj *o; robj *o;
char *p; struct hllhdr *hdr;
sds s;
uint8_t *p;
int sparselen = HLL_HDR_SIZE +
((HLL_REGISTERS+(HLL_SPARSE_XZERO_MAX_LEN-1)) /
HLL_SPARSE_XZERO_MAX_LEN);
int aux;
/* Create a string of the right size filled with zero bytes. /* Populate the sparse representation with as many XZERO opcodes as
* Note that the cached cardinality is set to 0 as a side effect * needed to represent all the registers. */
* that is exactly the cardinality of an empty HLL. */ aux = sparselen;
o = createObject(REDIS_STRING,sdsnewlen(NULL,HLL_DENSE_SIZE)); s = sdsnewlen(NULL,sparselen);
p = o->ptr; p = (uint8_t*)s + HLL_HDR_SIZE;
memcpy(p,"HYLL",4); while(aux) {
int xzero = HLL_SPARSE_XZERO_MAX_LEN-1;
if (xzero > aux) xzero = aux;
HLL_SPARSE_XZERO_SET(p,xzero);
p += 2;
aux -= xzero;
}
redisAssert((p-(uint8_t*)s) == sparselen);
/* Create the actual object. */
o = createObject(REDIS_STRING,s);
hdr = o->ptr;
memcpy(hdr->magic,"HYLL",4);
hdr->encoding = HLL_SPARSE;
return o; return o;
} }