Skip to content

Commit

Permalink
Merge pull request twitter#254 from idning/xscan
Browse files Browse the repository at this point in the history
hscan/sscan/zscan supported
  • Loading branch information
idning committed Aug 29, 2014
2 parents f6cc55b + efece2e commit b72c722
Show file tree
Hide file tree
Showing 3 changed files with 45 additions and 3 deletions.
6 changes: 3 additions & 3 deletions notes/redis.md
Original file line number Diff line number Diff line change
Expand Up @@ -131,7 +131,7 @@
+-------------------+------------+---------------------------------------------------------------------------------------------------------------------+
| HVALS | Yes | HVALS key |
+-------------------+------------+---------------------------------------------------------------------------------------------------------------------+
| HSCAN | No | HSCAN key cursor [MATCH pattern] [COUNT count] |
| HSCAN | Yes | HSCAN key cursor [MATCH pattern] [COUNT count] |
+-------------------+------------+---------------------------------------------------------------------------------------------------------------------+

### Lists
Expand Down Expand Up @@ -209,7 +209,7 @@
+-------------------+------------+---------------------------------------------------------------------------------------------------------------------+
| SUNIONSTORE | Yes* | SUNIONSTORE destination key [key ...] |
+-------------------+------------+---------------------------------------------------------------------------------------------------------------------+
| SSCAN | No | SSCAN key cursor [MATCH pattern] [COUNT count] |
| SSCAN | Yes | SSCAN key cursor [MATCH pattern] [COUNT count] |
+-------------------+------------+---------------------------------------------------------------------------------------------------------------------+

