summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorantirez <antirez@gmail.com>2016-12-16 09:02:50 +0100
committerantirez <antirez@gmail.com>2016-12-16 09:02:50 +0100
commitac61f9062583d67dd43f7d698824464d1e30d84b (patch)
tree5d447b04cd69c0d408988c6ab7f7f7239ef5a97c /src
parentb53e73e159a38308c2873bfce7237b7373ef4374 (diff)
downloadredis-ac61f9062583d67dd43f7d698824464d1e30d84b.tar.gz
DEBUG: new "ziplist" subcommand added. Dumps a ziplist on stdout.
The commit improves ziplistRepr() and adds a new debugging subcommand so that we can trigger the dump directly from the Redis API. This command capability was used while investigating issue #3684.
Diffstat (limited to 'src')
-rw-r--r--src/debug.c14
-rw-r--r--src/server.h2
-rw-r--r--src/ziplist.c31
-rw-r--r--src/ziplist.h1
4 files changed, 35 insertions, 13 deletions
diff --git a/src/debug.c b/src/debug.c
index f4689d532..b8ad4e511 100644
--- a/src/debug.c
+++ b/src/debug.c
@@ -280,6 +280,8 @@ void debugCommand(client *c) {
blen++; addReplyStatus(c,
"sdslen <key> -- Show low level SDS string info representing key and value.");
blen++; addReplyStatus(c,
+ "ziplist <key> -- Show low level info about the ziplist encoding.");
+ blen++; addReplyStatus(c,
"populate <count> [prefix] -- Create <count> string keys named key:<num>. If a prefix is specified is used instead of the 'key' prefix.");
blen++; addReplyStatus(c,
"digest -- Outputs an hex signature representing the current DB content.");
@@ -418,6 +420,18 @@ void debugCommand(client *c) {
(long long) sdsavail(val->ptr),
(long long) getStringObjectSdsUsedMemory(val));
}
+ } else if (!strcasecmp(c->argv[1]->ptr,"ziplist") && c->argc == 3) {
+ robj *o;
+
+ if ((o = objectCommandLookupOrReply(c,c->argv[2],shared.nokeyerr))
+ == NULL) return;
+
+ if (o->encoding != OBJ_ENCODING_ZIPLIST) {
+ addReplyError(c,"Not an sds encoded string.");
+ } else {
+ ziplistRepr(o->ptr);
+ addReplyStatus(c,"Ziplist structure printed on stdout");
+ }
} else if (!strcasecmp(c->argv[1]->ptr,"populate") &&
(c->argc == 3 || c->argc == 4)) {
long keys, j;
diff --git a/src/server.h b/src/server.h
index 2a61ea419..7ff151de8 100644
--- a/src/server.h
+++ b/src/server.h
@@ -1655,6 +1655,8 @@ robj *lookupKeyWrite(redisDb *db, robj *key);
robj *lookupKeyReadOrReply(client *c, robj *key, robj *reply);
robj *lookupKeyWriteOrReply(client *c, robj *key, robj *reply);
robj *lookupKeyReadWithFlags(redisDb *db, robj *key, int flags);
+robj *objectCommandLookup(client *c, robj *key);
+robj *objectCommandLookupOrReply(client *c, robj *key, robj *reply);
#define LOOKUP_NONE 0
#define LOOKUP_NOTOUCH (1<<0)
void dbAdd(redisDb *db, robj *key, robj *val);
diff --git a/src/ziplist.c b/src/ziplist.c
index 7428d30e9..f7d7877f7 100644
--- a/src/ziplist.c
+++ b/src/ziplist.c
@@ -1029,7 +1029,7 @@ void ziplistRepr(unsigned char *zl) {
printf(
"{total bytes %d} "
- "{length %u}\n"
+ "{num entries %u}\n"
"{tail offset %u}\n",
intrev32ifbe(ZIPLIST_BYTES(zl)),
intrev16ifbe(ZIPLIST_LENGTH(zl)),
@@ -1038,16 +1038,15 @@ void ziplistRepr(unsigned char *zl) {
while(*p != ZIP_END) {
zipEntry(p, &entry);
printf(
- "{"
- "addr 0x%08lx, "
- "index %2d, "
- "offset %5ld, "
- "rl: %5u, "
- "hs %2u, "
- "pl: %5u, "
- "pls: %2u, "
- "payload %5u"
- "} ",
+ "{\n"
+ "\taddr 0x%08lx,\n"
+ "\tindex %2d,\n"
+ "\toffset %5ld,\n"
+ "\thdr+entry len: %5u,\n"
+ "\thdr len%2u,\n"
+ "\tprevrawlen: %5u,\n"
+ "\tprevrawlensize: %2u,\n"
+ "\tpayload %5u\n",
(long unsigned)p,
index,
(unsigned long) (p-zl),
@@ -1056,8 +1055,14 @@ void ziplistRepr(unsigned char *zl) {
entry.prevrawlen,
entry.prevrawlensize,
entry.len);
+ printf("\tbytes: ");
+ for (unsigned int i = 0; i < entry.headersize+entry.len; i++) {
+ printf("%02x|",p[i]);
+ }
+ printf("\n");
p += entry.headersize;
if (ZIP_IS_STR(entry.encoding)) {
+ printf("\t[str]");
if (entry.len > 40) {
if (fwrite(p,40,1,stdout) == 0) perror("fwrite");
printf("...");
@@ -1066,9 +1071,9 @@ void ziplistRepr(unsigned char *zl) {
fwrite(p,entry.len,1,stdout) == 0) perror("fwrite");
}
} else {
- printf("%lld", (long long) zipLoadInteger(p,entry.encoding));
+ printf("\t[int]%lld", (long long) zipLoadInteger(p,entry.encoding));
}
- printf("\n");
+ printf("\n}\n");
p += entry.len;
index++;
}
diff --git a/src/ziplist.h b/src/ziplist.h
index ae96823f9..964a47f6d 100644
--- a/src/ziplist.h
+++ b/src/ziplist.h
@@ -48,6 +48,7 @@ unsigned int ziplistCompare(unsigned char *p, unsigned char *s, unsigned int sle
unsigned char *ziplistFind(unsigned char *p, unsigned char *vstr, unsigned int vlen, unsigned int skip);
unsigned int ziplistLen(unsigned char *zl);
size_t ziplistBlobLen(unsigned char *zl);
+void ziplistRepr(unsigned char *zl);
#ifdef REDIS_TEST
int ziplistTest(int argc, char *argv[]);