summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRobey Pointer <robey@twitter.com>2010-08-02 19:01:56 -0700
committerRobey Pointer <robey@twitter.com>2010-08-02 19:01:56 -0700
commit0b6677608d54ba31d338ed23fb50754890b97e4d (patch)
tree3dd228016af2369f2a787c590def57056fcb432a
parent0c7a9dec651aa15857da30b95cca7079490725ab (diff)
downloadredis-0b6677608d54ba31d338ed23fb50754890b97e4d.tar.gz
add LISMEMBER.twitter-20100804
-rw-r--r--src/redis.c1
-rw-r--r--src/redis.h1
-rw-r--r--src/t_list.c29
-rw-r--r--tests/unit/type/list.tcl20
4 files changed, 51 insertions, 0 deletions
diff --git a/src/redis.c b/src/redis.c
index c8b1c7814..6d5ba628e 100644
--- a/src/redis.c
+++ b/src/redis.c
@@ -91,6 +91,7 @@ struct redisCommand readonlyCommandTable[] = {
{"blpop",blpopCommand,-3,REDIS_CMD_INLINE,NULL,1,1,1},
{"llen",llenCommand,2,REDIS_CMD_INLINE,NULL,1,1,1},
{"lindex",lindexCommand,3,REDIS_CMD_INLINE,NULL,1,1,1},
+ {"lismember",lismemberCommand,3,REDIS_CMD_INLINE,NULL,1,1,1},
{"lset",lsetCommand,4,REDIS_CMD_BULK|REDIS_CMD_DENYOOM,NULL,1,1,1},
{"lrange",lrangeCommand,4,REDIS_CMD_INLINE,NULL,1,1,1},
{"ltrim",ltrimCommand,4,REDIS_CMD_INLINE,NULL,1,1,1},
diff --git a/src/redis.h b/src/redis.h
index fb051f8eb..d4b09cb50 100644
--- a/src/redis.h
+++ b/src/redis.h
@@ -808,6 +808,7 @@ void lpopCommand(redisClient *c);
void rpopCommand(redisClient *c);
void llenCommand(redisClient *c);
void lindexCommand(redisClient *c);
+void lismemberCommand(redisClient *c);
void lrangeCommand(redisClient *c);
void ltrimCommand(redisClient *c);
void typeCommand(redisClient *c);
diff --git a/src/t_list.c b/src/t_list.c
index 2a9810333..b60ad57be 100644
--- a/src/t_list.c
+++ b/src/t_list.c
@@ -405,6 +405,35 @@ void lindexCommand(redisClient *c) {
}
}
+void lismemberCommand(redisClient *c) {
+ robj *subject;
+ robj *refval = c->argv[2];
+ listTypeIterator *iter;
+ listTypeEntry entry;
+ int found = 0;
+
+ if ((subject = lookupKeyReadOrReply(c,c->argv[1],shared.czero)) == NULL ||
+ checkType(c,subject,REDIS_LIST)) return;
+
+ redisAssert(refval->encoding == REDIS_ENCODING_RAW);
+
+ /* Seek refval from head to tail */
+ iter = listTypeInitIterator(subject,0,REDIS_TAIL);
+ while (listTypeNext(iter,&entry)) {
+ if (listTypeEqual(&entry,refval)) {
+ found = 1;
+ break;
+ }
+ }
+ listTypeReleaseIterator(iter);
+
+ if (found) {
+ addReply(c,shared.cone);
+ } else {
+ addReply(c,shared.czero);
+ }
+}
+
void lsetCommand(redisClient *c) {
robj *o = lookupKeyWriteOrReply(c,c->argv[1],shared.nokeyerr);
if (o == NULL || checkType(c,o,REDIS_LIST)) return;
diff --git a/tests/unit/type/list.tcl b/tests/unit/type/list.tcl
index d3ed90ecc..84d4c475c 100644
--- a/tests/unit/type/list.tcl
+++ b/tests/unit/type/list.tcl
@@ -55,6 +55,26 @@ start_server {
assert_equal $largevalue(linkedlist) [r lindex mylist2 2]
}
+ test {LISMEMBER - ziplist} {
+ r del mylist1
+ assert_equal 1 [r rpush mylist1 house]
+ assert_equal 2 [r rpush mylist1 boat]
+ assert_encoding ziplist mylist1
+ assert_equal 1 [r lismember mylist1 house]
+ assert_equal 1 [r lismember mylist1 boat]
+ assert_equal 0 [r lismember mylist1 airplane]
+ }
+
+ test {LISMEMBER - regular list} {
+ r del mylist1
+ assert_equal 1 [r rpush mylist1 $largevalue(linkedlist)]
+ assert_equal 2 [r rpush mylist1 boat]
+ assert_encoding linkedlist mylist1
+ assert_equal 1 [r lismember mylist1 $largevalue(linkedlist)]
+ assert_equal 1 [r lismember mylist1 boat]
+ assert_equal 0 [r lismember mylist1 airplane]
+ }
+
test {DEL a list - ziplist} {
assert_equal 1 [r del myziplist2]
assert_equal 0 [r exists myziplist2]