]> git.saurik.com Git - redis.git/commitdiff
DUMP implemented, RESTORE and MIGRATE fixed. Use zcalloc() instead of zmalloc()+memse...
authorantirez <antirez@gmail.com>
Fri, 1 Apr 2011 16:59:28 +0000 (18:59 +0200)
committerantirez <antirez@gmail.com>
Fri, 1 Apr 2011 16:59:28 +0000 (18:59 +0200)
src/cluster.c
src/redis.c
src/redis.h
src/sds.c

index 76ea894de0fc850e69f2a8f6301d3f30c4ddeb2a..b57dd48ca8588817d0769a674966cc53a63b7345 100644 (file)
@@ -1270,6 +1270,7 @@ file_wr_err:
         strerror(errno));
     fclose(fp);
     close(fd);
+    return;
 
 file_rd_err:
     redisLog(REDIS_WARNING,"Can't read from tmp file for MIGRATE: %s",
@@ -1278,6 +1279,7 @@ file_rd_err:
         strerror(errno));
     fclose(fp);
     close(fd);
+    return;
 
 socket_wr_err:
     redisLog(REDIS_NOTICE,"Can't write to target node for MIGRATE: %s",
@@ -1286,6 +1288,7 @@ socket_wr_err:
         strerror(errno));
     fclose(fp);
     close(fd);
+    return;
 
 socket_rd_err:
     redisLog(REDIS_NOTICE,"Can't read from target node for MIGRATE: %s",
@@ -1294,6 +1297,81 @@ socket_rd_err:
         strerror(errno));
     fclose(fp);
     close(fd);
+    return;
+}
+
+/* DUMP keyname
+ * DUMP is actually not used by Redis Cluster but it is the obvious
+ * complement of RESTORE and can be useful for different applications. */
+void dumpCommand(redisClient *c) {
+    char buf[64];
+    FILE *fp;
+    robj *o, *dumpobj;
+    sds dump = NULL;
+    off_t payload_len;
+    unsigned int type;
+
+    /* Check if the key is here. */
+    if ((o = lookupKeyRead(c->db,c->argv[1])) == NULL) {
+        addReply(c,shared.nullbulk);
+        return;
+    }
+    
+    /* Create temp file */
+    snprintf(buf,sizeof(buf),"redis-dump-%d.tmp",getpid());
+    fp = fopen(buf,"w+");
+    if (!fp) {
+        redisLog(REDIS_WARNING,"Can't open tmp file for MIGRATE: %s",
+            strerror(errno));
+        addReplyErrorFormat(c,"DUMP failed, tmp file creation error: %s.",
+            strerror(errno));
+        return;
+    }
+    unlink(buf);
+
+    /* Dump the serailized object and read it back in memory.
+     * We prefix it with a one byte containing the type ID.
+     * This is the serialization format understood by RESTORE. */
+    if (rdbSaveObject(fp,o) == -1) goto file_wr_err;
+    payload_len = ftello(fp);
+    if (fseeko(fp,0,SEEK_SET) == -1) goto file_rd_err;
+    dump = sdsnewlen(NULL,payload_len+1);
+    if (payload_len && fread(dump+1,payload_len,1,fp) != 1) goto file_rd_err;
+    fclose(fp);
+    type = o->type;
+    if (type == REDIS_LIST && o->encoding == REDIS_ENCODING_ZIPLIST)
+        type = REDIS_LIST_ZIPLIST;
+    else if (type == REDIS_HASH && o->encoding == REDIS_ENCODING_ZIPMAP)
+        type = REDIS_HASH_ZIPMAP;
+    else if (type == REDIS_SET && o->encoding == REDIS_ENCODING_INTSET)
+        type = REDIS_SET_INTSET;
+    else
+        type = o->type;
+    dump[0] = type;
+
+    /* Transfer to the client */
+    dumpobj = createObject(REDIS_STRING,dump);
+    addReplyBulk(c,dumpobj);
+    decrRefCount(dumpobj);
+    return;
+
+file_wr_err:
+    redisLog(REDIS_WARNING,"Can't write on tmp file for DUMP: %s",
+        strerror(errno));
+    addReplyErrorFormat(c,"DUMP failed, tmp file write error: %s.",
+        strerror(errno));
+    sdsfree(dump);
+    fclose(fp);
+    return;
+
+file_rd_err:
+    redisLog(REDIS_WARNING,"Can't read from tmp file for DUMP: %s",
+        strerror(errno));
+    addReplyErrorFormat(c,"DUMP failed, tmp file read error: %s.",
+        strerror(errno));
+    sdsfree(dump);
+    fclose(fp);
+    return;
 }
 
 /* -----------------------------------------------------------------------------
index 8b8c49eb7e5abf1def75bb1762399a36c266f9b6..1cc8cc75f6c900b9707368e71f90dedc5e003abd 100644 (file)
@@ -189,8 +189,9 @@ struct redisCommand redisCommandTable[] = {
     {"watch",watchCommand,-2,0,noPreloadGetKeys,1,-1,1,0,0},
     {"unwatch",unwatchCommand,1,0,NULL,0,0,0,0,0},
     {"cluster",clusterCommand,-2,0,NULL,0,0,0,0,0},
-    {"restore",restoreCommand,3,0,NULL,0,0,0,0,0},
-    {"migrate",migrateCommand,6,0,NULL,0,0,0,0,0}
+    {"restore",restoreCommand,4,0,NULL,0,0,0,0,0},
+    {"migrate",migrateCommand,6,0,NULL,0,0,0,0,0},
+    {"dump",dumpCommand,2,0,NULL,0,0,0,0,0}
 };
 
 /*============================ Utility functions ============================ */
index 5b403798bf037a2f3fd2ec06692a23ce139d7ff1..91a64ecfddc049eddd2473b7c370ca2ce11fd3c7 100644 (file)
@@ -1180,6 +1180,7 @@ void unwatchCommand(redisClient *c);
 void clusterCommand(redisClient *c);
 void restoreCommand(redisClient *c);
 void migrateCommand(redisClient *c);
+void dumpCommand(redisClient *c);
 
 #if defined(__GNUC__)
 void *calloc(size_t count, size_t size) __attribute__ ((deprecated));
index 7cb43962e451a5518e4aed1adb4615f53d16e0ef..8c7540990e8154d0326f885e2a529da062acf21f 100644 (file)
--- a/src/sds.c
+++ b/src/sds.c
@@ -51,7 +51,11 @@ static void sdsOomAbort(void) {
 sds sdsnewlen(const void *init, size_t initlen) {
     struct sdshdr *sh;
 
-    sh = zmalloc(sizeof(struct sdshdr)+initlen+1);
+    if (init) {
+        sh = zmalloc(sizeof(struct sdshdr)+initlen+1);
+    } else {
+        sh = zcalloc(sizeof(struct sdshdr)+initlen+1);
+    }
 #ifdef SDS_ABORT_ON_OOM
     if (sh == NULL) sdsOomAbort();
 #else
@@ -59,10 +63,8 @@ sds sdsnewlen(const void *init, size_t initlen) {
 #endif
     sh->len = initlen;
     sh->free = 0;
-    if (initlen) {
-        if (init) memcpy(sh->buf, init, initlen);
-        else memset(sh->buf,0,initlen);
-    }
+    if (initlen && init)
+        memcpy(sh->buf, init, initlen);
     sh->buf[initlen] = '\0';
     return (char*)sh->buf;
 }