Commit e3870fab authored by antirez's avatar antirez
Browse files

backward support to skiplists for ZREVRANGE, still broken, committing since...

backward support to skiplists for ZREVRANGE, still broken, committing since I've to merge the Solaris patches
parent 9b1d5ebb
...@@ -92,6 +92,7 @@ static struct redisCommand cmdTable[] = { ...@@ -92,6 +92,7 @@ static struct redisCommand cmdTable[] = {
{"zadd",4,REDIS_CMD_BULK}, {"zadd",4,REDIS_CMD_BULK},
{"zrem",3,REDIS_CMD_BULK}, {"zrem",3,REDIS_CMD_BULK},
{"zrange",4,REDIS_CMD_INLINE}, {"zrange",4,REDIS_CMD_INLINE},
{"zrevrange",4,REDIS_CMD_INLINE},
{"zlen",2,REDIS_CMD_INLINE}, {"zlen",2,REDIS_CMD_INLINE},
{"incrby",3,REDIS_CMD_INLINE}, {"incrby",3,REDIS_CMD_INLINE},
{"decrby",3,REDIS_CMD_INLINE}, {"decrby",3,REDIS_CMD_INLINE},
......
...@@ -311,12 +311,13 @@ typedef struct _redisSortOperation { ...@@ -311,12 +311,13 @@ typedef struct _redisSortOperation {
typedef struct zskiplistNode { typedef struct zskiplistNode {
struct zskiplistNode **forward; struct zskiplistNode **forward;
struct zskiplistNode *backward;
double score; double score;
robj *obj; robj *obj;
} zskiplistNode; } zskiplistNode;
typedef struct zskiplist { typedef struct zskiplist {
struct zskiplistNode *header; struct zskiplistNode *header, *tail;
long length; long length;
int level; int level;
} zskiplist; } zskiplist;
...@@ -435,6 +436,7 @@ static void msetCommand(redisClient *c); ...@@ -435,6 +436,7 @@ static void msetCommand(redisClient *c);
static void msetnxCommand(redisClient *c); static void msetnxCommand(redisClient *c);
static void zaddCommand(redisClient *c); static void zaddCommand(redisClient *c);
static void zrangeCommand(redisClient *c); static void zrangeCommand(redisClient *c);
static void zrevrangeCommand(redisClient *c);
static void zlenCommand(redisClient *c); static void zlenCommand(redisClient *c);
static void zremCommand(redisClient *c); static void zremCommand(redisClient *c);
...@@ -478,6 +480,7 @@ static struct redisCommand cmdTable[] = { ...@@ -478,6 +480,7 @@ static struct redisCommand cmdTable[] = {
{"zadd",zaddCommand,4,REDIS_CMD_BULK|REDIS_CMD_DENYOOM}, {"zadd",zaddCommand,4,REDIS_CMD_BULK|REDIS_CMD_DENYOOM},
{"zrem",zremCommand,3,REDIS_CMD_BULK}, {"zrem",zremCommand,3,REDIS_CMD_BULK},
{"zrange",zrangeCommand,4,REDIS_CMD_INLINE}, {"zrange",zrangeCommand,4,REDIS_CMD_INLINE},
{"zrevrange",zrevrangeCommand,4,REDIS_CMD_INLINE},
{"zlen",zlenCommand,2,REDIS_CMD_INLINE}, {"zlen",zlenCommand,2,REDIS_CMD_INLINE},
{"incrby",incrbyCommand,3,REDIS_CMD_INLINE|REDIS_CMD_DENYOOM}, {"incrby",incrbyCommand,3,REDIS_CMD_INLINE|REDIS_CMD_DENYOOM},
{"decrby",decrbyCommand,3,REDIS_CMD_INLINE|REDIS_CMD_DENYOOM}, {"decrby",decrbyCommand,3,REDIS_CMD_INLINE|REDIS_CMD_DENYOOM},
...@@ -3721,6 +3724,8 @@ static zskiplist *zslCreate(void) { ...@@ -3721,6 +3724,8 @@ static zskiplist *zslCreate(void) {
zsl->header = zslCreateNode(ZSKIPLIST_MAXLEVEL,0,NULL); zsl->header = zslCreateNode(ZSKIPLIST_MAXLEVEL,0,NULL);
for (j = 0; j < ZSKIPLIST_MAXLEVEL; j++) for (j = 0; j < ZSKIPLIST_MAXLEVEL; j++)
zsl->header->forward[j] = NULL; zsl->header->forward[j] = NULL;
zsl->header->backward = NULL;
zsl->tail = NULL;
return zsl; return zsl;
} }
...@@ -3771,6 +3776,11 @@ static void zslInsert(zskiplist *zsl, double score, robj *obj) { ...@@ -3771,6 +3776,11 @@ static void zslInsert(zskiplist *zsl, double score, robj *obj) {
x->forward[i] = update[i]->forward[i]; x->forward[i] = update[i]->forward[i];
update[i]->forward[i] = x; update[i]->forward[i] = x;
} }
x->backward = (update[0] == zsl->header) ? NULL : update[i];
if (x->forward[0])
x->forward[0]->backward = x;
else
zsl->tail = x;
zsl->length++; zsl->length++;
} }
...@@ -3793,6 +3803,12 @@ static int zslDelete(zskiplist *zsl, double score, robj *obj) { ...@@ -3793,6 +3803,12 @@ static int zslDelete(zskiplist *zsl, double score, robj *obj) {
if (update[i]->forward[i] != x) break; if (update[i]->forward[i] != x) break;
update[i]->forward[i] = x->forward[i]; update[i]->forward[i] = x->forward[i];
} }
if (x->forward[0]) {
x->forward[0]->backward = (x->backward == zsl->header) ?
NULL : x->backward;
} else {
zsl->tail = x->backward;
}
zslFreeNode(x); zslFreeNode(x);
while(zsl->level > 1 && zsl->header->forward[zsl->level-1] == NULL) while(zsl->level > 1 && zsl->header->forward[zsl->level-1] == NULL)
zsl->level--; zsl->level--;
...@@ -3890,7 +3906,7 @@ static void zremCommand(redisClient *c) { ...@@ -3890,7 +3906,7 @@ static void zremCommand(redisClient *c) {
} }
} }
static void zrangeCommand(redisClient *c) { static void zrangeGenericCommand(redisClient *c, int reverse) {
robj *o; robj *o;
int start = atoi(c->argv[2]->ptr); int start = atoi(c->argv[2]->ptr);
int end = atoi(c->argv[3]->ptr); int end = atoi(c->argv[3]->ptr);
...@@ -3926,9 +3942,15 @@ static void zrangeCommand(redisClient *c) { ...@@ -3926,9 +3942,15 @@ static void zrangeCommand(redisClient *c) {
rangelen = (end-start)+1; rangelen = (end-start)+1;
/* Return the result in form of a multi-bulk reply */ /* Return the result in form of a multi-bulk reply */
ln = zsl->header->forward[0]; if (reverse) {
while (start--) ln = zsl->tail;
ln = ln->forward[0]; while (start--)
ln = ln->backward;
} else {
ln = zsl->header->forward[0];
while (start--)
ln = ln->forward[0];
}
addReplySds(c,sdscatprintf(sdsempty(),"*%d\r\n",rangelen)); addReplySds(c,sdscatprintf(sdsempty(),"*%d\r\n",rangelen));
for (j = 0; j < rangelen; j++) { for (j = 0; j < rangelen; j++) {
...@@ -3936,12 +3958,20 @@ static void zrangeCommand(redisClient *c) { ...@@ -3936,12 +3958,20 @@ static void zrangeCommand(redisClient *c) {
addReplyBulkLen(c,ele); addReplyBulkLen(c,ele);
addReply(c,ele); addReply(c,ele);
addReply(c,shared.crlf); addReply(c,shared.crlf);
ln = ln->forward[0]; ln = reverse ? ln->backward : ln->forward[0];
} }
} }
} }
} }
static void zrangeCommand(redisClient *c) {
zrangeGenericCommand(c,0);
}
static void zrevrangeCommand(redisClient *c) {
zrangeGenericCommand(c,1);
}
static void zlenCommand(redisClient *c) { static void zlenCommand(redisClient *c) {
robj *o; robj *o;
zset *zs; zset *zs;
...@@ -5016,7 +5046,9 @@ static struct redisFunctionSym symsTable[] = { ...@@ -5016,7 +5046,9 @@ static struct redisFunctionSym symsTable[] = {
{"zslDelete",(unsigned long)zslDelete}, {"zslDelete",(unsigned long)zslDelete},
{"createZsetObject",(unsigned long)createZsetObject}, {"createZsetObject",(unsigned long)createZsetObject},
{"zaddCommand",(unsigned long)zaddCommand}, {"zaddCommand",(unsigned long)zaddCommand},
{"zrangeGenericCommand",(unsigned long)zrangeGenericCommand},
{"zrangeCommand",(unsigned long)zrangeCommand}, {"zrangeCommand",(unsigned long)zrangeCommand},
{"zrevrangeCommand",(unsigned long)zrevrangeCommand},
{"zremCommand",(unsigned long)zremCommand}, {"zremCommand",(unsigned long)zremCommand},
{NULL,0} {NULL,0}
}; };
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment