From 978c2c944cb540827ba53ceb2301e4bd460d9591 Mon Sep 17 00:00:00 2001 From: antirez Date: Sat, 6 Mar 2010 01:56:16 +0100 Subject: [PATCH] first implementation of HSET/HSET. More work needed --- TODO | 1 + redis-cli.c | 4 ++- redis.c | 74 +++++++++++++++++++++++++++++++++++++++++++++++++++++ zipmap.c | 1 + 4 files changed, 79 insertions(+), 1 deletion(-) diff --git a/TODO b/TODO index d40d5585..e54a0aec 100644 --- a/TODO +++ b/TODO @@ -59,6 +59,7 @@ BIG ONES: SMALL ONES: +* Delete on writes against expire policy should only happen after argument parsing for commands doing their own arg parsing stuff. * Give errors when incrementing a key that does not look like an integer, when providing as a sorted set score something can't be parsed as a double, and so forth. * MSADD (n keys) (n values). See this thread in the Redis google group: http://groups.google.com/group/redis-db/browse_thread/thread/e766d84eb375cd41 * Don't save empty lists / sets / zsets on disk with snapshotting. diff --git a/redis-cli.c b/redis-cli.c index bbcac0c5..807f676d 100644 --- a/redis-cli.c +++ b/redis-cli.c @@ -141,8 +141,10 @@ static struct redisCommand cmdTable[] = { {"msetnx",-3,REDIS_CMD_MULTIBULK}, {"monitor",1,REDIS_CMD_INLINE}, {"multi",1,REDIS_CMD_INLINE}, - {"exec",1,REDIS_CMD_MULTIBULK}, + {"exec",1,REDIS_CMD_INLINE}, {"discard",1,REDIS_CMD_INLINE}, + {"hset",4,REDIS_CMD_MULTIBULK}, + {"hget",3,REDIS_CMD_BULK}, {NULL,0,0} }; diff --git a/redis.c b/redis.c index 11056d54..b49de865 100644 --- a/redis.c +++ b/redis.c @@ -666,6 +666,8 @@ static void brpopCommand(redisClient *c); static void appendCommand(redisClient *c); static void substrCommand(redisClient *c); static void zrankCommand(redisClient *c); +static void hsetCommand(redisClient *c); +static void hgetCommand(redisClient *c); /*================================= Globals ================================= */ @@ -720,6 +722,8 @@ static struct redisCommand cmdTable[] = { {"zcard",zcardCommand,2,REDIS_CMD_INLINE,1,1,1}, {"zscore",zscoreCommand,3,REDIS_CMD_BULK|REDIS_CMD_DENYOOM,1,1,1}, {"zrank",zrankCommand,3,REDIS_CMD_INLINE,1,1,1}, + {"hset",hsetCommand,4,REDIS_CMD_BULK|REDIS_CMD_DENYOOM,1,1,1}, + {"hget",hgetCommand,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}, @@ -5573,6 +5577,76 @@ static void zrankCommand(redisClient *c) { } } +/* ==================================== Hash ================================ */ +static void hsetCommand(redisClient *c) { + int update = 0; + robj *o = lookupKeyWrite(c->db,c->argv[1]); + + if (o == 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; + } + } + if (o->encoding == REDIS_ENCODING_ZIPMAP) { + unsigned char *zm = o->ptr; + + zm = zipmapSet(zm,c->argv[2]->ptr,sdslen(c->argv[2]->ptr), + c->argv[3]->ptr,sdslen(c->argv[3]->ptr),&update); + } else { + if (dictAdd(o->ptr,c->argv[2],c->argv[3]) == DICT_OK) { + incrRefCount(c->argv[2]); + } else { + update = 1; + } + incrRefCount(c->argv[3]); + } + server.dirty++; + addReplySds(c,sdscatprintf(sdsempty(),":%d\r\n",update == 0)); +} + +static void hgetCommand(redisClient *c) { + robj *o = lookupKeyRead(c->db,c->argv[1]); + + if (o == NULL) { + addReply(c,shared.nullbulk); + return; + } else { + if (o->encoding == REDIS_ENCODING_ZIPMAP) { + unsigned char *zm = o->ptr; + unsigned char *val; + unsigned int vlen; + + if (zipmapGet(zm,c->argv[2]->ptr,sdslen(c->argv[2]->ptr), &val,&vlen)) { + addReplySds(c,sdscatprintf(sdsempty(),"$%u\r\n", vlen)); + addReplySds(c,sdsnewlen(val,vlen)); + addReply(c,shared.crlf); + return; + } else { + addReply(c,shared.nullbulk); + return; + } + } else { + struct dictEntry *de; + + de = dictFind(o->ptr,c->argv[2]); + if (de == NULL) { + addReply(c,shared.nullbulk); + } else { + robj *e = dictGetEntryVal(de); + + addReplyBulkLen(c,e); + addReply(c,e); + addReply(c,shared.crlf); + } + } + } +} + /* ========================= Non type-specific commands ==================== */ static void flushdbCommand(redisClient *c) { diff --git a/zipmap.c b/zipmap.c index 136549bc..05bf6d6d 100644 --- a/zipmap.c +++ b/zipmap.c @@ -412,6 +412,7 @@ int main(void) { zm = zipmapSet(zm,(unsigned char*) "foo",3, (unsigned char*) "12345",5,NULL); zipmapRepr(zm); zm = zipmapSet(zm,(unsigned char*) "new",3, (unsigned char*) "xx",2,NULL); + zm = zipmapSet(zm,(unsigned char*) "noval",5, (unsigned char*) "",0,NULL); zipmapRepr(zm); zm = zipmapDel(zm,(unsigned char*) "new",3,NULL); zipmapRepr(zm);