Merge by computing MAX(registers[i],hll[i]) the HyperLogLog 'hll' * with an array of uint8_t HLL_REGISTERS registers pointed by 'max'. * * The hll object must be already validated via isHLLObjectOrReply() * or in some other way. * * If the HyperLogLog is sparse and is found to be invalid, C_ERR * is returned, otherwise the function always succeeds. */
| 1066 | * If the HyperLogLog is sparse and is found to be invalid, C_ERR |
| 1067 | * is returned, otherwise the function always succeeds. */ |
| 1068 | int hllMerge(uint8_t *max, robj *hll) { |
| 1069 | struct hllhdr *hdr = hll->ptr; |
| 1070 | int i; |
| 1071 | |
| 1072 | if (hdr->encoding == HLL_DENSE) { |
| 1073 | uint8_t val; |
| 1074 | |
| 1075 | for (i = 0; i < HLL_REGISTERS; i++) { |
| 1076 | HLL_DENSE_GET_REGISTER(val,hdr->registers,i); |
| 1077 | if (val > max[i]) max[i] = val; |
| 1078 | } |
| 1079 | } else { |
| 1080 | uint8_t *p = hll->ptr, *end = p + sdslen(hll->ptr); |
| 1081 | long runlen, regval; |
| 1082 | |
| 1083 | p += HLL_HDR_SIZE; |
| 1084 | i = 0; |
| 1085 | while(p < end) { |
| 1086 | if (HLL_SPARSE_IS_ZERO(p)) { |
| 1087 | runlen = HLL_SPARSE_ZERO_LEN(p); |
| 1088 | i += runlen; |
| 1089 | p++; |
| 1090 | } else if (HLL_SPARSE_IS_XZERO(p)) { |
| 1091 | runlen = HLL_SPARSE_XZERO_LEN(p); |
| 1092 | i += runlen; |
| 1093 | p += 2; |
| 1094 | } else { |
| 1095 | runlen = HLL_SPARSE_VAL_LEN(p); |
| 1096 | regval = HLL_SPARSE_VAL_VALUE(p); |
| 1097 | if ((runlen + i) > HLL_REGISTERS) break; /* Overflow. */ |
| 1098 | while(runlen--) { |
| 1099 | if (regval > max[i]) max[i] = regval; |
| 1100 | i++; |
| 1101 | } |
| 1102 | p++; |
| 1103 | } |
| 1104 | } |
| 1105 | if (i != HLL_REGISTERS) return C_ERR; |
| 1106 | } |
| 1107 | return C_OK; |
| 1108 | } |
| 1109 | |
| 1110 | /* ========================== HyperLogLog commands ========================== */ |
| 1111 |
no test coverage detected