LRANK: Add command (the command will be renamed LPOS).
The `LRANK` command returns the index (position) of a given element within a list. Using the `direction` argument it is possible to specify going from head to tail (acending, 1) or from tail to head (decending, -1). Only the first found index is returend. The complexity is O(N). When using lists as a queue it can be of interest at what position a given element is, for instance to monitor a job processing through a work queue. This came up within the Python `rq` project which is based on Redis[0]. [0]: https://github.com/rq/rq/issues/1197 Signed-off-by: Paul Spooren <mail@aparcar.org>
This commit is contained in:
parent
2ebcd63d6a
commit
a7936ef96d
@ -668,6 +668,11 @@ struct commandHelp {
|
||||
"Remove elements from a list",
|
||||
2,
|
||||
"1.0.0" },
|
||||
{ "LRANK",
|
||||
"key direction element",
|
||||
"Return first index of element in list based on direction",
|
||||
2,
|
||||
"9.9.9" },
|
||||
{ "LSET",
|
||||
"key index element",
|
||||
"Set the value of an element in a list by its index",
|
||||
|
@ -326,6 +326,10 @@ struct redisCommand redisCommandTable[] = {
|
||||
"write @list",
|
||||
0,NULL,1,1,1,0,0,0},
|
||||
|
||||
{"lrank",lrankCommand,4,
|
||||
"read-only fast @list",
|
||||
0,NULL,1,1,1,0,0,0},
|
||||
|
||||
{"lrem",lremCommand,4,
|
||||
"write @list",
|
||||
0,NULL,1,1,1,0,0,0},
|
||||
|
@ -2269,6 +2269,7 @@ void flushdbCommand(client *c);
|
||||
void flushallCommand(client *c);
|
||||
void sortCommand(client *c);
|
||||
void lremCommand(client *c);
|
||||
void lrankCommand(client *c);
|
||||
void rpoplpushCommand(client *c);
|
||||
void infoCommand(client *c);
|
||||
void mgetCommand(client *c);
|
||||
|
34
src/t_list.c
34
src/t_list.c
@ -487,6 +487,40 @@ void ltrimCommand(client *c) {
|
||||
addReply(c,shared.ok);
|
||||
}
|
||||
|
||||
void lrankCommand(client *c) {
|
||||
robj *subject, *obj;
|
||||
obj = c->argv[3];
|
||||
long direction = 0;
|
||||
long index = 0;
|
||||
|
||||
if ((getLongFromObjectOrReply(c, c->argv[2], &direction, NULL) != C_OK))
|
||||
return;
|
||||
|
||||
subject = lookupKeyWriteOrReply(c,c->argv[1],shared.czero);
|
||||
if (subject == NULL || checkType(c,subject,OBJ_LIST)) return;
|
||||
|
||||
listTypeIterator *li;
|
||||
if (direction < 0) {
|
||||
direction = -1;
|
||||
li = listTypeInitIterator(subject,-1,LIST_HEAD);
|
||||
} else {
|
||||
direction = 1;
|
||||
li = listTypeInitIterator(subject,0,LIST_TAIL);
|
||||
}
|
||||
|
||||
listTypeEntry entry;
|
||||
while (listTypeNext(li,&entry)) {
|
||||
if (listTypeEqual(&entry,obj)) {
|
||||
break;
|
||||
}
|
||||
index++;
|
||||
}
|
||||
|
||||
listTypeReleaseIterator(li);
|
||||
|
||||
addReplyLongLong(c,index * direction);
|
||||
}
|
||||
|
||||
void lremCommand(client *c) {
|
||||
robj *subject, *obj;
|
||||
obj = c->argv[3];
|
||||
|
Loading…
x
Reference in New Issue
Block a user