* SIDFF, SDIFFSTORE, SINTER, SINTERSTORE, SMOVE, SUNION and SUNIONSTORE support requires that the supplied keys hash to the same server. You can ensure this by using the same [hashtag](notes/recommendation.md#hash-tags) for all keys in the command. Twemproxy does no checking on its end to verify that all the keys hash to the same server, and the given command is forwarded to the server that the first key hashes to.
Expand Down Expand Up @@ -258,7 +258,7 @@
+-------------------+------------+---------------------------------------------------------------------------------------------------------------------+
| ZUNIONSTORE | Yes* | ZUNIONSTORE destination numkeys key [key ...] [WEIGHTS weight [weight ...]] [AGGREGATE SUM|MIN|MAX] |
+-------------------+------------+---------------------------------------------------------------------------------------------------------------------+
| ZSCAN | No | ZSCAN key cursor [MATCH pattern] [COUNT count] |
| ZSCAN | Yes | ZSCAN key cursor [MATCH pattern] [COUNT count] |
+-------------------+------------+---------------------------------------------------------------------------------------------------------------------+

* ZINTERSTORE and ZUNIONSTORE support requires that the supplied keys hash to the same server. You can ensure this by using the same [hashtag](notes/recommendation.md#hash-tags) for all keys in the command. Twemproxy does no checking on its end to verify that all the keys hash to the same server, and the given command is forwarded to the server that the first key hashes to.
Expand Down
3 changes: 3 additions & 0 deletions src/nc_message.h
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,7 @@ typedef enum msg_parse_result {
ACTION( REQ_REDIS_HMSET ) \
ACTION( REQ_REDIS_HSET ) \
ACTION( REQ_REDIS_HSETNX ) \
ACTION( REQ_REDIS_HSCAN) \
ACTION( REQ_REDIS_HVALS ) \
ACTION( REQ_REDIS_LINDEX ) /* redis requests - lists */ \
ACTION( REQ_REDIS_LINSERT ) \
Expand Down Expand Up @@ -132,6 +133,7 @@ typedef enum msg_parse_result {
ACTION( REQ_REDIS_SREM ) \
ACTION( REQ_REDIS_SUNION ) \
ACTION( REQ_REDIS_SUNIONSTORE ) \
ACTION( REQ_REDIS_SSCAN) \
ACTION( REQ_REDIS_ZADD ) /* redis requests - sorted sets */ \
ACTION( REQ_REDIS_ZCARD ) \
ACTION( REQ_REDIS_ZCOUNT ) \
Expand All @@ -151,6 +153,7 @@ typedef enum msg_parse_result {
ACTION( REQ_REDIS_ZREVRANK ) \
ACTION( REQ_REDIS_ZSCORE ) \
ACTION( REQ_REDIS_ZUNIONSTORE ) \
ACTION( REQ_REDIS_ZSCAN) \
ACTION( REQ_REDIS_EVAL ) /* redis requests - eval */ \
ACTION( REQ_REDIS_EVALSHA ) \
ACTION( RSP_REDIS_STATUS ) /* redis response */ \
Expand Down
39 changes: 39 additions & 0 deletions src/proto/nc_redis.c
Original file line number Diff line number Diff line change
Expand Up @@ -184,6 +184,7 @@ redis_argn(struct msg *r)
case MSG_REQ_REDIS_HDEL:
case MSG_REQ_REDIS_HMGET:
case MSG_REQ_REDIS_HMSET:
case MSG_REQ_REDIS_HSCAN:

case MSG_REQ_REDIS_LPUSH:
case MSG_REQ_REDIS_RPUSH:
Expand All @@ -197,6 +198,7 @@ redis_argn(struct msg *r)
case MSG_REQ_REDIS_SUNION:
case MSG_REQ_REDIS_SUNIONSTORE:
case MSG_REQ_REDIS_SRANDMEMBER:
case MSG_REQ_REDIS_SSCAN:

case MSG_REQ_REDIS_PFADD:
case MSG_REQ_REDIS_PFMERGE:
Expand All @@ -210,6 +212,7 @@ redis_argn(struct msg *r)
case MSG_REQ_REDIS_ZRANGEBYLEX:
case MSG_REQ_REDIS_ZREVRANGEBYSCORE:
case MSG_REQ_REDIS_ZUNIONSTORE:
case MSG_REQ_REDIS_ZSCAN:
return true;

default:
Expand Down Expand Up @@ -608,6 +611,11 @@ redis_parse_req(struct msg *r)
break;
}

if (str5icmp(m, 'h', 's', 'c', 'a', 'n')) {
r->type = MSG_REQ_REDIS_HSCAN;
break;
}

if (str5icmp(m, 'l', 'p', 'u', 's', 'h')) {
r->type = MSG_REQ_REDIS_LPUSH;
break;
Expand Down Expand Up @@ -648,6 +656,11 @@ redis_parse_req(struct msg *r)
break;
}

if (str5icmp(m, 's', 's', 'c', 'a', 'n')) {
r->type = MSG_REQ_REDIS_SSCAN;
break;
}

if (str5icmp(m, 'z', 'c', 'a', 'r', 'd')) {
r->type = MSG_REQ_REDIS_ZCARD;
break;
Expand All @@ -658,6 +671,11 @@ redis_parse_req(struct msg *r)
break;
}

if (str5icmp(m, 'z', 's', 'c', 'a', 'n')) {
r->type = MSG_REQ_REDIS_ZSCAN;
break;
}

if (str5icmp(m, 'p', 'f', 'a', 'd', 'd')) {
r->type = MSG_REQ_REDIS_PFADD;
break;
Expand Down Expand Up @@ -1859,7 +1877,28 @@ redis_parse_rsp(struct msg *r)
*
* Here, we only handle a multi bulk reply element that
* are either integer reply or bulk reply.
*
* there is a special case for sscan/hscan/zscan, these command
* replay a nested multi-bulk with a number and a multi bulk like this:
*
* - mulit-bulk
* - cursor
* - mulit-bulk
* - val1
* - val2
* - val3
*
* in this case, there is only one sub-multi-bulk,
* and it's the last element of parent,
* we can handle it like tail-recursive.
*
*/
if (ch == '*') { /* for sscan/hscan/zscan only */
p = p - 1; /* go back by 1 byte */
state = SW_MULTIBULK;
break;
}

if (ch != '$' && ch != ':') {
goto error;
}
Expand Down

0 comments on commit b72c722

Please sign in to comment.