From aaaed66c566910277fddd35a345dea6664c8e646 Mon Sep 17 00:00:00 2001 From: antirez Date: Thu, 3 Apr 2014 10:45:30 +0200 Subject: [PATCH] PFGETREG added for testing purposes. The new command allows to get a dump of the registers stored into an HyperLogLog data structure for testing / debugging purposes. --- src/hyperloglog.c | 40 +++++++++++++++++++++++++++++++++++++++- src/redis.c | 3 ++- src/redis.h | 1 + 3 files changed, 42 insertions(+), 2 deletions(-) diff --git a/src/hyperloglog.c b/src/hyperloglog.c index 7fad34d5b..e3621ac95 100644 --- a/src/hyperloglog.c +++ b/src/hyperloglog.c @@ -630,7 +630,10 @@ void pfmergeCommand(redisClient *c) { addReply(c,shared.ok); } -/* This command performs a self-test of the HLL registers implementation. +/* ========================== Testing / Debugging ========================== */ + +/* PFSELFTEST + * This command performs a self-test of the HLL registers implementation. * Something that is not easy to test from within the outside. */ #define REDIS_HLL_TEST_CYCLES 1000 void pfselftestCommand(redisClient *c) { @@ -701,3 +704,38 @@ void pfselftestCommand(redisClient *c) { cleanup: sdsfree(bitcounters); } + +/* PFGETREG + * Return the registers values of the specified HLL. */ +void pfgetregCommand(redisClient *c) { + robj *o = lookupKeyRead(c->db,c->argv[1]); + uint8_t *registers; + int j; + + if (o == NULL) { + addReplyError(c,"The specified key does not exist"); + return; + } else { + /* Key exists, check type */ + if (checkType(c,o,REDIS_STRING)) + return; + + /* If this is a string representing an HLL, the size should match + * exactly. */ + if (stringObjectLen(o) != REDIS_HLL_SIZE) { + addReplyErrorFormat(c, + "PFCOUNT target key must contain a %d bytes string.", + REDIS_HLL_SIZE); + return; + } + + registers = o->ptr; + addReplyMultiBulkLen(c,REDIS_HLL_REGISTERS); + for (j = 0; j < REDIS_HLL_REGISTERS; j++) { + uint8_t val; + + HLL_GET_REGISTER(val,registers,j); + addReplyLongLong(c,val); + } + } +} diff --git a/src/redis.c b/src/redis.c index 03268be79..f9853c4f8 100644 --- a/src/redis.c +++ b/src/redis.c @@ -271,7 +271,8 @@ struct redisCommand redisCommandTable[] = { {"pfselftest",pfselftestCommand,1,"r",0,NULL,0,0,0,0,0}, {"pfadd",pfaddCommand,-2,"wm",0,NULL,1,1,1,0,0}, {"pfcount",pfcountCommand,2,"w",0,NULL,1,1,1,0,0}, - {"pfmerge",pfmergeCommand,-2,"wm",0,NULL,1,-1,1,0,0} + {"pfmerge",pfmergeCommand,-2,"wm",0,NULL,1,-1,1,0,0}, + {"pfgetreg",pfgetregCommand,2,"r",0,NULL,0,0,0,0,0} }; struct evictionPoolEntry *evictionPoolAlloc(void); diff --git a/src/redis.h b/src/redis.h index 35345d388..e95b939e4 100644 --- a/src/redis.h +++ b/src/redis.h @@ -1452,6 +1452,7 @@ void pfselftestCommand(redisClient *c); void pfaddCommand(redisClient *c); void pfcountCommand(redisClient *c); void pfmergeCommand(redisClient *c); +void pfgetregCommand(redisClient *c); #if defined(__GNUC__) void *calloc(size_t count, size_t size) __attribute__ ((deprecated));