From 0333e803644ae0c14a15c1a914becc915657da3f Mon Sep 17 00:00:00 2001 From: antirez Date: Sun, 19 Dec 2010 12:22:12 +0100 Subject: [PATCH 1/3] overflow detection in INCR family functions --- src/t_string.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/t_string.c b/src/t_string.c index eb080c882..c3e3607f3 100644 --- a/src/t_string.c +++ b/src/t_string.c @@ -346,14 +346,19 @@ void msetnxCommand(redisClient *c) { } void incrDecrCommand(redisClient *c, long long incr) { - long long value; + long long value, oldvalue; robj *o; o = lookupKeyWrite(c->db,c->argv[1]); if (o != NULL && checkType(c,o,REDIS_STRING)) return; if (getLongLongFromObjectOrReply(c,o,&value,NULL) != REDIS_OK) return; + oldvalue = value; value += incr; + if ((incr < 0 && value > oldvalue) || (incr > 0 && value < oldvalue)) { + addReplyError(c,"increment or decrement would overflow"); + return; + } o = createStringObjectFromLongLong(value); dbReplace(c->db,c->argv[1],o); touchWatchedKey(c->db,c->argv[1]); From cb802cedc32141d11748dd93c6f4901c666dbe37 Mon Sep 17 00:00:00 2001 From: antirez Date: Sun, 19 Dec 2010 15:15:08 +0100 Subject: [PATCH 2/3] removed some dead code, added evicted keys counter separated from expired keys. --- src/redis.c | 36 ++++-------------------------------- src/redis.h | 1 + 2 files changed, 5 insertions(+), 32 deletions(-) diff --git a/src/redis.c b/src/redis.c index fb6eb4694..6e667f29a 100644 --- a/src/redis.c +++ b/src/redis.c @@ -891,6 +891,7 @@ void initServer() { server.stat_numcommands = 0; server.stat_numconnections = 0; server.stat_expiredkeys = 0; + server.stat_evictedkeys = 0; server.stat_starttime = time(NULL); server.stat_keyspace_misses = 0; server.stat_keyspace_hits = 0; @@ -1177,6 +1178,7 @@ sds genRedisInfoString(void) { "total_connections_received:%lld\r\n" "total_commands_processed:%lld\r\n" "expired_keys:%lld\r\n" + "evicted_keys:%lld\r\n" "keyspace_hits:%lld\r\n" "keyspace_misses:%lld\r\n" "hash_max_zipmap_entries:%zu\r\n" @@ -1219,6 +1221,7 @@ sds genRedisInfoString(void) { server.stat_numconnections, server.stat_numcommands, server.stat_expiredkeys, + server.stat_evictedkeys, server.stat_keyspace_hits, server.stat_keyspace_misses, server.hash_max_zipmap_entries, @@ -1436,44 +1439,13 @@ void freeMemoryIfNeeded(void) { if (bestkey) { robj *keyobj = createStringObject(bestkey,sdslen(bestkey)); dbDelete(db,keyobj); - server.stat_expiredkeys++; + server.stat_evictedkeys++; decrRefCount(keyobj); freed++; } } if (!freed) return; /* nothing to free... */ } - - while(0) { - int j, k, freed = 0; - for (j = 0; j < server.dbnum; j++) { - int minttl = -1; - sds minkey = NULL; - robj *keyobj = NULL; - struct dictEntry *de; - - if (dictSize(server.db[j].expires)) { - freed = 1; - /* From a sample of three keys drop the one nearest to - * the natural expire */ - for (k = 0; k < 3; k++) { - time_t t; - - de = dictGetRandomKey(server.db[j].expires); - t = (time_t) dictGetEntryVal(de); - if (minttl == -1 || t < minttl) { - minkey = dictGetEntryKey(de); - minttl = t; - } - } - keyobj = createStringObject(minkey,sdslen(minkey)); - dbDelete(server.db+j,keyobj); - server.stat_expiredkeys++; - decrRefCount(keyobj); - } - } - if (!freed) return; /* nothing to free... */ - } } /* =================================== Main! ================================ */ diff --git a/src/redis.h b/src/redis.h index 8495a87e5..bc1a58c17 100644 --- a/src/redis.h +++ b/src/redis.h @@ -387,6 +387,7 @@ struct redisServer { long long stat_numcommands; /* number of processed commands */ long long stat_numconnections; /* number of connections received */ long long stat_expiredkeys; /* number of expired keys */ + long long stat_evictedkeys; /* number of evicted keys (maxmemory) */ long long stat_keyspace_hits; /* number of successful lookups of keys */ long long stat_keyspace_misses; /* number of failed lookups of keys */ /* Configuration */ From c1f127387107523a900e8bba7924527e6e5b6e37 Mon Sep 17 00:00:00 2001 From: antirez Date: Wed, 15 Dec 2010 17:39:40 +0100 Subject: [PATCH 3/3] help.h updated --- src/help.h | 54 ++++++++++++++++++++++++++-------- utils/generate-command-help.rb | 1 + 2 files changed, 43 insertions(+), 12 deletions(-) diff --git a/src/help.h b/src/help.h index 121d9dfaf..51613c9b3 100644 --- a/src/help.h +++ b/src/help.h @@ -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 #define __REDIS_HELP_H @@ -53,11 +53,21 @@ struct commandHelp { "Remove and get the last element in a list, or block until one is available", 2, "1.3.1" }, + { "BRPOPLPUSH", + "source destination timeout", + "Pop a value from a list, push it to another list and return it; or block until one is available", + 2, + "2.1.7" }, { "CONFIG GET", "parameter", "Get the value of a configuration parameter", 9, "2.0" }, + { "CONFIG RESETSTAT", + "-", + "Reset the stats returned by INFO", + 9, + "2.0" }, { "CONFIG SET", "parameter value", "Set a configuration parameter to the given value", @@ -79,7 +89,7 @@ struct commandHelp { 9, "0.101" }, { "DECR", - "key decrement", + "key", "Decrement the integer value of a key by one", 1, "0.07" }, @@ -138,6 +148,11 @@ struct commandHelp { "Get the value of a key", 1, "0.07" }, + { "GETBIT", + "key offset", + "Returns the bit value at offset in the string value stored at key", + 1, + "2.1.8" }, { "GETSET", "key value", "Set the string value of a key and return its old value", @@ -344,12 +359,12 @@ struct commandHelp { 0, "0.07" }, { "RENAME", - "old new", + "key newkey", "Rename a key", 0, "0.07" }, { "RENAMENX", - "old new", + "key newkey", "Rename a key, only if the new key does not exist", 0, "0.07" }, @@ -408,8 +423,13 @@ struct commandHelp { "Set the string value of a key", 1, "0.07" }, + { "SETBIT", + "key offset value", + "Sets or clears the bit at offset in the string value stored at key", + 1, + "2.1.8" }, { "SETEX", - "key timestamp value", + "key seconds value", "Set the value and expiration of a key", 1, "1.3.10" }, @@ -418,6 +438,11 @@ struct commandHelp { "Set the value of a key, only if the key does not exist", 1, "0.07" }, + { "SETRANGE", + "key offset value", + "Overwrite part of a string at key starting at the specified offset", + 1, + "2.1.8" }, { "SHUTDOWN", "-", "Synchronously save the dataset to disk and then shut down the server", @@ -454,7 +479,7 @@ struct commandHelp { 3, "0.091" }, { "SORT", - "key [BY pattern] [LIMIT start count] [GET pattern [GET pattern ...]] [ASC|DESC] [ALPHA] [STORE destination]", + "key [BY pattern] [LIMIT offset count] [GET pattern [GET pattern ...]] [ASC|DESC] [ALPHA] [STORE destination]", "Sort the elements in a list, set or sorted set", 0, "0.07" }, @@ -484,7 +509,7 @@ struct commandHelp { 6, "1.3.8" }, { "SUBSTR", - "key start stop", + "key start end", "Get a substring of the string stored at a key", 1, "1.3.4" }, @@ -549,17 +574,17 @@ struct commandHelp { 4, "1.1" }, { "ZINTERSTORE", - "destination key [key ...] [WEIGHTS weight] [AGGREGATE SUM|MIN|MAX]", + "destination numkeys key [key ...] [WEIGHTS weight] [AGGREGATE SUM|MIN|MAX]", "Intersect multiple sorted sets and store the resulting sorted set in a new key", 4, "1.3.10" }, { "ZRANGE", - "key start stop", + "key start stop [WITHSCORES]", "Return a range of members in a sorted set, by index", 4, "1.1" }, { "ZRANGEBYSCORE", - "key min max", + "key min max [WITHSCORES] [LIMIT offset count]", "Return a range of members in a sorted set, by score", 4, "1.050" }, @@ -584,10 +609,15 @@ struct commandHelp { 4, "1.1" }, { "ZREVRANGE", - "key start stop", + "key start stop [WITHSCORES]", "Return a range of members in a sorted set, by index, with scores ordered from high to low", 4, "1.1" }, + { "ZREVRANGEBYSCORE", + "key max min [WITHSCORES] [LIMIT offset count]", + "Return a range of members in a sorted set, by score, with scores ordered from high to low", + 4, + "2.1.6" }, { "ZREVRANK", "key member", "Determine the index of a member in a sorted set, with scores ordered from high to low", @@ -599,7 +629,7 @@ struct commandHelp { 4, "1.1" }, { "ZUNIONSTORE", - "destination key [key ...] [WEIGHTS weight] [AGGREGATE SUM|MIN|MAX]", + "destination numkeys key [key ...] [WEIGHTS weight] [AGGREGATE SUM|MIN|MAX]", "Add multiple sorted sets and store the resulting sorted set in a new key", 4, "1.3.10" } diff --git a/utils/generate-command-help.rb b/utils/generate-command-help.rb index f730eaf10..96cccc2bf 100755 --- a/utils/generate-command-help.rb +++ b/utils/generate-command-help.rb @@ -42,6 +42,7 @@ end def commands return @commands if @commands + require "rubygems" require "net/http" require "net/https" require "json"