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
| 654 | * not representable with the sparse representation, or when the resulting |
| 655 | * size would be greater than g_pserver->hll_sparse_max_bytes. */ |
| 656 | int 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 |
no test coverage detected