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