diff options
author | Robey Pointer <robey@twitter.com> | 2010-08-02 19:01:56 -0700 |
---|---|---|
committer | Robey Pointer <robey@twitter.com> | 2010-08-02 19:01:56 -0700 |
commit | 0b6677608d54ba31d338ed23fb50754890b97e4d (patch) | |
tree | 3dd228016af2369f2a787c590def57056fcb432a | |
parent | 0c7a9dec651aa15857da30b95cca7079490725ab (diff) | |
download | redis-0b6677608d54ba31d338ed23fb50754890b97e4d.tar.gz |
add LISMEMBER.twitter-20100804
-rw-r--r-- | src/redis.c | 1 | ||||
-rw-r--r-- | src/redis.h | 1 | ||||
-rw-r--r-- | src/t_list.c | 29 | ||||
-rw-r--r-- | tests/unit/type/list.tcl | 20 |
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] |