]> git.saurik.com Git - redis.git/commitdiff
APPEND command
authorantirez <antirez@gmail.com>
Thu, 4 Feb 2010 14:55:52 +0000 (15:55 +0100)
committerantirez <antirez@gmail.com>
Thu, 4 Feb 2010 14:55:52 +0000 (15:55 +0100)
redis-cli.c
redis.c
sds.c

index cac22c9bb5d209db8b1c1db67ea44da0ad9d7a05..278ecd30bc07610f8141d722a1200d5c7c852068 100644 (file)
@@ -63,6 +63,7 @@ static struct redisCommand cmdTable[] = {
     {"get",2,REDIS_CMD_INLINE},
     {"set",3,REDIS_CMD_BULK},
     {"setnx",3,REDIS_CMD_BULK},
+    {"append",3,REDIS_CMD_BULK},
     {"del",-2,REDIS_CMD_INLINE},
     {"exists",2,REDIS_CMD_INLINE},
     {"incr",2,REDIS_CMD_INLINE},
diff --git a/redis.c b/redis.c
index 87711dabb13c68a08f44b2dd7c5853fb4b974f1f..3326516864a206582ee685823d034a9143fffbfc 100644 (file)
--- a/redis.c
+++ b/redis.c
@@ -650,6 +650,7 @@ static void multiCommand(redisClient *c);
 static void execCommand(redisClient *c);
 static void blpopCommand(redisClient *c);
 static void brpopCommand(redisClient *c);
+static void appendCommand(redisClient *c);
 
 /*================================= Globals ================================= */
 
@@ -659,6 +660,7 @@ static struct redisCommand cmdTable[] = {
     {"get",getCommand,2,REDIS_CMD_INLINE},
     {"set",setCommand,3,REDIS_CMD_BULK|REDIS_CMD_DENYOOM},
     {"setnx",setnxCommand,3,REDIS_CMD_BULK|REDIS_CMD_DENYOOM},
+    {"append",appendCommand,3,REDIS_CMD_BULK|REDIS_CMD_DENYOOM},
     {"del",delCommand,-2,REDIS_CMD_INLINE},
     {"exists",existsCommand,2,REDIS_CMD_INLINE},
     {"incr",incrCommand,2,REDIS_CMD_INLINE|REDIS_CMD_DENYOOM},
@@ -3695,6 +3697,52 @@ static void decrbyCommand(redisClient *c) {
     incrDecrCommand(c,-incr);
 }
 
+static void appendCommand(redisClient *c) {
+    int retval;
+    size_t totlen;
+    robj *o;
+
+    o = lookupKeyWrite(c->db,c->argv[1]);
+    if (o == NULL) {
+        /* Create the key */
+        retval = dictAdd(c->db->dict,c->argv[1],c->argv[2]);
+        incrRefCount(c->argv[1]);
+        incrRefCount(c->argv[2]);
+        totlen = stringObjectLen(c->argv[2]);
+    } else {
+        dictEntry *de;
+       
+        de = dictFind(c->db->dict,c->argv[1]);
+        assert(de != NULL);
+
+        o = dictGetEntryVal(de);
+        if (o->type != REDIS_STRING) {
+            addReply(c,shared.wrongtypeerr);
+            return;
+        }
+        /* If the object is specially encoded or shared we have to make
+         * a copy */
+        if (o->refcount != 1 || o->encoding != REDIS_ENCODING_RAW) {
+            robj *decoded = getDecodedObject(o);
+
+            o = createStringObject(decoded->ptr, sdslen(decoded->ptr));
+            decrRefCount(decoded);
+            dictReplace(c->db->dict,c->argv[1],o);
+        }
+        /* APPEND! */
+        if (c->argv[2]->encoding == REDIS_ENCODING_RAW) {
+            o->ptr = sdscatlen(o->ptr,
+                c->argv[2]->ptr, sdslen(c->argv[2]->ptr));
+        } else {
+            o->ptr = sdscatprintf(o->ptr, "%ld",
+                (unsigned long) c->argv[2]->ptr);
+        }
+        totlen = sdslen(o->ptr);
+    }
+    server.dirty++;
+    addReplySds(c,sdscatprintf(sdsempty(),":%lu\r\n",(unsigned long)totlen));
+}
+
 /* ========================= Type agnostic commands ========================= */
 
 static void delCommand(redisClient *c) {
diff --git a/sds.c b/sds.c
index 497d00f58e304228e59b1cea424e3b8fa6d3cb3b..247b7c30d57d0df9b0234ebe0ddd34e8d11b027e 100644 (file)
--- a/sds.c
+++ b/sds.c
@@ -159,7 +159,7 @@ sds sdscpy(sds s, char *t) {
 sds sdscatprintf(sds s, const char *fmt, ...) {
     va_list ap;
     char *buf, *t;
-    size_t buflen = 32;
+    size_t buflen = 16;
 
     while(1) {
         buf = zmalloc(buflen);