提交 a7936ef9 编写于 作者: P Paul Spooren 提交者: antirez

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/1197Signed-off-by: NPaul Spooren <mail@aparcar.org>
上级 2ebcd63d
......@@ -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);
......
......@@ -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];
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册