From 28173a49a7f6c8d5850f70c26874f3cba6f64941 Mon Sep 17 00:00:00 2001 From: antirez Date: Sat, 21 Nov 2009 13:25:51 +0100 Subject: [PATCH] SORT GET # implemented, with a test --- TODO | 3 +-- redis.c | 13 ++++++++++++- redis.tcl | 2 +- test-redis.tcl | 26 ++++++++++++++++++++++++++ 4 files changed, 40 insertions(+), 4 deletions(-) diff --git a/TODO b/TODO index 27102e01..c3175783 100644 --- a/TODO +++ b/TODO @@ -3,10 +3,9 @@ VERSION 1.1 TODO * For now only the last argument gets integer encoded, so make sure that: 1) every multi bulk commands implemented will have the last arg that is indeed a value, and not used otherwise. 2) to explicitly call the function to encode the object in MSET and other commands where there are multiple "values". * Man pages for MSET MSETNX and SRANDMEMBER, Z-commands, ... * Use strcoll() to compare objects in sorted sets, like it already happens for SORT. -* Tests for: EXPIREAT, ZSCORE, ZINCRBY, SRANDMEMBER, SORT with #. +* Tests for: ZINCRBY, SRANDMEMBER, SORT with #. * Write docs for the "STORE" operaiton of SORT, and GET "#" option. * Append only mode: testing and a command to rebuild the log from scratch. -* Redis-cli should be able to select a different DB than 0 using some switch. VERSION 1.2 TODO diff --git a/redis.c b/redis.c index f3968b81..bbb46117 100644 --- a/redis.c +++ b/redis.c @@ -4577,13 +4577,24 @@ static robj *lookupKeyByPattern(redisDb *db, robj *pattern, robj *subst) { char buf[REDIS_SORTKEY_MAX+1]; } keyname; + /* If the pattern is "#" return the substitution object itself in order + * to implement the "SORT ... GET #" feature. */ + spat = pattern->ptr; + if (spat[0] == '#' && spat[1] == '\0') { + return subst; + } + + /* The substitution object may be specially encoded. If so we create + * a decoded object on the fly. */ if (subst->encoding == REDIS_ENCODING_RAW) + /* If we don't need to get a decoded object increment the refcount + * so that the final decrRefCount() call will restore the original + * count */ incrRefCount(subst); else { subst = getDecodedObject(subst); } - spat = pattern->ptr; ssub = subst->ptr; if (sdslen(spat)+sdslen(ssub)-1 > REDIS_SORTKEY_MAX) return NULL; p = strchr(spat,'*'); diff --git a/redis.tcl b/redis.tcl index 3407d5d1..8ad96f45 100644 --- a/redis.tcl +++ b/redis.tcl @@ -20,7 +20,7 @@ array set ::redis::multibulkarg {} # Flag commands requiring last argument as a bulk write operation foreach redis_bulk_cmd { - set setnx rpush lpush lset lrem sadd srem sismember echo getset smove zadd zrem zscore rpoplpush + set setnx rpush lpush lset lrem sadd srem sismember echo getset smove zadd zrem zscore rpoplpush zincrby } { set ::redis::bulkarg($redis_bulk_cmd) {} } diff --git a/test-redis.tcl b/test-redis.tcl index a7b40cd3..10b1acd2 100644 --- a/test-redis.tcl +++ b/test-redis.tcl @@ -696,6 +696,15 @@ proc main {server port} { $r sort mylist } [lsort -real {1.1 5.10 3.10 7.44 2.1 5.75 6.12 0.25 1.15}] + test {SORT with GET #} { + $r del mylist + $r lpush mylist 1 + $r lpush mylist 2 + $r lpush mylist 3 + $r mset weight_1 10 weight_2 5 weight_3 30 + $r sort mylist BY weight_* GET # + } {2 1 3} + test {LREM, remove all the occurrences} { $r flushdb $r rpush mylist foo @@ -934,6 +943,23 @@ proc main {server port} { format $delta } {0} + test {ZINCRBY - can create a new sorted set} { + $r del zset + $r zincrby zset 1 foo + list [$r zrange zset 0 -1] [$r zscore zset foo] + } {foo 1} + + test {ZINCRBY - increment and decrement} { + $r zincrby zset 2 foo + $r zincrby zset 1 bar + set v1 [$r zrange zset 0 -1] + $r zincrby zset 10 bar + $r zincrby zset -5 foo + $r zincrby zset -5 bar + set v2 [$r zrange zset 0 -1] + list $v1 $v2 [$r zscore zset foo] [$r zscore zset bar] + } {{bar foo} {foo bar} -2 6} + test {EXPIRE - don't set timeouts multiple times} { $r set x foobar set v1 [$r expire x 5] -- GitLab