MCPcopy Create free account
hub / github.com/Snapchat/KeyDB / hllSparseToDense

Function hllSparseToDense

src/hyperloglog.cpp:586–639  ·  view source on GitHub ↗

Convert the HLL with sparse representation given as input in its dense * representation. Both representations are represented by SDS strings, and * the input representation is freed as a side effect. * * The function returns C_OK if the sparse representation was valid, * otherwise C_ERR is returned if the representation was corrupted. */

Source from the content-addressed store, hash-verified

584 * The function returns C_OK if the sparse representation was valid,
585 * otherwise C_ERR is returned if the representation was corrupted. */
586int hllSparseToDense(robj *o) {
587 sds sparse = szFromObj(o), dense;
588 struct hllhdr *hdr, *oldhdr = (struct hllhdr*)sparse;
589 int idx = 0, runlen, regval;
590 uint8_t *p = (uint8_t*)sparse, *end = p+sdslen(sparse);
591
592 /* If the representation is already the right one return ASAP. */
593 hdr = (struct hllhdr*) sparse;
594 if (hdr->encoding == HLL_DENSE) return C_OK;
595
596 /* Create a string of the right size filled with zero bytes.
597 * Note that the cached cardinality is set to 0 as a side effect
598 * that is exactly the cardinality of an empty HLL. */
599 dense = sdsnewlen(NULL,HLL_DENSE_SIZE);
600 hdr = (struct hllhdr*) dense;
601 *hdr = *oldhdr; /* This will copy the magic and cached cardinality. */
602 hdr->encoding = HLL_DENSE;
603
604 /* Now read the sparse representation and set non-zero registers
605 * accordingly. */
606 p += HLL_HDR_SIZE;
607 while(p < end) {
608 if (HLL_SPARSE_IS_ZERO(p)) {
609 runlen = HLL_SPARSE_ZERO_LEN(p);
610 idx += runlen;
611 p++;
612 } else if (HLL_SPARSE_IS_XZERO(p)) {
613 runlen = HLL_SPARSE_XZERO_LEN(p);
614 idx += runlen;
615 p += 2;
616 } else {
617 runlen = HLL_SPARSE_VAL_LEN(p);
618 regval = HLL_SPARSE_VAL_VALUE(p);
619 if ((runlen + idx) > HLL_REGISTERS) break; /* Overflow. */
620 while(runlen--) {
621 HLL_DENSE_SET_REGISTER(hdr->registers(),idx,regval);
622 idx++;
623 }
624 p++;
625 }
626 }
627
628 /* If the sparse representation was valid, we expect to find idx
629 * set to HLL_REGISTERS. */
630 if (idx != HLL_REGISTERS) {
631 sdsfree(dense);
632 return C_ERR;
633 }
634
635 /* Free the old representation and set the new one. */
636 sdsfree(szFromObj(o));
637 o->m_ptr = dense;
638 return C_OK;
639}
640
641/* Low level function to set the sparse HLL register at 'index' to the
642 * specified value if the current value is smaller than 'count'.

Callers 3

hllSparseSetFunction · 0.85
pfmergeCommandFunction · 0.85
pfdebugCommandFunction · 0.85

Calls 5

szFromObjFunction · 0.85
sdslenFunction · 0.85
sdsnewlenFunction · 0.85
sdsfreeFunction · 0.85
registersMethod · 0.80

Tested by

no test coverage detected