Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- 0a1,17
- > #include <assert.h>
- > #include <math.h>
- > #include <stddef.h>
- > #include <stdint.h>
- > #include <stdio.h>
- > #include <stdlib.h>
- > #include <string.h>
- >
- > #include "hyperloglog.h"
- >
- > #ifdef DEBUG
- > #define xprintf(fmt, ...) \
- > printf("FILE:<%s>,FUN:<%s>,LINE:<%d>," fmt "\n", __FILE__, __FUNCTION__, \
- > __LINE__, ##__VA_ARGS__)
- > #else
- > #define xprintf(fmt, ...)
- > #endif
- 1a19,23
- > #define xassert(X) \
- > if (!(X)) { \
- > xprintf(" (%s) assert fail!", #X); \
- > assert(0); \
- > }
- 3c25
- < #include "server.h"
- ---
- > enum { _Little_endian = 0, _Big_endian };
- 5,6c27,126
- < #include <math.h>
- < #include <stdint.h>
- ---
- > inline static int byte_order() {
- > union {
- > short a;
- > char b;
- > } w;
- >
- > w.a = 1;
- >
- > return (w.b == 1) ? _Little_endian : _Big_endian;
- > }
- >
- > const uint16_t hll_sparse_max_bytes = 3000;
- >
- > typedef struct sdshdr sdshdr;
- > typedef char *sds;
- >
- > struct __attribute__((__packed__)) sdshdr {
- > uint16_t len;
- > uint16_t alloc;
- > char buf[];
- > };
- >
- > #define sdsHdrSize sizeof(sdshdr)
- >
- > static inline size_t sdsavail(const sds s) {
- > sdshdr *sh = (sdshdr *)(s - sdsHdrSize);
- > return (sh->alloc - sh->len);
- > }
- >
- > static inline void sdssetlen(void *ptr, size_t len) {
- > sds s = (sds)ptr;
- > sdshdr *sh = (sdshdr *)(s - sdsHdrSize);
- > sh->len = len;
- > }
- >
- > static inline void sdssetalloc(void *ptr, size_t len) {
- > sds s = (sds)ptr;
- > sdshdr *sh = (sdshdr *)(s - sdsHdrSize);
- > sh->alloc = len;
- > }
- >
- > static inline size_t sdslen(const void *ptr) {
- > sds s = (sds)ptr;
- > sdshdr *sh = (sdshdr *)(s - sdsHdrSize);
- > return sh->len;
- > }
- >
- > static inline void sdsIncrLen(void *ptr, int inc) {
- > sds s = (sds)ptr;
- > sdshdr *sh = (sdshdr *)(s - sdsHdrSize);
- > sh->len += inc;
- > }
- >
- > sds sdsnewlen(const void *init, size_t initlen) {
- > sdshdr *sh = (sdshdr *)calloc(sdsHdrSize + initlen + 1, 1);
- > sds s = (char *)sh + sdsHdrSize;
- > if (init) {
- > memcpy(s, init, initlen);
- > }
- > sh->alloc = initlen;
- > sh->len = initlen;
- > s[initlen] = '\0';
- > return s;
- > }
- >
- > void sdsfree(void *s) {
- > if (s == NULL) return;
- > free(((char *)s - sdsHdrSize));
- > }
- >
- > sds sdsMakeRoomFor(void *ptr, size_t addlen) {
- > void *sh, *newsh;
- > sds s = (sds)ptr;
- > size_t avail = sdsavail(s);
- > size_t len = sdslen(s);
- > size_t newlen = len + addlen;
- >
- > if (avail >= addlen || len >= hll_sparse_max_bytes) {
- > return s;
- > }
- >
- > if (newlen * 2 < (hll_sparse_max_bytes / 4 * 3)) {
- > newlen *= 2;
- > } else {
- > newlen = hll_sparse_max_bytes;
- > }
- >
- > sh = (char *)s - sdsHdrSize;
- > newsh = realloc(sh, sdsHdrSize + newlen + 1);
- >
- > if (!newsh) {
- > return NULL;
- > }
- >
- > s = (char *)newsh + sdsHdrSize;
- > sdssetlen(s, len);
- > sdssetalloc(s, newlen);
- >
- > return ((char *)newsh + sdsHdrSize);
- > }
- 32c154
- < static char *invalid_hll_err = "-INVALIDOBJ Corrupted HLL object detected";
- ---
- > static char *invalid_hll_err = "-INVALIDOBJ Corrupted HLL object detected\r\n";
- 97,112c234,245
- < #if (BYTE_ORDER == LITTLE_ENDIAN)
- < #ifdef USE_ALIGNED_ACCESS
- < memcpy(&k, data, sizeof(uint64_t));
- < #else
- < k = *((uint64_t *)data);
- < #endif
- < #else
- < k = (uint64_t)data[0];
- < k |= (uint64_t)data[1] << 8;
- < k |= (uint64_t)data[2] << 16;
- < k |= (uint64_t)data[3] << 24;
- < k |= (uint64_t)data[4] << 32;
- < k |= (uint64_t)data[5] << 40;
- < k |= (uint64_t)data[6] << 48;
- < k |= (uint64_t)data[7] << 56;
- < #endif
- ---
- > if (byte_order() == _Little_endian) {
- > k = *((uint64_t *)data);
- > } else {
- > k = (uint64_t)data[0];
- > k |= (uint64_t)data[1] << 8;
- > k |= (uint64_t)data[2] << 16;
- > k |= (uint64_t)data[3] << 24;
- > k |= (uint64_t)data[4] << 32;
- > k |= (uint64_t)data[5] << 40;
- > k |= (uint64_t)data[6] << 48;
- > k |= (uint64_t)data[7] << 56;
- > }
- 146c279
- < int hllPatLen(unsigned char *ele, size_t elesize, long *regp) {
- ---
- > int hllPatLen(const unsigned char *ele, size_t elesize, long *regp) {
- 176c309
- < int hllDenseAdd(uint8_t *registers, unsigned char *ele, size_t elesize) {
- ---
- > int hllDenseAdd(uint8_t *registers, const unsigned char *ele, size_t elesize) {
- 236,238c369,375
- < int hllSparseToDense(robj *o) {
- < sds sparse = o->ptr, dense;
- < struct hllhdr *hdr, *oldhdr = (struct hllhdr *)sparse;
- ---
- > hllhdr *hllSparseToDense(hllhdr *ptr) {
- > if (!ptr) {
- > return NULL;
- > }
- >
- > sds sparse = (sds)ptr;
- > hllhdr *hdr = NULL;
- 242,243c379
- < hdr = (struct hllhdr *)sparse;
- < if (hdr->encoding == HLL_DENSE) return C_OK;
- ---
- > if (ptr->encoding == HLL_DENSE) return ptr;
- 245,247c381,383
- < dense = sdsnewlen(NULL, HLL_DENSE_SIZE);
- < hdr = (struct hllhdr *)dense;
- < *hdr = *oldhdr;
- ---
- > hdr = (hllhdr *)sdsnewlen(NULL, HLL_DENSE_SIZE);
- >
- > *hdr = *ptr;
- 260c396,398
- < } else {
- ---
- > }
- >
- > else {
- 273,274c410,411
- < sdsfree(dense);
- < return C_ERR;
- ---
- > sdsfree(hdr);
- > return NULL;
- 277,279c414,415
- < sdsfree(o->ptr);
- < o->ptr = dense;
- < return C_OK;
- ---
- > sdsfree(ptr);
- > return hdr;
- 282,283c418,419
- < int hllSparseSet(robj *o, long index, uint8_t count) {
- < struct hllhdr *hdr;
- ---
- > int hllSparseSet(hllhdr **ptr, long index, uint8_t count) {
- > hllhdr *hdr = *ptr;
- 290c426
- < o->ptr = sdsMakeRoomFor(o->ptr, 3);
- ---
- > hdr = (hllhdr *)sdsMakeRoomFor(hdr, 3);
- 292,293c428,434
- < sparse = p = ((uint8_t *)o->ptr) + HLL_HDR_SIZE;
- < end = p + sdslen(o->ptr) - HLL_HDR_SIZE;
- ---
- > if (!hdr) {
- > xprintf("memory rellac error: %s!", sterrror(errno));
- > return -1;
- > }
- >
- > sparse = p = ((uint8_t *)hdr) + HLL_HDR_SIZE;
- > end = p + sdslen(hdr) - HLL_HDR_SIZE;
- 317c458
- < if (span == 0 || p >= end) return -1;
- ---
- > if (span == 0) return -1;
- 319c460
- < next = HLL_SPARSE_IS_XZERO(p) ? p + 2 : p + 1;
- ---
- > next = HLL_SPARSE_IS_XZERO(p) ? (p + 2) : (p + 1);
- 397c537
- < if (deltalen > 0 && sdslen(o->ptr) + deltalen > server.hll_sparse_max_bytes)
- ---
- > if (deltalen > 0 && sdslen(hdr) + deltalen > hll_sparse_max_bytes)
- 400c540
- < sdsIncrLen(o->ptr, deltalen);
- ---
- > sdsIncrLen(hdr, deltalen);
- 425c564
- < sdsIncrLen(o->ptr, -1);
- ---
- > sdsIncrLen(hdr, -1);
- 435d572
- < hdr = o->ptr;
- 436a574
- > *ptr = hdr;
- 440,441c578
- < if (hllSparseToDense(o) == C_ERR) return -1;
- < hdr = o->ptr;
- ---
- > if ((hdr = hllSparseToDense(hdr)) == NULL) return -1;
- 444c581,582
- < serverAssert(dense_retval == 1);
- ---
- > assert(dense_retval == 1);
- > *ptr = hdr;
- 448c586
- < int hllSparseAdd(robj *o, unsigned char *ele, size_t elesize) {
- ---
- > int hllSparseAdd(hllhdr **ptr, const unsigned char *ele, size_t elesize) {
- 451,452c589
- <
- < return hllSparseSet(o, index, count);
- ---
- > return hllSparseSet(ptr, index, count);
- 548c685,686
- < serverPanic("Unknown HyperLogLog encoding in hllCount()");
- ---
- > *invalid = 1;
- > return 0;
- 562,568c700,711
- < int hllAdd(robj *o, unsigned char *ele, size_t elesize) {
- < struct hllhdr *hdr = o->ptr;
- < switch (hdr->encoding) {
- < case HLL_DENSE:
- < return hllDenseAdd(hdr->registers, ele, elesize);
- < case HLL_SPARSE:
- < return hllSparseAdd(o, ele, elesize);
- ---
- > int hllAdd(hllhdr **ptr, const unsigned char *ele, size_t elesize) {
- > switch ((*ptr)->encoding) {
- > case HLL_DENSE: {
- > if (hllDenseAdd((*ptr)->registers, ele, elesize)) {
- > HLL_INVALIDATE_CACHE(*ptr);
- > return 1;
- > }
- > return 0;
- > }
- > case HLL_SPARSE: {
- > return hllSparseAdd(ptr, ele, elesize);
- > }
- 574,575c717
- < int hllMerge(uint8_t *max, robj *hll) {
- < struct hllhdr *hdr = hll->ptr;
- ---
- > int hllMerge(uint8_t *max, hllhdr *ptr) {
- 578c720
- < if (hdr->encoding == HLL_DENSE) {
- ---
- > if (ptr->encoding == HLL_DENSE) {
- 582c724
- < HLL_DENSE_GET_REGISTER(val, hdr->registers, i);
- ---
- > HLL_DENSE_GET_REGISTER(val, ptr->registers, i);
- 586c728
- < uint8_t *p = hll->ptr, *end = p + sdslen(hll->ptr);
- ---
- > uint8_t *p = (uint8_t *)ptr, *end = p + sdslen(ptr);
- 611c753
- < if (i != HLL_REGISTERS) return C_ERR;
- ---
- > if (i != HLL_REGISTERS) return -1;
- 613c755
- < return C_OK;
- ---
- > return 0;
- 616,617c758,760
- < robj *createHLLObject(void) {
- < robj *o;
- ---
- > void deleteHLLObject(hllhdr *hdr) { sdsfree(hdr); }
- >
- > hllhdr *createHLLObject(void) {
- 628a773
- > hdr = (hllhdr *)s;
- 637c782
- < serverAssert((p - (uint8_t *)s) == sparselen);
- ---
- > assert((p - (uint8_t *)s) == sparselen);
- 639,641c784
- < o = createObject(OBJ_STRING, s);
- < hdr = o->ptr;
- < memcpy(hdr->magic, "HYLL", 4);
- ---
- > memcpy(hdr->magic, hll_magic_char, 4);
- 643c786
- < return o;
- ---
- > return hdr;
- 646c789
- < int isHLLObjectOrReply(client *c, robj *o) {
- ---
- > int isHLLObjectOrReply(void *ptr) {
- 649,653c792
- < if (checkType(c, o, OBJ_STRING)) return C_ERR;
- <
- < if (!sdsEncodedObject(o)) goto invalid;
- < if (stringObjectLen(o) < sizeof(*hdr)) goto invalid;
- < hdr = o->ptr;
- ---
- > hdr = ptr;
- 661,662c800
- < if (hdr->encoding == HLL_DENSE && stringObjectLen(o) != HLL_DENSE_SIZE)
- < goto invalid;
- ---
- > if (hdr->encoding == HLL_DENSE && sdslen(ptr) != HLL_DENSE_SIZE) goto invalid;
- 664c802
- < return C_OK;
- ---
- > return 0;
- 667,670c805
- < addReplyError(c,
- < "-WRONGTYPE Key is not a valid "
- < "HyperLogLog string value.");
- < return C_ERR;
- ---
- > return -1;
- 673,684c808,810
- < void pfaddCommand(client *c) {
- < robj *o = lookupKeyWrite(c->db, c->argv[1]);
- < struct hllhdr *hdr;
- < int updated = 0, j;
- <
- < if (o == NULL) {
- < o = createHLLObject();
- < dbAdd(c->db, c->argv[1], o);
- < updated++;
- < } else {
- < if (isHLLObjectOrReply(c, o) != C_OK) return;
- < o = dbUnshareStringValue(c->db, c->argv[1], o);
- ---
- > int pfaddCommand(hllhdr **ptr, const unsigned char *key, int len) {
- > if (!ptr || !*ptr || !key) {
- > return -1;
- 687,706c813,814
- < for (j = 2; j < c->argc; j++) {
- < int retval =
- < hllAdd(o, (unsigned char *)c->argv[j]->ptr, sdslen(c->argv[j]->ptr));
- < switch (retval) {
- < case 1:
- < updated++;
- < break;
- < case -1:
- < addReplyError(c, invalid_hll_err);
- < return;
- < }
- < }
- < hdr = o->ptr;
- < if (updated) {
- < signalModifiedKey(c, c->db, c->argv[1]);
- < notifyKeyspaceEvent(NOTIFY_STRING, "pfadd", c->argv[1], c->db->id);
- < server.dirty += updated;
- < HLL_INVALIDATE_CACHE(hdr);
- < }
- < addReply(c, updated ? shared.cone : shared.czero);
- ---
- > len = (len > 0) ? len : strlen(key);
- > return hllAdd(ptr, key, len);
- 709,711c817
- < void pfcountCommand(client *c) {
- < robj *o;
- < struct hllhdr *hdr;
- ---
- > int pfcountCommand(hllhdr *hdr, uint64_t *ret) {
- 713,739c819,827
- <
- < if (c->argc > 2) {
- < uint8_t max[HLL_HDR_SIZE + HLL_REGISTERS], *registers;
- < int j;
- <
- < memset(max, 0, sizeof(max));
- < hdr = (struct hllhdr *)max;
- < hdr->encoding = HLL_RAW;
- < registers = max + HLL_HDR_SIZE;
- < for (j = 1; j < c->argc; j++) {
- < robj *o = lookupKeyRead(c->db, c->argv[j]);
- < if (o == NULL) continue;
- < if (isHLLObjectOrReply(c, o) != C_OK) return;
- <
- < if (hllMerge(registers, o) == C_ERR) {
- < addReplyError(c, invalid_hll_err);
- < return;
- < }
- < }
- <
- < addReplyLongLong(c, hllCount(hdr, NULL));
- < return;
- < }
- <
- < o = lookupKeyWrite(c->db, c->argv[1]);
- < if (o == NULL) {
- < addReply(c, shared.czero);
- ---
- > if (HLL_VALID_CACHE(hdr)) {
- > card = (uint64_t)hdr->card[0];
- > card |= (uint64_t)hdr->card[1] << 8;
- > card |= (uint64_t)hdr->card[2] << 16;
- > card |= (uint64_t)hdr->card[3] << 24;
- > card |= (uint64_t)hdr->card[4] << 32;
- > card |= (uint64_t)hdr->card[5] << 40;
- > card |= (uint64_t)hdr->card[6] << 48;
- > card |= (uint64_t)hdr->card[7] << 56;
- 741,772c829,832
- < if (isHLLObjectOrReply(c, o) != C_OK) return;
- < o = dbUnshareStringValue(c->db, c->argv[1], o);
- <
- < hdr = o->ptr;
- < if (HLL_VALID_CACHE(hdr)) {
- < card = (uint64_t)hdr->card[0];
- < card |= (uint64_t)hdr->card[1] << 8;
- < card |= (uint64_t)hdr->card[2] << 16;
- < card |= (uint64_t)hdr->card[3] << 24;
- < card |= (uint64_t)hdr->card[4] << 32;
- < card |= (uint64_t)hdr->card[5] << 40;
- < card |= (uint64_t)hdr->card[6] << 48;
- < card |= (uint64_t)hdr->card[7] << 56;
- < } else {
- < int invalid = 0;
- <
- < card = hllCount(hdr, &invalid);
- < if (invalid) {
- < addReplyError(c, invalid_hll_err);
- < return;
- < }
- < hdr->card[0] = card & 0xff;
- < hdr->card[1] = (card >> 8) & 0xff;
- < hdr->card[2] = (card >> 16) & 0xff;
- < hdr->card[3] = (card >> 24) & 0xff;
- < hdr->card[4] = (card >> 32) & 0xff;
- < hdr->card[5] = (card >> 40) & 0xff;
- < hdr->card[6] = (card >> 48) & 0xff;
- < hdr->card[7] = (card >> 56) & 0xff;
- <
- < signalModifiedKey(c, c->db, c->argv[1]);
- < server.dirty++;
- ---
- > int invalid = 0;
- > card = hllCount(hdr, &invalid);
- > if (invalid) {
- > return -1;
- 774c834,841
- < addReplyLongLong(c, card);
- ---
- > hdr->card[0] = card & 0xff;
- > hdr->card[1] = (card >> 8) & 0xff;
- > hdr->card[2] = (card >> 16) & 0xff;
- > hdr->card[3] = (card >> 24) & 0xff;
- > hdr->card[4] = (card >> 32) & 0xff;
- > hdr->card[5] = (card >> 40) & 0xff;
- > hdr->card[6] = (card >> 48) & 0xff;
- > hdr->card[7] = (card >> 56) & 0xff;
- 775a843,845
- >
- > *ret = card;
- > return 0;
- 778c848
- < void pfmergeCommand(client *c) {
- ---
- > int pfmergeCommand(hllhdr **hdr, hllhdr *src) {
- 780d849
- < struct hllhdr *hdr;
- 784,822c853,854
- < memset(max, 0, sizeof(max));
- < for (j = 1; j < c->argc; j++) {
- < robj *o = lookupKeyRead(c->db, c->argv[j]);
- < if (o == NULL) continue;
- < if (isHLLObjectOrReply(c, o) != C_OK) return;
- <
- < hdr = o->ptr;
- < if (hdr->encoding == HLL_DENSE) use_dense = 1;
- <
- < if (hllMerge(max, o) == C_ERR) {
- < addReplyError(c, invalid_hll_err);
- < return;
- < }
- < }
- <
- < robj *o = lookupKeyWrite(c->db, c->argv[1]);
- < if (o == NULL) {
- < o = createHLLObject();
- < dbAdd(c->db, c->argv[1], o);
- < } else {
- < o = dbUnshareStringValue(c->db, c->argv[1], o);
- < }
- <
- < if (use_dense && hllSparseToDense(o) == C_ERR) {
- < addReplyError(c, invalid_hll_err);
- < return;
- < }
- <
- < for (j = 0; j < HLL_REGISTERS; j++) {
- < if (max[j] == 0) continue;
- < hdr = o->ptr;
- < switch (hdr->encoding) {
- < case HLL_DENSE:
- < hllDenseSet(hdr->registers, j, max[j]);
- < break;
- < case HLL_SPARSE:
- < hllSparseSet(o, j, max[j]);
- < break;
- < }
- ---
- > if (!hdr || !*hdr || !src) {
- > return -1;
- 824,825d855
- < hdr = o->ptr;
- < HLL_INVALIDATE_CACHE(hdr);
- 827,980c857
- < signalModifiedKey(c, c->db, c->argv[1]);
- <
- < notifyKeyspaceEvent(NOTIFY_STRING, "pfadd", c->argv[1], c->db->id);
- < server.dirty++;
- < addReply(c, shared.ok);
- < }
- <
- < #define HLL_TEST_CYCLES 1000
- < void pfselftestCommand(client *c) {
- < unsigned int j, i;
- < sds bitcounters = sdsnewlen(NULL, HLL_DENSE_SIZE);
- < struct hllhdr *hdr = (struct hllhdr *)bitcounters, *hdr2;
- < robj *o = NULL;
- < uint8_t bytecounters[HLL_REGISTERS];
- <
- < for (j = 0; j < HLL_TEST_CYCLES; j++) {
- < for (i = 0; i < HLL_REGISTERS; i++) {
- < unsigned int r = rand() & HLL_REGISTER_MAX;
- <
- < bytecounters[i] = r;
- < HLL_DENSE_SET_REGISTER(hdr->registers, i, r);
- < }
- <
- < for (i = 0; i < HLL_REGISTERS; i++) {
- < unsigned int val;
- <
- < HLL_DENSE_GET_REGISTER(val, hdr->registers, i);
- < if (val != bytecounters[i]) {
- < addReplyErrorFormat(c, "TESTFAILED Register %d should be %d but is %d",
- < i, (int)bytecounters[i], (int)val);
- < goto cleanup;
- < }
- < }
- < }
- <
- < memset(hdr->registers, 0, HLL_DENSE_SIZE - HLL_HDR_SIZE);
- < o = createHLLObject();
- < double relerr = 1.04 / sqrt(HLL_REGISTERS);
- < int64_t checkpoint = 1;
- < uint64_t seed = (uint64_t)rand() | (uint64_t)rand() << 32;
- < uint64_t ele;
- < for (j = 1; j <= 10000000; j++) {
- < ele = j ^ seed;
- < hllDenseAdd(hdr->registers, (unsigned char *)&ele, sizeof(ele));
- < hllAdd(o, (unsigned char *)&ele, sizeof(ele));
- <
- < if (j == checkpoint && j < server.hll_sparse_max_bytes / 2) {
- < hdr2 = o->ptr;
- < if (hdr2->encoding != HLL_SPARSE) {
- < addReplyError(c, "TESTFAILED sparse encoding not used");
- < goto cleanup;
- < }
- < }
- <
- < if (j == checkpoint && hllCount(hdr, NULL) != hllCount(o->ptr, NULL)) {
- < addReplyError(c, "TESTFAILED dense/sparse disagree");
- < goto cleanup;
- < }
- <
- < if (j == checkpoint) {
- < int64_t abserr = checkpoint - (int64_t)hllCount(hdr, NULL);
- < uint64_t maxerr = ceil(relerr * 6 * checkpoint);
- <
- < if (j == 10) maxerr = 1;
- <
- < if (abserr < 0) abserr = -abserr;
- < if (abserr > (int64_t)maxerr) {
- < addReplyErrorFormat(
- < c, "TESTFAILED Too big error. card:%llu abserr:%llu",
- < (unsigned long long)checkpoint, (unsigned long long)abserr);
- < goto cleanup;
- < }
- < checkpoint *= 10;
- < }
- < }
- <
- < addReply(c, shared.ok);
- <
- < cleanup:
- < sdsfree(bitcounters);
- < if (o) decrRefCount(o);
- < }
- <
- < void pfdebugCommand(client *c) {
- < char *cmd = c->argv[1]->ptr;
- < struct hllhdr *hdr;
- < robj *o;
- < int j;
- <
- < o = lookupKeyWrite(c->db, c->argv[2]);
- < if (o == NULL) {
- < addReplyError(c, "The specified key does not exist");
- < return;
- < }
- < if (isHLLObjectOrReply(c, o) != C_OK) return;
- < o = dbUnshareStringValue(c->db, c->argv[2], o);
- < hdr = o->ptr;
- <
- < if (!strcasecmp(cmd, "getreg")) {
- < if (c->argc != 3) goto arityerr;
- <
- < if (hdr->encoding == HLL_SPARSE) {
- < if (hllSparseToDense(o) == C_ERR) {
- < addReplyError(c, invalid_hll_err);
- < return;
- < }
- < server.dirty++;
- < }
- <
- < hdr = o->ptr;
- < addReplyArrayLen(c, HLL_REGISTERS);
- < for (j = 0; j < HLL_REGISTERS; j++) {
- < uint8_t val;
- <
- < HLL_DENSE_GET_REGISTER(val, hdr->registers, j);
- < addReplyLongLong(c, val);
- < }
- < }
- <
- < else if (!strcasecmp(cmd, "decode")) {
- < if (c->argc != 3) goto arityerr;
- <
- < uint8_t *p = o->ptr, *end = p + sdslen(o->ptr);
- < sds decoded = sdsempty();
- <
- < if (hdr->encoding != HLL_SPARSE) {
- < sdsfree(decoded);
- < addReplyError(c, "HLL encoding is not sparse");
- < return;
- < }
- <
- < p += HLL_HDR_SIZE;
- < while (p < end) {
- < int runlen, regval;
- <
- < if (HLL_SPARSE_IS_ZERO(p)) {
- < runlen = HLL_SPARSE_ZERO_LEN(p);
- < p++;
- < decoded = sdscatprintf(decoded, "z:%d ", runlen);
- < } else if (HLL_SPARSE_IS_XZERO(p)) {
- < runlen = HLL_SPARSE_XZERO_LEN(p);
- < p += 2;
- < decoded = sdscatprintf(decoded, "Z:%d ", runlen);
- < } else {
- < runlen = HLL_SPARSE_VAL_LEN(p);
- < regval = HLL_SPARSE_VAL_VALUE(p);
- < p++;
- < decoded = sdscatprintf(decoded, "v:%d,%d ", regval, runlen);
- < }
- < }
- < decoded = sdstrim(decoded, " ");
- < addReplyBulkCBuffer(c, decoded, sdslen(decoded));
- < sdsfree(decoded);
- < }
- ---
- > memset(max, 0, sizeof(max));
- 982,984c859
- < else if (!strcasecmp(cmd, "encoding")) {
- < char *encodingstr[2] = {"dense", "sparse"};
- < if (c->argc != 3) goto arityerr;
- ---
- > if ((*hdr)->encoding == HLL_DENSE) use_dense = 1;
- 986c861,862
- < addReplyStatus(c, encodingstr[hdr->encoding]);
- ---
- > if (hllMerge(max, src)) {
- > return -1;
- 989,999c865,869
- < else if (!strcasecmp(cmd, "todense")) {
- < int conv = 0;
- < if (c->argc != 3) goto arityerr;
- <
- < if (hdr->encoding == HLL_SPARSE) {
- < if (hllSparseToDense(o) == C_ERR) {
- < addReplyError(c, invalid_hll_err);
- < return;
- < }
- < conv = 1;
- < server.dirty++;
- ---
- > for (j = 0; j < HLL_REGISTERS; j++) {
- > if (use_dense) {
- > hllDenseSet((*hdr)->registers, j, max[j]);
- > } else {
- > hllSparseSet(hdr, j, max[j]);
- 1001,1003d870
- < addReply(c, conv ? shared.cone : shared.czero);
- < } else {
- < addReplyErrorFormat(c, "Unknown PFDEBUG subcommand '%s'", cmd);
- 1005d871
- < return;
- 1007,1009c873,874
- < arityerr:
- < addReplyErrorFormat(c, "Wrong number of arguments for the '%s' subcommand",
- < cmd);
- ---
- > HLL_INVALIDATE_CACHE(*hdr);
- > return 0;
Advertisement
Add Comment
Please, Sign In to add comment