diff --git a/src/db.c b/src/db.c index 6682e573..8b43d4b5 100644 --- a/src/db.c +++ b/src/db.c @@ -1363,6 +1363,34 @@ int *georadiusGetKeys(struct redisCommand *cmd, robj **argv, int argc, int *numk return keys; } +/* XREAD [BLOCK ] [COUNT ] [GROUP ] + * [RETRY ] STREAMS key_1 ID_1 key_2 ID_2 ... + * key_N ID_N */ +int *xreadGetKeys(struct redisCommand *cmd, robj **argv, int argc, int *numkeys) { + int i, num, *keys; + UNUSED(cmd); + + /* We need to seek the last argument that contains "STREAMS", because other + * arguments before may contain it (for example the group name). */ + int streams_pos = -1; + for (i = 1; i < argc; i++) { + char *arg = argv[i]->ptr; + if (!strcasecmp(arg, "streams")) streams_pos = i; + } + + /* Syntax error. */ + if (streams_pos == -1) { + *numkeys = 0; + return NULL; + } + + num = argc - streams_pos - 1; + keys = zmalloc(sizeof(int) * num); + for (i = streams_pos+1; i < argc; i++) keys[i-streams_pos-1] = i; + *numkeys = num; + return keys; +} + /* Slot to Key API. This is used by Redis Cluster in order to obtain in * a fast way a key that belongs to a specified hash slot. This is useful * while rehashing the cluster and in other conditions when we need to diff --git a/src/server.c b/src/server.c index 56b2188e..e1d9abef 100644 --- a/src/server.c +++ b/src/server.c @@ -305,6 +305,7 @@ struct redisCommand redisCommandTable[] = { {"xadd",xaddCommand,-4,"wmF",0,NULL,1,1,1,0,0}, {"xrange",xrangeCommand,-4,"r",0,NULL,1,1,1,0,0}, {"xlen",xlenCommand,2,"rF",0,NULL,1,1,1,0,0}, + {"xread",xreadCommand,-3,"rs",0,xreadGetKeys,1,1,1,0,0}, {"post",securityWarningCommand,-1,"lt",0,NULL,0,0,0,0,0}, {"host:",securityWarningCommand,-1,"lt",0,NULL,0,0,0,0,0}, {"latency",latencyCommand,-2,"aslt",0,NULL,0,0,0,0,0} diff --git a/src/server.h b/src/server.h index 34c5fb06..4b84486e 100644 --- a/src/server.h +++ b/src/server.h @@ -1767,6 +1767,7 @@ int *evalGetKeys(struct redisCommand *cmd, robj **argv, int argc, int *numkeys); int *sortGetKeys(struct redisCommand *cmd, robj **argv, int argc, int *numkeys); int *migrateGetKeys(struct redisCommand *cmd, robj **argv, int argc, int *numkeys); int *georadiusGetKeys(struct redisCommand *cmd, robj **argv, int argc, int *numkeys); +int *xreadGetKeys(struct redisCommand *cmd, robj **argv, int argc, int *numkeys); /* Cluster */ void clusterInit(void); @@ -2011,6 +2012,7 @@ void securityWarningCommand(client *c); void xaddCommand(client *c); void xrangeCommand(client *c); void xlenCommand(client *c); +void xreadCommand(client *c); #if defined(__GNUC__) void *calloc(size_t count, size_t size) __attribute__ ((deprecated));