Support dual encoding for more commands

This commit is contained in:
Pieter Noordhuis 2011-03-09 12:37:59 +01:00
parent aff255c81d
commit d1c920c538

View File

@ -658,7 +658,7 @@ int zzlInsert(robj *zobj, robj *ele, double score) {
break; break;
} else if (s == score) { } else if (s == score) {
/* Ensure lexicographical ordering for elements. */ /* Ensure lexicographical ordering for elements. */
if (zzlCompareElements(eptr,ele->ptr,sdslen(ele->ptr)) < 0) { if (zzlCompareElements(eptr,ele->ptr,sdslen(ele->ptr)) > 0) {
zzlInsertAt(zobj,ele,score,eptr); zzlInsertAt(zobj,ele,score,eptr);
break; break;
} }
@ -1505,66 +1505,103 @@ void zcountCommand(redisClient *c) {
} }
void zcardCommand(redisClient *c) { void zcardCommand(redisClient *c) {
robj *o; robj *key = c->argv[1];
zset *zs; robj *zobj;
if ((o = lookupKeyReadOrReply(c,c->argv[1],shared.czero)) == NULL || if ((zobj = lookupKeyReadOrReply(c,key,shared.czero)) == NULL ||
checkType(c,o,REDIS_ZSET)) return; checkType(c,zobj,REDIS_ZSET)) return;
zs = o->ptr; addReplyLongLong(c,zzlLength(zobj));
addReplyLongLong(c,zs->zsl->length);
} }
void zscoreCommand(redisClient *c) { void zscoreCommand(redisClient *c) {
robj *o; robj *key = c->argv[1];
zset *zs; robj *zobj;
dictEntry *de; double score;
if ((o = lookupKeyReadOrReply(c,c->argv[1],shared.nullbulk)) == NULL || if ((zobj = lookupKeyReadOrReply(c,key,shared.nullbulk)) == NULL ||
checkType(c,o,REDIS_ZSET)) return; checkType(c,zobj,REDIS_ZSET)) return;
zs = o->ptr; if (zobj->encoding == REDIS_ENCODING_ZIPLIST) {
c->argv[2] = tryObjectEncoding(c->argv[2]); if (zzlFind(zobj,c->argv[2],&score) != NULL)
de = dictFind(zs->dict,c->argv[2]); addReplyDouble(c,score);
if (!de) { else
addReply(c,shared.nullbulk); addReply(c,shared.nullbulk);
} else if (zobj->encoding == REDIS_ENCODING_RAW) {
zset *zs = zobj->ptr;
dictEntry *de;
c->argv[2] = tryObjectEncoding(c->argv[2]);
de = dictFind(zs->dict,c->argv[2]);
if (de != NULL) {
score = *(double*)dictGetEntryVal(de);
addReplyDouble(c,score);
} else {
addReply(c,shared.nullbulk);
}
} else { } else {
double *score = dictGetEntryVal(de); redisPanic("Unknown sorted set encoding");
addReplyDouble(c,*score);
} }
} }
void zrankGenericCommand(redisClient *c, int reverse) { void zrankGenericCommand(redisClient *c, int reverse) {
robj *o; robj *key = c->argv[1];
zset *zs; robj *ele = c->argv[2];
zskiplist *zsl; robj *zobj;
dictEntry *de; unsigned long llen;
unsigned long rank; unsigned long rank;
double *score;
if ((o = lookupKeyReadOrReply(c,c->argv[1],shared.nullbulk)) == NULL || if ((zobj = lookupKeyReadOrReply(c,key,shared.nullbulk)) == NULL ||
checkType(c,o,REDIS_ZSET)) return; checkType(c,zobj,REDIS_ZSET)) return;
llen = zsLength(zobj);
zs = o->ptr; redisAssert(ele->encoding == REDIS_ENCODING_RAW);
zsl = zs->zsl; if (zobj->encoding == REDIS_ENCODING_ZIPLIST) {
c->argv[2] = tryObjectEncoding(c->argv[2]); unsigned char *zl = zobj->ptr;
de = dictFind(zs->dict,c->argv[2]); unsigned char *eptr, *sptr;
if (!de) {
addReply(c,shared.nullbulk);
return;
}
score = dictGetEntryVal(de); eptr = ziplistIndex(zl,0);
rank = zslGetRank(zsl, *score, c->argv[2]); redisAssert(eptr != NULL);
if (rank) { sptr = ziplistNext(zl,eptr);
if (reverse) { redisAssert(sptr != NULL);
addReplyLongLong(c, zsl->length - rank);
rank = 1;
while(eptr != NULL) {
if (ziplistCompare(eptr,ele->ptr,sdslen(ele->ptr)))
break;
rank++;
zzlNext(zl,&eptr,&sptr);
}
if (eptr != NULL) {
if (reverse)
addReplyLongLong(c,llen-rank);
else
addReplyLongLong(c,rank-1);
} else { } else {
addReplyLongLong(c, rank-1); addReply(c,shared.nullbulk);
}
} else if (zobj->encoding == REDIS_ENCODING_RAW) {
zset *zs = zobj->ptr;
zskiplist *zsl = zs->zsl;
dictEntry *de;
double score;
ele = c->argv[2] = tryObjectEncoding(c->argv[2]);
de = dictFind(zs->dict,ele);
if (de != NULL) {
score = *(double*)dictGetEntryVal(de);
rank = zslGetRank(zsl,score,ele);
redisAssert(rank); /* Existing elements always have a rank. */
if (reverse)
addReplyLongLong(c,llen-rank);
else
addReplyLongLong(c,rank-1);
} else {
addReply(c,shared.nullbulk);
} }
} else { } else {
addReply(c,shared.nullbulk); redisPanic("Unknown sorted set encoding");
} }
} }