Skip to content
GitLab
Menu
Projects
Groups
Snippets
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Menu
Open sidebar
ruanhaishen
redis
Commits
443c6409
Commit
443c6409
authored
Nov 01, 2009
by
antirez
Browse files
SORT STORE option
parent
d8f8b666
Changes
3
Show whitespace changes
Inline
Side-by-side
TODO
View file @
443c6409
...
@@ -21,7 +21,6 @@ LONG TERM TODO
...
@@ -21,7 +21,6 @@ LONG TERM TODO
* Add a command to inspect the currently selected DB index
* Add a command to inspect the currently selected DB index
* Consistent hashing implemented in all the client libraries having an user base
* Consistent hashing implemented in all the client libraries having an user base
* SORT: Don't copy the list into a vector when BY argument is constant.
* SORT: Don't copy the list into a vector when BY argument is constant.
* SORT ... STORE keyname. Instead to return the SORTed data set it into key.
* Profiling and optimization in order to limit the CPU usage at minimum
* Profiling and optimization in order to limit the CPU usage at minimum
* Write the hash table size of every db in the dump, so that Redis can resize the hash table just one time when loading a big DB.
* Write the hash table size of every db in the dump, so that Redis can resize the hash table just one time when loading a big DB.
* Elapsed time in logs for SAVE when saving is going to take more than 2 seconds
* Elapsed time in logs for SAVE when saving is going to take more than 2 seconds
...
...
redis-cli.c
View file @
443c6409
...
@@ -239,6 +239,7 @@ static int cliReadReply(int fd) {
...
@@ -239,6 +239,7 @@ static int cliReadReply(int fd) {
return
1
;
return
1
;
case
'+'
:
case
'+'
:
case
':'
:
case
':'
:
printf
(
"(integer) "
);
return
cliReadSingleLineReply
(
fd
);
return
cliReadSingleLineReply
(
fd
);
case
'$'
:
case
'$'
:
return
cliReadBulkReply
(
fd
);
return
cliReadBulkReply
(
fd
);
...
...
redis.c
View file @
443c6409
...
@@ -172,11 +172,8 @@
...
@@ -172,11 +172,8 @@
/* Sort operations */
/* Sort operations */
#define REDIS_SORT_GET 0
#define REDIS_SORT_GET 0
#define REDIS_SORT_DEL 1
#define REDIS_SORT_ASC 1
#define REDIS_SORT_INCR 2
#define REDIS_SORT_DESC 2
#define REDIS_SORT_DECR 3
#define REDIS_SORT_ASC 4
#define REDIS_SORT_DESC 5
#define REDIS_SORTKEY_MAX 1024
#define REDIS_SORTKEY_MAX 1024
/* Log levels */
/* Log levels */
...
@@ -4447,7 +4444,7 @@ static void sortCommand(redisClient *c) {
...
@@ -4447,7 +4444,7 @@ static void sortCommand(redisClient *c) {
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;
int getop = 0; /* GET operation counter */
int getop = 0; /* GET operation counter */
robj *sortval, *sortby = NULL;
robj *sortval, *sortby =
NULL, *storekey =
NULL;
redisSortObject *vector; /* Resulting vector to sort */
redisSortObject *vector; /* Resulting vector to sort */
/* Lookup the key to sort. It must be of the right types */
/* Lookup the key to sort. It must be of the right types */
...
@@ -4485,6 +4482,9 @@ static void sortCommand(redisClient *c) {
...
@@ -4485,6 +4482,9 @@ static void sortCommand(redisClient *c) {
limit_start = atoi(c->argv[j+1]->ptr);
limit_start = atoi(c->argv[j+1]->ptr);
limit_count = atoi(c->argv[j+2]->ptr);
limit_count = atoi(c->argv[j+2]->ptr);
j+=2;
j+=2;
} else if (!strcasecmp(c->argv[j]->ptr,"store") && leftargs >= 1) {
storekey = c->argv[j+1];
j++;
} else if (!strcasecmp(c->argv[j]->ptr,"by") && leftargs >= 1) {
} else if (!strcasecmp(c->argv[j]->ptr,"by") && leftargs >= 1) {
sortby = c->argv[j+1];
sortby = c->argv[j+1];
/* If the BY pattern does not contain '*', i.e. it is constant,
/* If the BY pattern does not contain '*', i.e. it is constant,
...
@@ -4496,18 +4496,6 @@ static void sortCommand(redisClient *c) {
...
@@ -4496,18 +4496,6 @@ static void sortCommand(redisClient *c) {
REDIS_SORT_GET,c->argv[j+1]));
REDIS_SORT_GET,c->argv[j+1]));
getop++;
getop++;
j++;
j++;
} else if (!strcasecmp(c->argv[j]->ptr,"del") && leftargs >= 1) {
listAddNodeTail(operations,createSortOperation(
REDIS_SORT_DEL,c->argv[j+1]));
j++;
} else if (!strcasecmp(c->argv[j]->ptr,"incr") && leftargs >= 1) {
listAddNodeTail(operations,createSortOperation(
REDIS_SORT_INCR,c->argv[j+1]));
j++;
} else if (!strcasecmp(c->argv[j]->ptr,"get") && leftargs >= 1) {
listAddNodeTail(operations,createSortOperation(
REDIS_SORT_DECR,c->argv[j+1]));
j++;
} else {
} else {
decrRefCount(sortval);
decrRefCount(sortval);
listRelease(operations);
listRelease(operations);
...
@@ -4614,6 +4602,8 @@ static void sortCommand(redisClient *c) {
...
@@ -4614,6 +4602,8 @@ static void sortCommand(redisClient *c) {
/* Send command output to the output buffer, performing the specified
/* Send command output to the output buffer, performing the specified
* GET/DEL/INCR/DECR operations if any. */
* GET/DEL/INCR/DECR operations if any. */
outputlen = getop ? getop*(end-start+1) : end-start+1;
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));
addReplySds(c,sdscatprintf(sdsempty(),"*%d\r\n",outputlen));
for (j = start; j <= end; j++) {
for (j = start; j <= end; j++) {
listNode *ln;
listNode *ln;
...
@@ -4636,10 +4626,46 @@ static void sortCommand(redisClient *c) {
...
@@ -4636,10 +4626,46 @@ static void sortCommand(redisClient *c) {
addReply(c,val);
addReply(c,val);
addReply(c,shared.crlf);
addReply(c,shared.crlf);
}
}
} else if (sop->type == REDIS_SORT_DEL) {
} else {
/* TODO */
assert(sop->type == REDIS_SORT_GET); /* always fails */
}
}
}
} else {
robj *listObject = createListObject();
list *listPtr = (list*) listObject->ptr;
/* STORE option specified, set the sorting result as a List object */
for (j = start; j <= end; j++) {
listNode *ln;
if (!getop) {
listAddNodeTail(listPtr,vector[j].obj);
incrRefCount(vector[j].obj);
}
listRewind(operations);
while((ln = listYield(operations))) {
redisSortOperation *sop = ln->value;
robj *val = lookupKeyByPattern(c->db,sop->pattern,
vector[j].obj);
if (sop->type == REDIS_SORT_GET) {
if (!val || val->type != REDIS_STRING) {
listAddNodeTail(listPtr,createStringObject("",0));
} else {
listAddNodeTail(listPtr,val);
incrRefCount(val);
}
} else {
assert(sop->type == REDIS_SORT_GET); /* always fails */
}
}
}
}
}
dictReplace(c->db->dict,storekey,listObject);
/* Note: we add 1 because the DB is dirty anyway since even if the
* 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));
}
}
/* Cleanup */
/* Cleanup */
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment