Merge branch 'unstable' into module_command_help

This commit is contained in:
Itamar Haber 2018-06-09 21:10:53 +03:00 committed by GitHub
commit e654b68d1f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 171 additions and 26 deletions

View File

@ -287,12 +287,13 @@ void debugCommand(client *c) {
const char *help[] = { const char *help[] = {
"ASSERT -- Crash by assertion failed.", "ASSERT -- Crash by assertion failed.",
"CHANGE-REPL-ID -- Change the replication IDs of the instance. Dangerous, should be used only for testing the replication subsystem.", "CHANGE-REPL-ID -- Change the replication IDs of the instance. Dangerous, should be used only for testing the replication subsystem.",
"CRASH-and-recover <milliseconds> -- Hard crash and restart after <milliseconds> delay.", "CRASH-AND-RECOVER <milliseconds> -- Hard crash and restart after <milliseconds> delay.",
"DIGEST -- Output a hex signature representing the current DB content.", "DIGEST -- Output a hex signature representing the current DB content.",
"ERROR <string> -- Return a Redis protocol error with <string> as message. Useful for clients unit tests to simulate Redis errors.", "ERROR <string> -- Return a Redis protocol error with <string> as message. Useful for clients unit tests to simulate Redis errors.",
"HTSTATS <dbid> -- Return hash table statistics of the specified Redis database.", "HTSTATS <dbid> -- Return hash table statistics of the specified Redis database.",
"HTSTATS-KEY <key> -- Like htstats but for the hash table stored as key's value.",
"LOADAOF -- Flush the AOF buffers on disk and reload the AOF in memory.", "LOADAOF -- Flush the AOF buffers on disk and reload the AOF in memory.",
"LUA-ALWAYS-REPLICATE-COMMANDS (0|1) -- Setting it to 1 makes Lua replication defaulting to replicating single commands, without the script having to enable effects replication.", "LUA-ALWAYS-REPLICATE-COMMANDS <0|1> -- Setting it to 1 makes Lua replication defaulting to replicating single commands, without the script having to enable effects replication.",
"OBJECT <key> -- Show low level info about key and associated value.", "OBJECT <key> -- Show low level info about key and associated value.",
"PANIC -- Crash the server simulating a panic.", "PANIC -- Crash the server simulating a panic.",
"POPULATE <count> [prefix] [size] -- Create <count> string keys named key:<num>. If a prefix is specified is used instead of the 'key' prefix.", "POPULATE <count> [prefix] [size] -- Create <count> string keys named key:<num>. If a prefix is specified is used instead of the 'key' prefix.",
@ -300,7 +301,7 @@ void debugCommand(client *c) {
"RESTART -- Graceful restart: save config, db, restart.", "RESTART -- Graceful restart: save config, db, restart.",
"SDSLEN <key> -- Show low level SDS string info representing key and value.", "SDSLEN <key> -- Show low level SDS string info representing key and value.",
"SEGFAULT -- Crash the server with sigsegv.", "SEGFAULT -- Crash the server with sigsegv.",
"SET-ACTIVE-EXPIRE (0|1) -- Setting it to 0 disables expiring keys in background when they are not accessed (otherwise the Redis behavior). Setting it to 1 reenables back the default.", "SET-ACTIVE-EXPIRE <0|1> -- Setting it to 0 disables expiring keys in background when they are not accessed (otherwise the Redis behavior). Setting it to 1 reenables back the default.",
"SLEEP <seconds> -- Stop the server for <seconds>. Decimals allowed.", "SLEEP <seconds> -- Stop the server for <seconds>. Decimals allowed.",
"STRUCTSIZE -- Return the size of different Redis core C structures.", "STRUCTSIZE -- Return the size of different Redis core C structures.",
"ZIPLIST <key> -- Show low level info about the ziplist encoding.", "ZIPLIST <key> -- Show low level info about the ziplist encoding.",
@ -547,6 +548,34 @@ NULL
stats = sdscat(stats,buf); stats = sdscat(stats,buf);
addReplyBulkSds(c,stats); addReplyBulkSds(c,stats);
} else if (!strcasecmp(c->argv[1]->ptr,"htstats-key") && c->argc == 3) {
robj *o;
dict *ht = NULL;
if ((o = objectCommandLookupOrReply(c,c->argv[2],shared.nokeyerr))
== NULL) return;
/* Get the hash table reference from the object, if possible. */
switch (o->encoding) {
case OBJ_ENCODING_SKIPLIST:
{
zset *zs = o->ptr;
ht = zs->dict;
}
break;
case OBJ_ENCODING_HT:
ht = o->ptr;
break;
}
if (ht == NULL) {
addReplyError(c,"The value stored at the specified key is not "
"represented using an hash table");
} else {
char buf[4096];
dictGetStats(buf,sizeof(buf),ht);
addReplyBulkCString(c,buf);
}
} else if (!strcasecmp(c->argv[1]->ptr,"change-repl-id") && c->argc == 2) { } else if (!strcasecmp(c->argv[1]->ptr,"change-repl-id") && c->argc == 2) {
serverLog(LL_WARNING,"Changing replication IDs after receiving DEBUG change-repl-id"); serverLog(LL_WARNING,"Changing replication IDs after receiving DEBUG change-repl-id");
changeReplicationId(); changeReplicationId();

View File

@ -146,14 +146,14 @@ int dictResize(dict *d)
/* Expand or create the hash table */ /* Expand or create the hash table */
int dictExpand(dict *d, unsigned long size) int dictExpand(dict *d, unsigned long size)
{ {
dictht n; /* the new hash table */
unsigned long realsize = _dictNextPower(size);
/* the size is invalid if it is smaller than the number of /* the size is invalid if it is smaller than the number of
* elements already inside the hash table */ * elements already inside the hash table */
if (dictIsRehashing(d) || d->ht[0].used > size) if (dictIsRehashing(d) || d->ht[0].used > size)
return DICT_ERR; return DICT_ERR;
dictht n; /* the new hash table */
unsigned long realsize = _dictNextPower(size);
/* Rehashing to the same table size is not useful. */ /* Rehashing to the same table size is not useful. */
if (realsize == d->ht[0].size) return DICT_ERR; if (realsize == d->ht[0].size) return DICT_ERR;

View File

@ -1,4 +1,4 @@
/* Automatically generated by utils/generate-command-help.rb, do not edit. */ /* Automatically generated by generate-command-help.rb, do not edit. */
#ifndef __REDIS_HELP_H #ifndef __REDIS_HELP_H
#define __REDIS_HELP_H #define __REDIS_HELP_H
@ -17,7 +17,8 @@ static char *commandGroups[] = {
"scripting", "scripting",
"hyperloglog", "hyperloglog",
"cluster", "cluster",
"geo" "geo",
"stream"
}; };
struct commandHelp { struct commandHelp {
@ -82,6 +83,16 @@ struct commandHelp {
"Pop a value from a list, push it to another list and return it; or block until one is available", "Pop a value from a list, push it to another list and return it; or block until one is available",
2, 2,
"2.2.0" }, "2.2.0" },
{ "BZPOPMAX",
"key [key ...] timeout",
"Remove and return the member with the highest score from one or more sorted sets, or block until one is available",
4,
"5.0.0" },
{ "BZPOPMIN",
"key [key ...] timeout",
"Remove and return the member with the lowest score from one or more sorted sets, or block until one is available",
4,
"5.0.0" },
{ "CLIENT GETNAME", { "CLIENT GETNAME",
"-", "-",
"Get the current connection name", "Get the current connection name",
@ -318,12 +329,12 @@ struct commandHelp {
0, 0,
"1.2.0" }, "1.2.0" },
{ "FLUSHALL", { "FLUSHALL",
"-", "[ASYNC]",
"Remove all keys from all databases", "Remove all keys from all databases",
9, 9,
"1.0.0" }, "1.0.0" },
{ "FLUSHDB", { "FLUSHDB",
"-", "[ASYNC]",
"Remove all keys from the current database", "Remove all keys from the current database",
9, 9,
"1.0.0" }, "1.0.0" },
@ -532,6 +543,36 @@ struct commandHelp {
"Trim a list to the specified range", "Trim a list to the specified range",
2, 2,
"1.0.0" }, "1.0.0" },
{ "MEMORY DOCTOR",
"-",
"Outputs memory problems report",
9,
"4.0.0" },
{ "MEMORY HELP",
"-",
"Show helpful text about the different subcommands",
9,
"4.0.0" },
{ "MEMORY MALLOC-STATS",
"-",
"Show allocator internal stats",
9,
"4.0.0" },
{ "MEMORY PURGE",
"-",
"Ask the allocator to release memory",
9,
"4.0.0" },
{ "MEMORY STATS",
"-",
"Show memory usage details",
9,
"4.0.0" },
{ "MEMORY USAGE",
"key [SAMPLES count]",
"Estimate the memory usage of a key",
9,
"4.0.0" },
{ "MGET", { "MGET",
"key [key ...]", "key [key ...]",
"Get the values of all the given keys", "Get the values of all the given keys",
@ -723,7 +764,7 @@ struct commandHelp {
10, 10,
"3.2.0" }, "3.2.0" },
{ "SCRIPT EXISTS", { "SCRIPT EXISTS",
"script [script ...]", "sha1 [sha1 ...]",
"Check existence of scripts in the script cache.", "Check existence of scripts in the script cache.",
10, 10,
"2.6.0" }, "2.6.0" },
@ -758,7 +799,7 @@ struct commandHelp {
8, 8,
"1.0.0" }, "1.0.0" },
{ "SET", { "SET",
"key value [EX seconds] [PX milliseconds] [NX|XX]", "key value [expiration EX seconds|PX milliseconds] [NX|XX]",
"Set the string value of a key", "Set the string value of a key",
1, 1,
"1.0.0" }, "1.0.0" },
@ -867,6 +908,11 @@ struct commandHelp {
"Add multiple sets and store the resulting set in a key", "Add multiple sets and store the resulting set in a key",
3, 3,
"1.0.0" }, "1.0.0" },
{ "SWAPDB",
"index index",
"Swaps two Redis databases",
8,
"4.0.0" },
{ "SYNC", { "SYNC",
"-", "-",
"Internal command used for replication", "Internal command used for replication",
@ -877,6 +923,11 @@ struct commandHelp {
"Return the current server time", "Return the current server time",
9, 9,
"2.6.0" }, "2.6.0" },
{ "TOUCH",
"key [key ...]",
"Alters the last access time of a key(s). Returns the number of existing keys specified.",
0,
"3.2.1" },
{ "TTL", { "TTL",
"key", "key",
"Get the time to live for a key", "Get the time to live for a key",
@ -887,6 +938,11 @@ struct commandHelp {
"Determine the type stored at key", "Determine the type stored at key",
0, 0,
"1.0.0" }, "1.0.0" },
{ "UNLINK",
"key [key ...]",
"Delete a key asynchronously in another thread. Otherwise it is just as DEL, but non blocking.",
0,
"4.0.0" },
{ "UNSUBSCRIBE", { "UNSUBSCRIBE",
"[channel [channel ...]]", "[channel [channel ...]]",
"Stop listening for messages posted to the given channels", "Stop listening for messages posted to the given channels",
@ -907,6 +963,41 @@ struct commandHelp {
"Watch the given keys to determine execution of the MULTI/EXEC block", "Watch the given keys to determine execution of the MULTI/EXEC block",
7, 7,
"2.2.0" }, "2.2.0" },
{ "XADD",
"key ID field string [field string ...]",
"Appends a new entry to a stream",
14,
"5.0.0" },
{ "XLEN",
"key",
"Return the number of entires in a stream",
14,
"5.0.0" },
{ "XPENDING",
"key group [start end count] [consumer]",
"Return information and entries from a stream conusmer group pending entries list, that are messages fetched but never acknowledged.",
14,
"5.0.0" },
{ "XRANGE",
"key start end [COUNT count]",
"Return a range of elements in a stream, with IDs matching the specified IDs interval",
14,
"5.0.0" },
{ "XREAD",
"[COUNT count] [BLOCK milliseconds] STREAMS key [key ...] ID [ID ...]",
"Return never seen elements in multiple streams, with IDs greater than the ones reported by the caller for each stream. Can block.",
14,
"5.0.0" },
{ "XREADGROUP",
"GROUP group consumer [COUNT count] [BLOCK milliseconds] STREAMS key [key ...] ID [ID ...]",
"Return new entries from a stream using a consumer group, or access the history of the pending entries for a given consumer. Can block.",
14,
"5.0.0" },
{ "XREVRANGE",
"key end start [COUNT count]",
"Return a range of elements in a stream, with IDs matching the specified IDs interval, in reverse order (from greater to smaller IDs) compared to XRANGE",
14,
"5.0.0" },
{ "ZADD", { "ZADD",
"key [NX|XX] [CH] [INCR] score member [score member ...]", "key [NX|XX] [CH] [INCR] score member [score member ...]",
"Add one or more members to a sorted set, or update its score if it already exists", "Add one or more members to a sorted set, or update its score if it already exists",
@ -937,6 +1028,16 @@ struct commandHelp {
"Count the number of members in a sorted set between a given lexicographical range", "Count the number of members in a sorted set between a given lexicographical range",
4, 4,
"2.8.9" }, "2.8.9" },
{ "ZPOPMAX",
"key [count]",
"Remove and return members with the highest scores in a sorted set",
4,
"5.0.0" },
{ "ZPOPMIN",
"key [count]",
"Remove and return members with the lowest scores in a sorted set",
4,
"5.0.0" },
{ "ZRANGE", { "ZRANGE",
"key start stop [WITHSCORES]", "key start stop [WITHSCORES]",
"Return a range of members in a sorted set, by index", "Return a range of members in a sorted set, by index",

View File

@ -1441,6 +1441,9 @@ robj *rdbLoadObject(int rdbtype, rio *rdb) {
o = createZsetObject(); o = createZsetObject();
zs = o->ptr; zs = o->ptr;
if (zsetlen > DICT_HT_INITIAL_SIZE)
dictExpand(zs->dict,zsetlen);
/* Load every single element of the sorted set. */ /* Load every single element of the sorted set. */
while(zsetlen--) { while(zsetlen--) {
sds sdsele; sds sdsele;
@ -1509,6 +1512,9 @@ robj *rdbLoadObject(int rdbtype, rio *rdb) {
sdsfree(value); sdsfree(value);
} }
if (o->encoding == OBJ_ENCODING_HT && len > DICT_HT_INITIAL_SIZE)
dictExpand(o->ptr,len);
/* Load remaining fields and values into the hash table */ /* Load remaining fields and values into the hash table */
while (o->encoding == OBJ_ENCODING_HT && len > 0) { while (o->encoding == OBJ_ENCODING_HT && len > 0) {
len--; len--;

View File

@ -1075,6 +1075,8 @@ static int cliSendCommand(int argc, char **argv, long repeat) {
if (!strcasecmp(command,"info") || if (!strcasecmp(command,"info") ||
(argc >= 2 && !strcasecmp(command,"debug") && (argc >= 2 && !strcasecmp(command,"debug") &&
!strcasecmp(argv[1],"htstats")) || !strcasecmp(argv[1],"htstats")) ||
(argc >= 2 && !strcasecmp(command,"debug") &&
!strcasecmp(argv[1],"htstats-key")) ||
(argc >= 2 && !strcasecmp(command,"memory") && (argc >= 2 && !strcasecmp(command,"memory") &&
(!strcasecmp(argv[1],"malloc-stats") || (!strcasecmp(argv[1],"malloc-stats") ||
!strcasecmp(argv[1],"doctor"))) || !strcasecmp(argv[1],"doctor"))) ||

View File

@ -339,7 +339,7 @@ typedef long long mstime_t; /* millisecond time type. */
/* Anti-warning macro... */ /* Anti-warning macro... */
#define UNUSED(V) ((void) V) #define UNUSED(V) ((void) V)
#define ZSKIPLIST_MAXLEVEL 32 /* Should be enough for 2^32 elements */ #define ZSKIPLIST_MAXLEVEL 64 /* Should be enough for 2^64 elements */
#define ZSKIPLIST_P 0.25 /* Skiplist P = 1/4 */ #define ZSKIPLIST_P 0.25 /* Skiplist P = 1/4 */
/* Append only defines */ /* Append only defines */
@ -782,7 +782,7 @@ typedef struct zskiplistNode {
struct zskiplistNode *backward; struct zskiplistNode *backward;
struct zskiplistLevel { struct zskiplistLevel {
struct zskiplistNode *forward; struct zskiplistNode *forward;
unsigned int span; unsigned long span;
} level[]; } level[];
} zskiplistNode; } zskiplistNode;
@ -1629,7 +1629,7 @@ void zzlNext(unsigned char *zl, unsigned char **eptr, unsigned char **sptr);
void zzlPrev(unsigned char *zl, unsigned char **eptr, unsigned char **sptr); void zzlPrev(unsigned char *zl, unsigned char **eptr, unsigned char **sptr);
unsigned char *zzlFirstInRange(unsigned char *zl, zrangespec *range); unsigned char *zzlFirstInRange(unsigned char *zl, zrangespec *range);
unsigned char *zzlLastInRange(unsigned char *zl, zrangespec *range); unsigned char *zzlLastInRange(unsigned char *zl, zrangespec *range);
unsigned int zsetLength(const robj *zobj); unsigned long zsetLength(const robj *zobj);
void zsetConvert(robj *zobj, int encoding); void zsetConvert(robj *zobj, int encoding);
void zsetConvertToZiplistIfNeeded(robj *zobj, size_t maxelelen); void zsetConvertToZiplistIfNeeded(robj *zobj, size_t maxelelen);
int zsetScore(robj *zobj, sds member, double *score); int zsetScore(robj *zobj, sds member, double *score);

View File

@ -1783,8 +1783,10 @@ void xpendingCommand(client *c) {
/* If a consumer name was mentioned but it does not exist, we can /* If a consumer name was mentioned but it does not exist, we can
* just return an empty array. */ * just return an empty array. */
if (consumername && consumer == NULL) if (consumername && consumer == NULL) {
addReplyMultiBulkLen(c,0); addReplyMultiBulkLen(c,0);
return;
}
rax *pel = consumer ? consumer->pel : group->pel; rax *pel = consumer ? consumer->pel : group->pel;
unsigned char startkey[sizeof(streamID)]; unsigned char startkey[sizeof(streamID)];

View File

@ -1100,8 +1100,8 @@ unsigned char *zzlDeleteRangeByRank(unsigned char *zl, unsigned int start, unsig
* Common sorted set API * Common sorted set API
*----------------------------------------------------------------------------*/ *----------------------------------------------------------------------------*/
unsigned int zsetLength(const robj *zobj) { unsigned long zsetLength(const robj *zobj) {
int length = -1; unsigned long length = 0;
if (zobj->encoding == OBJ_ENCODING_ZIPLIST) { if (zobj->encoding == OBJ_ENCODING_ZIPLIST) {
length = zzlLength(zobj->ptr); length = zzlLength(zobj->ptr);
} else if (zobj->encoding == OBJ_ENCODING_SKIPLIST) { } else if (zobj->encoding == OBJ_ENCODING_SKIPLIST) {
@ -1878,7 +1878,7 @@ void zuiClearIterator(zsetopsrc *op) {
} }
} }
int zuiLength(zsetopsrc *op) { unsigned long zuiLength(zsetopsrc *op) {
if (op->subject == NULL) if (op->subject == NULL)
return 0; return 0;
@ -2085,7 +2085,11 @@ int zuiFind(zsetopsrc *op, zsetopval *val, double *score) {
} }
int zuiCompareByCardinality(const void *s1, const void *s2) { int zuiCompareByCardinality(const void *s1, const void *s2) {
return zuiLength((zsetopsrc*)s1) - zuiLength((zsetopsrc*)s2); unsigned long first = zuiLength((zsetopsrc*)s1);
unsigned long second = zuiLength((zsetopsrc*)s2);
if (first > second) return 1;
if (first < second) return -1;
return 0;
} }
#define REDIS_AGGR_SUM 1 #define REDIS_AGGR_SUM 1
@ -2129,7 +2133,7 @@ void zunionInterGenericCommand(client *c, robj *dstkey, int op) {
zsetopsrc *src; zsetopsrc *src;
zsetopval zval; zsetopval zval;
sds tmp; sds tmp;
unsigned int maxelelen = 0; size_t maxelelen = 0;
robj *dstobj; robj *dstobj;
zset *dstzset; zset *dstzset;
zskiplistNode *znode; zskiplistNode *znode;
@ -2363,8 +2367,8 @@ void zrangeGenericCommand(client *c, int reverse) {
int withscores = 0; int withscores = 0;
long start; long start;
long end; long end;
int llen; long llen;
int rangelen; long rangelen;
if ((getLongFromObjectOrReply(c, c->argv[2], &start, NULL) != C_OK) || if ((getLongFromObjectOrReply(c, c->argv[2], &start, NULL) != C_OK) ||
(getLongFromObjectOrReply(c, c->argv[3], &end, NULL) != C_OK)) return; (getLongFromObjectOrReply(c, c->argv[3], &end, NULL) != C_OK)) return;
@ -2671,7 +2675,7 @@ void zcountCommand(client *c) {
robj *key = c->argv[1]; robj *key = c->argv[1];
robj *zobj; robj *zobj;
zrangespec range; zrangespec range;
int count = 0; unsigned long count = 0;
/* Parse the range arguments */ /* Parse the range arguments */
if (zslParseRange(c->argv[2],c->argv[3],&range) != C_OK) { if (zslParseRange(c->argv[2],c->argv[3],&range) != C_OK) {
@ -2748,7 +2752,7 @@ void zlexcountCommand(client *c) {
robj *key = c->argv[1]; robj *key = c->argv[1];
robj *zobj; robj *zobj;
zlexrangespec range; zlexrangespec range;
int count = 0; unsigned long count = 0;
/* Parse the range arguments */ /* Parse the range arguments */
if (zslParseLexRange(c->argv[2],c->argv[3],&range) != C_OK) { if (zslParseLexRange(c->argv[2],c->argv[3],&range) != C_OK) {

View File

@ -14,7 +14,8 @@ GROUPS = [
"scripting", "scripting",
"hyperloglog", "hyperloglog",
"cluster", "cluster",
"geo" "geo",
"stream"
].freeze ].freeze
GROUPS_BY_NAME = Hash[* GROUPS_BY_NAME = Hash[*