Permalink
Browse files

implemented HMSET

  • Loading branch information...
1 parent 05df762 commit d33278d1601bda80987a6f4ad4b2319fb2f7e972 @pietern pietern committed Apr 12, 2010
Showing with 99 additions and 7 deletions.
  1. +1 −0 redis-cli.c
  2. +66 −0 redis.c
  3. +1 −1 redis.tcl
  4. +31 −6 test-redis.tcl
View
@@ -150,6 +150,7 @@ static struct redisCommand cmdTable[] = {
{"exec",1,REDIS_CMD_INLINE},
{"discard",1,REDIS_CMD_INLINE},
{"hset",4,REDIS_CMD_MULTIBULK},
+ {"hmset",-4,REDIS_CMD_MULTIBULK},
{"hincrby",4,REDIS_CMD_INLINE},
{"hget",3,REDIS_CMD_BULK},
{"hdel",3,REDIS_CMD_BULK},
View
66 redis.c
@@ -704,6 +704,7 @@ static void substrCommand(redisClient *c);
static void zrankCommand(redisClient *c);
static void zrevrankCommand(redisClient *c);
static void hsetCommand(redisClient *c);
+static void hmsetCommand(redisClient *c);
static void hgetCommand(redisClient *c);
static void hdelCommand(redisClient *c);
static void hlenCommand(redisClient *c);
@@ -780,6 +781,7 @@ static struct redisCommand cmdTable[] = {
{"zrank",zrankCommand,3,REDIS_CMD_BULK,NULL,1,1,1},
{"zrevrank",zrevrankCommand,3,REDIS_CMD_BULK,NULL,1,1,1},
{"hset",hsetCommand,4,REDIS_CMD_BULK|REDIS_CMD_DENYOOM,NULL,1,1,1},
+ {"hmset",hmsetCommand,-4,REDIS_CMD_BULK|REDIS_CMD_DENYOOM,NULL,1,1,1},
{"hincrby",hincrbyCommand,4,REDIS_CMD_INLINE|REDIS_CMD_DENYOOM,NULL,1,1,1},
{"hget",hgetCommand,3,REDIS_CMD_BULK,NULL,1,1,1},
{"hdel",hdelCommand,3,REDIS_CMD_BULK,NULL,1,1,1},
@@ -6004,6 +6006,70 @@ static void hsetCommand(redisClient *c) {
addReplySds(c,sdscatprintf(sdsempty(),":%d\r\n",update == 0));
}
+static void hmsetCommand(redisClient *c) {
+ int i;
+ robj *o, *key, *val;
+
+ if ((c->argc % 2) == 1) {
+ addReplySds(c,sdsnew("-ERR wrong number of arguments for HMSET\r\n"));
+ return;
+ }
+
+ if ((o = lookupKeyWrite(c->db,c->argv[1])) == NULL) {
+ o = createHashObject();
+ dictAdd(c->db->dict,c->argv[1],o);
+ incrRefCount(c->argv[1]);
+ } else {
+ if (o->type != REDIS_HASH) {
+ addReply(c,shared.wrongtypeerr);
+ return;
+ }
+ }
+
+ /* We want to convert the zipmap into an hash table right now if the
+ * entry to be added is too big. */
+ if (o->encoding == REDIS_ENCODING_ZIPMAP) {
+ for (i = 2; i < c->argc; i+=2) {
+ if ((c->argv[i]->encoding == REDIS_ENCODING_RAW &&
+ sdslen(c->argv[i]->ptr) > server.hash_max_zipmap_value) ||
+ (c->argv[i+1]->encoding == REDIS_ENCODING_RAW &&
+ sdslen(c->argv[i+1]->ptr) > server.hash_max_zipmap_value)) {
+ convertToRealHash(o);
+ break;
+ }
+ }
+ }
+
+ if (o->encoding == REDIS_ENCODING_ZIPMAP) {
+ unsigned char *zm = o->ptr;
+
+ for (i = 2; i < c->argc; i+=2) {
+ key = getDecodedObject(c->argv[i]);
+ val = getDecodedObject(c->argv[i+1]);
+ zm = zipmapSet(zm,key->ptr,sdslen(key->ptr),
+ val->ptr,sdslen(val->ptr),NULL);
+ decrRefCount(key);
+ decrRefCount(val);
+ o->ptr = zm;
+ }
+
+ /* And here there is the second check for hash conversion. */
+ if (zipmapLen(zm) > server.hash_max_zipmap_entries)
+ convertToRealHash(o);
+ } else {
+ for (i = 2; i < c->argc; i+=2) {
+ key = tryObjectEncoding(c->argv[i]);
+ val = tryObjectEncoding(c->argv[i+1]);
+ if (dictReplace(o->ptr,key,val)) {
+ incrRefCount(key);
+ }
+ incrRefCount(val);
+ }
+ }
+
+ addReply(c, shared.ok);
+}
+
static void hincrbyCommand(redisClient *c) {
long long value = 0, incr = 0;
robj *o = lookupKeyWrite(c->db,c->argv[1]);
View
@@ -46,7 +46,7 @@ foreach redis_bulk_cmd {
# Flag commands requiring last argument as a bulk write operation
foreach redis_multibulk_cmd {
- mset msetnx hset
+ mset msetnx hset hmset
} {
set ::redis::multibulkarg($redis_multibulk_cmd) {}
}
View
@@ -1614,6 +1614,13 @@ proc main {server port} {
set _ $err
} {}
+ test {HGET against non existing key} {
+ set rv {}
+ lappend rv [$r hget smallhash __123123123__]
+ lappend rv [$r hget bighash __123123123__]
+ set _ $rv
+ } {{} {}}
+
test {HSET in update and insert mode} {
set rv {}
set k [lindex [array names smallhash *] 0]
@@ -1631,12 +1638,30 @@ proc main {server port} {
set _ $rv
} {0 newval1 1 0 newval2 1 1 1}
- test {HGET against non existing key} {
- set rv {}
- lappend rv [$r hget smallhash __123123123__]
- lappend rv [$r hget bighash __123123123__]
- set _ $rv
- } {{} {}}
+ test {HMSET wrong number of args} {
+ catch {$r hmset smallhash key1 val1 key2} err
+ format $err
+ } {*wrong number*}
+
+ test {HMSET - small hash} {
+ set args {}
+ foreach {k v} [array get smallhash] {
+ set newval [randstring 0 8 alpha]
+ set smallhash($k) $newval
+ lappend args $k $newval
+ }
+ $r hmset smallhash {*}$args
+ } {OK}
+
+ test {HMSET - big hash} {
+ set args {}
+ foreach {k v} [array get bighash] {
+ set newval [randstring 0 8 alpha]
+ set bighash($k) $newval
+ lappend args $k $newval
+ }
+ $r hmset bighash {*}$args
+ } {OK}
test {HKEYS - small hash} {
lsort [$r hkeys smallhash]

0 comments on commit d33278d

Please sign in to comment.