From a86f14b1907e72f97332c8f5f88bb97b937e64a9 Mon Sep 17 00:00:00 2001 From: antirez Date: Wed, 17 Mar 2010 13:34:27 +0100 Subject: [PATCH] HEXISTS and tests implemented --- redis-cli.c | 1 + redis.c | 22 ++++++++++++++++++++++ redis.tcl | 2 +- test-redis.tcl | 12 ++++++++++++ 4 files changed, 36 insertions(+), 1 deletion(-) diff --git a/redis-cli.c b/redis-cli.c index 03755efa..e22eb356 100644 --- a/redis-cli.c +++ b/redis-cli.c @@ -153,6 +153,7 @@ static struct redisCommand cmdTable[] = { {"hkeys",2,REDIS_CMD_INLINE}, {"hvals",2,REDIS_CMD_INLINE}, {"hgetall",2,REDIS_CMD_INLINE}, + {"hexists",3,REDIS_CMD_BULK}, {NULL,0,0} }; diff --git a/redis.c b/redis.c index 3f9c4c96..87575ee3 100644 --- a/redis.c +++ b/redis.c @@ -689,6 +689,7 @@ static void zinterCommand(redisClient *c); static void hkeysCommand(redisClient *c); static void hvalsCommand(redisClient *c); static void hgetallCommand(redisClient *c); +static void hexistsCommand(redisClient *c); /*================================= Globals ================================= */ @@ -754,6 +755,7 @@ static struct redisCommand cmdTable[] = { {"hkeys",hkeysCommand,2,REDIS_CMD_INLINE,1,1,1}, {"hvals",hvalsCommand,2,REDIS_CMD_INLINE,1,1,1}, {"hgetall",hgetallCommand,2,REDIS_CMD_INLINE,1,1,1}, + {"hexists",hexistsCommand,3,REDIS_CMD_BULK,1,1,1}, {"incrby",incrbyCommand,3,REDIS_CMD_INLINE|REDIS_CMD_DENYOOM,1,1,1}, {"decrby",decrbyCommand,3,REDIS_CMD_INLINE|REDIS_CMD_DENYOOM,1,1,1}, {"getset",getsetCommand,3,REDIS_CMD_BULK|REDIS_CMD_DENYOOM,1,1,1}, @@ -5995,6 +5997,26 @@ static void hgetallCommand(redisClient *c) { genericHgetallCommand(c,REDIS_GETALL_KEYS|REDIS_GETALL_VALS); } +static void hexistsCommand(redisClient *c) { + robj *o; + int exists = 0; + + if ((o = lookupKeyReadOrReply(c,c->argv[1],shared.czero)) == NULL || + checkType(c,o,REDIS_HASH)) return; + + if (o->encoding == REDIS_ENCODING_ZIPMAP) { + robj *field; + unsigned char *zm = o->ptr; + + field = getDecodedObject(c->argv[2]); + exists = zipmapExists(zm,field->ptr,sdslen(field->ptr)); + decrRefCount(field); + } else { + exists = dictFind(o->ptr,c->argv[2]) != NULL; + } + addReply(c,exists ? shared.cone : shared.czero); +} + static void convertToRealHash(robj *o) { unsigned char *key, *val, *p, *zm = o->ptr; unsigned int klen, vlen; diff --git a/redis.tcl b/redis.tcl index ac9f8601..ef210cbd 100644 --- a/redis.tcl +++ b/redis.tcl @@ -20,7 +20,7 @@ array set ::redis::multibulkarg {} # Flag commands requiring last argument as a bulk write operation foreach redis_bulk_cmd { - set setnx rpush lpush lset lrem sadd srem sismember echo getset smove zadd zrem zscore zincrby append zrank zrevrank hget hdel + set setnx rpush lpush lset lrem sadd srem sismember echo getset smove zadd zrem zscore zincrby append zrank zrevrank hget hdel hexists } { set ::redis::bulkarg($redis_bulk_cmd) {} } diff --git a/test-redis.tcl b/test-redis.tcl index 0cf1c410..5022eee1 100644 --- a/test-redis.tcl +++ b/test-redis.tcl @@ -1644,13 +1644,25 @@ proc main {server port} { lappend rv [$r hdel smallhash $k] lappend rv [$r hdel smallhash $k] lappend rv [$r hget smallhash $k] + unset smallhash($k) set k [lindex [array names bighash *] 0] lappend rv [$r hdel bighash $k] lappend rv [$r hdel bighash $k] lappend rv [$r hget bighash $k] + unset bighash($k) set _ $rv } {0 0 1 0 {} 1 0 {}} + test {HEXISTS} { + set rv {} + set k [lindex [array names smallhash *] 0] + lappend rv [$r hexists smallhash $k] + lappend rv [$r hexists smallhash nokey] + set k [lindex [array names bighash *] 0] + lappend rv [$r hexists bighash $k] + lappend rv [$r hexists bighash nokey] + } {1 0 1 0} + test {Is a zipmap encoded Hash promoted on big payload?} { $r hset smallhash foo [string repeat a 1024] $r debug object smallhash