mirror of
https://github.com/fluencelabs/redis
synced 2025-03-19 09:00:51 +00:00
update SORT to work with the dual list encoding
This commit is contained in:
parent
1cd92e7f04
commit
a03611e133
65
redis.c
65
redis.c
@ -7210,7 +7210,7 @@ static int sortCompare(const void *s1, const void *s2) {
|
|||||||
* is optimized for speed and a bit less for readability */
|
* is optimized for speed and a bit less for readability */
|
||||||
static void sortCommand(redisClient *c) {
|
static void sortCommand(redisClient *c) {
|
||||||
list *operations;
|
list *operations;
|
||||||
int outputlen = 0;
|
unsigned int outputlen = 0;
|
||||||
int desc = 0, alpha = 0;
|
int desc = 0, alpha = 0;
|
||||||
int limit_start = 0, limit_count = -1, start, end;
|
int limit_start = 0, limit_count = -1, start, end;
|
||||||
int j, dontsort = 0, vectorlen;
|
int j, dontsort = 0, vectorlen;
|
||||||
@ -7280,7 +7280,7 @@ static void sortCommand(redisClient *c) {
|
|||||||
|
|
||||||
/* Load the sorting vector with all the objects to sort */
|
/* Load the sorting vector with all the objects to sort */
|
||||||
switch(sortval->type) {
|
switch(sortval->type) {
|
||||||
case REDIS_LIST: vectorlen = listLength((list*)sortval->ptr); break;
|
case REDIS_LIST: vectorlen = lLength(sortval); break;
|
||||||
case REDIS_SET: vectorlen = dictSize((dict*)sortval->ptr); break;
|
case REDIS_SET: vectorlen = dictSize((dict*)sortval->ptr); break;
|
||||||
case REDIS_ZSET: vectorlen = dictSize(((zset*)sortval->ptr)->dict); break;
|
case REDIS_ZSET: vectorlen = dictSize(((zset*)sortval->ptr)->dict); break;
|
||||||
default: vectorlen = 0; redisPanic("Bad SORT type"); /* Avoid GCC warning */
|
default: vectorlen = 0; redisPanic("Bad SORT type"); /* Avoid GCC warning */
|
||||||
@ -7289,18 +7289,15 @@ static void sortCommand(redisClient *c) {
|
|||||||
j = 0;
|
j = 0;
|
||||||
|
|
||||||
if (sortval->type == REDIS_LIST) {
|
if (sortval->type == REDIS_LIST) {
|
||||||
list *list = sortval->ptr;
|
lIterator *li = lInitIterator(sortval,0,REDIS_TAIL);
|
||||||
listNode *ln;
|
lEntry entry;
|
||||||
listIter li;
|
while(lNext(li,&entry)) {
|
||||||
|
vector[j].obj = lGet(&entry);
|
||||||
listRewind(list,&li);
|
|
||||||
while((ln = listNext(&li))) {
|
|
||||||
robj *ele = ln->value;
|
|
||||||
vector[j].obj = ele;
|
|
||||||
vector[j].u.score = 0;
|
vector[j].u.score = 0;
|
||||||
vector[j].u.cmpobj = NULL;
|
vector[j].u.cmpobj = NULL;
|
||||||
j++;
|
j++;
|
||||||
}
|
}
|
||||||
|
lReleaseIterator(li);
|
||||||
} else {
|
} else {
|
||||||
dict *set;
|
dict *set;
|
||||||
dictIterator *di;
|
dictIterator *di;
|
||||||
@ -7410,8 +7407,12 @@ static void sortCommand(redisClient *c) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
robj *listObject = createListObject();
|
robj *sobj;
|
||||||
list *listPtr = (list*) listObject->ptr;
|
if (outputlen > server.list_max_ziplist_entries) {
|
||||||
|
sobj = createListObject();
|
||||||
|
} else {
|
||||||
|
sobj = createZiplistObject();
|
||||||
|
}
|
||||||
|
|
||||||
/* STORE option specified, set the sorting result as a List object */
|
/* STORE option specified, set the sorting result as a List object */
|
||||||
for (j = start; j <= end; j++) {
|
for (j = start; j <= end; j++) {
|
||||||
@ -7419,31 +7420,30 @@ static void sortCommand(redisClient *c) {
|
|||||||
listIter li;
|
listIter li;
|
||||||
|
|
||||||
if (!getop) {
|
if (!getop) {
|
||||||
listAddNodeTail(listPtr,vector[j].obj);
|
lPush(sobj,vector[j].obj,REDIS_TAIL);
|
||||||
incrRefCount(vector[j].obj);
|
} else {
|
||||||
}
|
listRewind(operations,&li);
|
||||||
listRewind(operations,&li);
|
while((ln = listNext(&li))) {
|
||||||
while((ln = listNext(&li))) {
|
redisSortOperation *sop = ln->value;
|
||||||
redisSortOperation *sop = ln->value;
|
robj *val = lookupKeyByPattern(c->db,sop->pattern,
|
||||||
robj *val = lookupKeyByPattern(c->db,sop->pattern,
|
vector[j].obj);
|
||||||
vector[j].obj);
|
|
||||||
|
|
||||||
if (sop->type == REDIS_SORT_GET) {
|
if (sop->type == REDIS_SORT_GET) {
|
||||||
if (!val) {
|
if (!val) val = createStringObject("",0);
|
||||||
listAddNodeTail(listPtr,createStringObject("",0));
|
|
||||||
|
/* lPush does an incrRefCount, so we should take care
|
||||||
|
* care of the incremented refcount caused by either
|
||||||
|
* lookupKeyByPattern or createStringObject("",0) */
|
||||||
|
lPush(sobj,val,REDIS_TAIL);
|
||||||
|
decrRefCount(val);
|
||||||
} else {
|
} else {
|
||||||
/* We should do a incrRefCount on val because it is
|
/* always fails */
|
||||||
* added to the list, but also a decrRefCount because
|
redisAssert(sop->type == REDIS_SORT_GET);
|
||||||
* it is returned by lookupKeyByPattern. This results
|
|
||||||
* in doing nothing at all. */
|
|
||||||
listAddNodeTail(listPtr,val);
|
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
redisAssert(sop->type == REDIS_SORT_GET); /* always fails */
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (dictReplace(c->db->dict,storekey,listObject)) {
|
if (dictReplace(c->db->dict,storekey,sobj)) {
|
||||||
incrRefCount(storekey);
|
incrRefCount(storekey);
|
||||||
}
|
}
|
||||||
/* Note: we add 1 because the DB is dirty anyway since even if the
|
/* Note: we add 1 because the DB is dirty anyway since even if the
|
||||||
@ -7454,6 +7454,9 @@ static void sortCommand(redisClient *c) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Cleanup */
|
/* Cleanup */
|
||||||
|
if (sortval->type == REDIS_LIST)
|
||||||
|
for (j = 0; j < vectorlen; j++)
|
||||||
|
decrRefCount(vector[j].obj);
|
||||||
decrRefCount(sortval);
|
decrRefCount(sortval);
|
||||||
listRelease(operations);
|
listRelease(operations);
|
||||||
for (j = 0; j < vectorlen; j++) {
|
for (j = 0; j < vectorlen; j++) {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user