mirror of
https://github.com/fluencelabs/redis
synced 2025-04-02 15:51:05 +00:00
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.
This commit is contained in:
parent
b53e73e159
commit
ac61f90625
14
src/debug.c
14
src/debug.c
@ -280,6 +280,8 @@ void debugCommand(client *c) {
|
|||||||
blen++; addReplyStatus(c,
|
blen++; addReplyStatus(c,
|
||||||
"sdslen <key> -- Show low level SDS string info representing key and value.");
|
"sdslen <key> -- Show low level SDS string info representing key and value.");
|
||||||
blen++; addReplyStatus(c,
|
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.");
|
"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,
|
blen++; addReplyStatus(c,
|
||||||
"digest -- Outputs an hex signature representing the current DB content.");
|
"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) sdsavail(val->ptr),
|
||||||
(long long) getStringObjectSdsUsedMemory(val));
|
(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") &&
|
} else if (!strcasecmp(c->argv[1]->ptr,"populate") &&
|
||||||
(c->argc == 3 || c->argc == 4)) {
|
(c->argc == 3 || c->argc == 4)) {
|
||||||
long keys, j;
|
long keys, j;
|
||||||
|
@ -1655,6 +1655,8 @@ robj *lookupKeyWrite(redisDb *db, robj *key);
|
|||||||
robj *lookupKeyReadOrReply(client *c, robj *key, robj *reply);
|
robj *lookupKeyReadOrReply(client *c, robj *key, robj *reply);
|
||||||
robj *lookupKeyWriteOrReply(client *c, robj *key, robj *reply);
|
robj *lookupKeyWriteOrReply(client *c, robj *key, robj *reply);
|
||||||
robj *lookupKeyReadWithFlags(redisDb *db, robj *key, int flags);
|
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_NONE 0
|
||||||
#define LOOKUP_NOTOUCH (1<<0)
|
#define LOOKUP_NOTOUCH (1<<0)
|
||||||
void dbAdd(redisDb *db, robj *key, robj *val);
|
void dbAdd(redisDb *db, robj *key, robj *val);
|
||||||
|
@ -1029,7 +1029,7 @@ void ziplistRepr(unsigned char *zl) {
|
|||||||
|
|
||||||
printf(
|
printf(
|
||||||
"{total bytes %d} "
|
"{total bytes %d} "
|
||||||
"{length %u}\n"
|
"{num entries %u}\n"
|
||||||
"{tail offset %u}\n",
|
"{tail offset %u}\n",
|
||||||
intrev32ifbe(ZIPLIST_BYTES(zl)),
|
intrev32ifbe(ZIPLIST_BYTES(zl)),
|
||||||
intrev16ifbe(ZIPLIST_LENGTH(zl)),
|
intrev16ifbe(ZIPLIST_LENGTH(zl)),
|
||||||
@ -1038,16 +1038,15 @@ void ziplistRepr(unsigned char *zl) {
|
|||||||
while(*p != ZIP_END) {
|
while(*p != ZIP_END) {
|
||||||
zipEntry(p, &entry);
|
zipEntry(p, &entry);
|
||||||
printf(
|
printf(
|
||||||
"{"
|
"{\n"
|
||||||
"addr 0x%08lx, "
|
"\taddr 0x%08lx,\n"
|
||||||
"index %2d, "
|
"\tindex %2d,\n"
|
||||||
"offset %5ld, "
|
"\toffset %5ld,\n"
|
||||||
"rl: %5u, "
|
"\thdr+entry len: %5u,\n"
|
||||||
"hs %2u, "
|
"\thdr len%2u,\n"
|
||||||
"pl: %5u, "
|
"\tprevrawlen: %5u,\n"
|
||||||
"pls: %2u, "
|
"\tprevrawlensize: %2u,\n"
|
||||||
"payload %5u"
|
"\tpayload %5u\n",
|
||||||
"} ",
|
|
||||||
(long unsigned)p,
|
(long unsigned)p,
|
||||||
index,
|
index,
|
||||||
(unsigned long) (p-zl),
|
(unsigned long) (p-zl),
|
||||||
@ -1056,8 +1055,14 @@ void ziplistRepr(unsigned char *zl) {
|
|||||||
entry.prevrawlen,
|
entry.prevrawlen,
|
||||||
entry.prevrawlensize,
|
entry.prevrawlensize,
|
||||||
entry.len);
|
entry.len);
|
||||||
|
printf("\tbytes: ");
|
||||||
|
for (unsigned int i = 0; i < entry.headersize+entry.len; i++) {
|
||||||
|
printf("%02x|",p[i]);
|
||||||
|
}
|
||||||
|
printf("\n");
|
||||||
p += entry.headersize;
|
p += entry.headersize;
|
||||||
if (ZIP_IS_STR(entry.encoding)) {
|
if (ZIP_IS_STR(entry.encoding)) {
|
||||||
|
printf("\t[str]");
|
||||||
if (entry.len > 40) {
|
if (entry.len > 40) {
|
||||||
if (fwrite(p,40,1,stdout) == 0) perror("fwrite");
|
if (fwrite(p,40,1,stdout) == 0) perror("fwrite");
|
||||||
printf("...");
|
printf("...");
|
||||||
@ -1066,9 +1071,9 @@ void ziplistRepr(unsigned char *zl) {
|
|||||||
fwrite(p,entry.len,1,stdout) == 0) perror("fwrite");
|
fwrite(p,entry.len,1,stdout) == 0) perror("fwrite");
|
||||||
}
|
}
|
||||||
} else {
|
} 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;
|
p += entry.len;
|
||||||
index++;
|
index++;
|
||||||
}
|
}
|
||||||
|
@ -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 char *ziplistFind(unsigned char *p, unsigned char *vstr, unsigned int vlen, unsigned int skip);
|
||||||
unsigned int ziplistLen(unsigned char *zl);
|
unsigned int ziplistLen(unsigned char *zl);
|
||||||
size_t ziplistBlobLen(unsigned char *zl);
|
size_t ziplistBlobLen(unsigned char *zl);
|
||||||
|
void ziplistRepr(unsigned char *zl);
|
||||||
|
|
||||||
#ifdef REDIS_TEST
|
#ifdef REDIS_TEST
|
||||||
int ziplistTest(int argc, char *argv[]);
|
int ziplistTest(int argc, char *argv[]);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user