+ addReplyMultiBulkLen(c, withscores ? (rangelen*2) : rangelen);
+
+ if (zobj->encoding == REDIS_ENCODING_ZIPLIST) {
+ unsigned char *zl = zobj->ptr;
+ unsigned char *eptr, *sptr;
+ unsigned char *vstr;
+ unsigned int vlen;
+ long long vlong;
+
+ if (reverse)
+ eptr = ziplistIndex(zl,-2-(2*start));
+ else
+ eptr = ziplistIndex(zl,2*start);
+
+ redisAssert(eptr != NULL);
+ sptr = ziplistNext(zl,eptr);
+
+ while (rangelen--) {
+ redisAssert(eptr != NULL && sptr != NULL);
+ redisAssert(ziplistGet(eptr,&vstr,&vlen,&vlong));
+ if (vstr == NULL)
+ addReplyBulkLongLong(c,vlong);
+ else
+ addReplyBulkCBuffer(c,vstr,vlen);
+
+ if (withscores)
+ addReplyDouble(c,zzlGetScore(sptr));
+
+ if (reverse)
+ zzlPrev(zl,&eptr,&sptr);
+ else
+ zzlNext(zl,&eptr,&sptr);
+ }
+
+ } else if (zobj->encoding == REDIS_ENCODING_RAW) {
+ zset *zs = zobj->ptr;
+ zskiplist *zsl = zs->zsl;
+ zskiplistNode *ln;
+ robj *ele;
+
+ /* Check if starting point is trivial, before doing log(N) lookup. */
+ if (reverse) {
+ ln = zsl->tail;
+ if (start > 0)
+ ln = zslGetElementByRank(zsl,llen-start);
+ } else {
+ ln = zsl->header->level[0].forward;
+ if (start > 0)
+ ln = zslGetElementByRank(zsl,start+1);
+ }
+
+ while(rangelen--) {
+ redisAssert(ln != NULL);
+ ele = ln->obj;
+ addReplyBulk(c,ele);
+ if (withscores)
+ addReplyDouble(c,ln->score);
+ ln = reverse ? ln->backward : ln->level[0].forward;
+ }
+ } else {
+ redisPanic("Unknown sorted set encoding");