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

Function hllSparseSet

src/hyperloglog.cpp:656–903  ·  view source on GitHub ↗

Low level function to set the sparse HLL register at 'index' to the * specified value if the current value is smaller than 'count'. * * The object 'o' is the String object holding the HLL. The function requires * a reference to the object in order to be able to enlarge the string if * needed. * * On success, the function returns 1 if the cardinality changed, or 0 * if the register for this

Source from the content-addressed store, hash-verified

654 * not representable with the sparse representation, or when the resulting
655 * size would be greater than g_pserver->hll_sparse_max_bytes. */
656int hllSparseSet(robj *o, long index, uint8_t count) {
657 struct hllhdr *hdr;
658 uint8_t oldcount, *sparse, *end, *p, *prev, *next;
659 long first, span;
660 long is_zero = 0, is_xzero = 0, is_val = 0, runlen = 0;
661 uint8_t seq[5], *n = nullptr;
662 int last;
663 int len;
664 int seqlen = 0;
665 int oldlen = 0;
666 int deltalen = 0;
667 int scanlen = 0;
668
669 /* If the count is too big to be representable by the sparse representation
670 * switch to dense representation. */
671 if (count > HLL_SPARSE_VAL_MAX_VALUE) goto promote;
672
673 /* When updating a sparse representation, sometimes we may need to
674 * enlarge the buffer for up to 3 bytes in the worst case (XZERO split
675 * into XZERO-VAL-XZERO). Make sure there is enough space right now
676 * so that the pointers we take during the execution of the function
677 * will be valid all the time. */
678 o->m_ptr = sdsMakeRoomFor(szFromObj(o),3);
679
680 /* Step 1: we need to locate the opcode we need to modify to check
681 * if a value update is actually needed. */
682 sparse = p = ((uint8_t*)ptrFromObj(o)) + HLL_HDR_SIZE;
683 end = p + sdslen(szFromObj(o)) - HLL_HDR_SIZE;
684
685 first = 0;
686 prev = NULL; /* Points to previous opcode at the end of the loop. */
687 next = NULL; /* Points to the next opcode at the end of the loop. */
688 span = 0;
689 while(p < end) {
690 long oplen;
691
692 /* Set span to the number of registers covered by this opcode.
693 *
694 * This is the most performance critical loop of the sparse
695 * representation. Sorting the conditionals from the most to the
696 * least frequent opcode in many-bytes sparse HLLs is faster. */
697 oplen = 1;
698 if (HLL_SPARSE_IS_ZERO(p)) {
699 span = HLL_SPARSE_ZERO_LEN(p);
700 } else if (HLL_SPARSE_IS_VAL(p)) {
701 span = HLL_SPARSE_VAL_LEN(p);
702 } else { /* XZERO. */
703 span = HLL_SPARSE_XZERO_LEN(p);
704 oplen = 2;
705 }
706 /* Break if this opcode covers the register as 'index'. */
707 if (index <= first+span-1) break;
708 prev = p;
709 p += oplen;
710 first += span;
711 }
712 if (span == 0 || p >= end) return -1; /* Invalid format. */
713

Callers 2

hllSparseAddFunction · 0.85
pfmergeCommandFunction · 0.85

Calls 8

sdsMakeRoomForFunction · 0.85
szFromObjFunction · 0.85
ptrFromObjFunction · 0.85
sdslenFunction · 0.85
sdsIncrLenFunction · 0.85
hllSparseToDenseFunction · 0.85
hllDenseSetFunction · 0.85
registersMethod · 0.80

Tested by

no test coverage detected