]> git.saurik.com Git - redis.git/commitdiff
first implementation of HSET/HSET. More work needed
authorantirez <antirez@gmail.com>
Sat, 6 Mar 2010 00:56:16 +0000 (01:56 +0100)
committerantirez <antirez@gmail.com>
Sat, 6 Mar 2010 00:56:16 +0000 (01:56 +0100)
TODO
redis-cli.c
redis.c
zipmap.c

diff --git a/TODO b/TODO
index d40d55856383d7e4719a653adb609eda6fdaba50..e54a0aec3b8705a3e8f55da9c014250cd381a6b1 100644 (file)
--- a/TODO
+++ b/TODO
@@ -59,6 +59,7 @@ BIG ONES:
 
 SMALL 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.
 * 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.
index bbcac0c5b1baa5e96d04d1f69cf369982d1a6fa4..807f676d11af9ff2b7b7afbfa41a4a2e031c2226 100644 (file)
@@ -141,8 +141,10 @@ static struct redisCommand cmdTable[] = {
     {"msetnx",-3,REDIS_CMD_MULTIBULK},
     {"monitor",1,REDIS_CMD_INLINE},
     {"multi",1,REDIS_CMD_INLINE},
     {"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},
     {"discard",1,REDIS_CMD_INLINE},
+    {"hset",4,REDIS_CMD_MULTIBULK},
+    {"hget",3,REDIS_CMD_BULK},
     {NULL,0,0}
 };
 
     {NULL,0,0}
 };
 
diff --git a/redis.c b/redis.c
index 11056d54cbd6c1979083236614c36c6b7f6f8f19..b49de86562190238224613c74e35f2f829b03675 100644 (file)
--- 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 appendCommand(redisClient *c);
 static void substrCommand(redisClient *c);
 static void zrankCommand(redisClient *c);
+static void hsetCommand(redisClient *c);
+static void hgetCommand(redisClient *c);
 
 /*================================= Globals ================================= */
 
 
 /*================================= 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},
     {"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},
     {"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) {
 /* ========================= Non type-specific commands  ==================== */
 
 static void flushdbCommand(redisClient *c) {
index 136549bcc8431108ab844a512ee2819bd69802c3..05bf6d6d9983d64d4055d43379da1f626b6b642c 100644 (file)
--- 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*) "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);
     zipmapRepr(zm);
     zm = zipmapDel(zm,(unsigned char*) "new",3,NULL);
     zipmapRepr(zm);