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
5d1b27f4f9
commit
cc04253b1d
@ -668,6 +668,11 @@ struct commandHelp {
|
|||||||
"Remove elements from a list",
|
"Remove elements from a list",
|
||||||
2,
|
2,
|
||||||
"1.0.0" },
|
"1.0.0" },
|
||||||
|
{ "LRANK",
|
||||||
|
"key direction element",
|
||||||
|
"Return first index of element in list based on direction",
|
||||||
|
2,
|
||||||
|
"9.9.9" },
|
||||||
{ "LSET",
|
{ "LSET",
|
||||||
"key index element",
|
"key index element",
|
||||||
"Set the value of an element in a list by its index",
|
"Set the value of an element in a list by its index",
|
||||||
|
@ -326,6 +326,10 @@ struct redisCommand redisCommandTable[] = {
|
|||||||
"write @list",
|
"write @list",
|
||||||
0,NULL,1,1,1,0,0,0},
|
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,
|
{"lrem",lremCommand,4,
|
||||||
"write @list",
|
"write @list",
|
||||||
0,NULL,1,1,1,0,0,0},
|
0,NULL,1,1,1,0,0,0},
|
||||||
|
@ -2269,6 +2269,7 @@ void flushdbCommand(client *c);
|
|||||||
void flushallCommand(client *c);
|
void flushallCommand(client *c);
|
||||||
void sortCommand(client *c);
|
void sortCommand(client *c);
|
||||||
void lremCommand(client *c);
|
void lremCommand(client *c);
|
||||||
|
void lrankCommand(client *c);
|
||||||
void rpoplpushCommand(client *c);
|
void rpoplpushCommand(client *c);
|
||||||
void infoCommand(client *c);
|
void infoCommand(client *c);
|
||||||
void mgetCommand(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);
|
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) {
|
void lremCommand(client *c) {
|
||||||
robj *subject, *obj;
|
robj *subject, *obj;
|
||||||
obj = c->argv[3];
|
obj = c->argv[3];
|
||||||
|
Loading…
x
Reference in New Issue
Block a user