X-Git-Url: https://git.saurik.com/redis.git/blobdiff_plain/af4e866dbb1455a50d51b3d5f46832f1a36e2080..7c0e1b53c4c4f646c788fcd09666e1c321c1d134:/src/sort.c diff --git a/src/sort.c b/src/sort.c index 0bc86b47..ff275c95 100644 --- a/src/sort.c +++ b/src/sort.c @@ -76,7 +76,7 @@ robj *lookupKeyByPattern(redisDb *db, robj *pattern, robj *subst) { /* Retrieve value from hash by the field name. This operation * already increases the refcount of the returned object. */ initStaticStringObject(fieldobj,((char*)&fieldname)+(sizeof(struct sdshdr))); - o = hashTypeGet(o, &fieldobj); + o = hashTypeGetObject(o, &fieldobj); } else { if (o->type != REDIS_STRING) return NULL; @@ -199,10 +199,13 @@ void sortCommand(redisClient *c) { j++; } + /* Destructively convert encoded sorted sets for SORT. */ + if (sortval->type == REDIS_ZSET) zsetConvert(sortval, REDIS_ENCODING_SKIPLIST); + /* Load the sorting vector with all the objects to sort */ switch(sortval->type) { case REDIS_LIST: vectorlen = listTypeLength(sortval); break; - case REDIS_SET: vectorlen = dictSize((dict*)sortval->ptr); break; + case REDIS_SET: vectorlen = setTypeSize(sortval); break; case REDIS_ZSET: vectorlen = dictSize(((zset*)sortval->ptr)->dict); break; default: vectorlen = 0; redisPanic("Bad SORT type"); /* Avoid GCC warning */ } @@ -219,18 +222,20 @@ void sortCommand(redisClient *c) { j++; } listTypeReleaseIterator(li); - } else { - dict *set; + } else if (sortval->type == REDIS_SET) { + setTypeIterator *si = setTypeInitIterator(sortval); + robj *ele; + while((ele = setTypeNextObject(si)) != NULL) { + vector[j].obj = ele; + vector[j].u.score = 0; + vector[j].u.cmpobj = NULL; + j++; + } + setTypeReleaseIterator(si); + } else if (sortval->type == REDIS_ZSET) { + dict *set = ((zset*)sortval->ptr)->dict; dictIterator *di; dictEntry *setele; - - if (sortval->type == REDIS_SET) { - set = sortval->ptr; - } else { - zset *zs = sortval->ptr; - set = zs->dict; - } - di = dictGetIterator(set); while((setele = dictNext(di)) != NULL) { vector[j].obj = dictGetEntryKey(setele); @@ -239,6 +244,8 @@ void sortCommand(redisClient *c) { j++; } dictReleaseIterator(di); + } else { + redisPanic("Unknown type"); } redisAssert(j == vectorlen); @@ -303,7 +310,7 @@ void sortCommand(redisClient *c) { outputlen = getop ? getop*(end-start+1) : end-start+1; if (storekey == NULL) { /* STORE option not specified, sent the sorting result to client */ - addReplySds(c,sdscatprintf(sdsempty(),"*%d\r\n",outputlen)); + addReplyMultiBulkLen(c,outputlen); for (j = start; j <= end; j++) { listNode *ln; listIter li; @@ -364,11 +371,12 @@ void sortCommand(redisClient *c) { * SORT result is empty a new key is set and maybe the old content * replaced. */ server.dirty += 1+outputlen; - addReplySds(c,sdscatprintf(sdsempty(),":%d\r\n",outputlen)); + signalModifiedKey(c->db,storekey); + addReplyLongLong(c,outputlen); } /* Cleanup */ - if (sortval->type == REDIS_LIST) + if (sortval->type == REDIS_LIST || sortval->type == REDIS_SET) for (j = 0; j < vectorlen; j++) decrRefCount(vector[j].obj); decrRefCount(sortval);