]> git.saurik.com Git - redis.git/commitdiff
Issue 69 fixed. Object integer encoding now works with replication and MONITORing...
authorantirez <antirez@gmail.com>
Fri, 2 Oct 2009 08:23:25 +0000 (10:23 +0200)
committerantirez <antirez@gmail.com>
Fri, 2 Oct 2009 08:23:25 +0000 (10:23 +0200)
Changelog
redis.c
sds.c
sds.h

index 1ce4d1184bcccab08c7a279fc79b18bf77c627cc..fa9174cd504d8a750d7383099e7ca1a1fc0e3172 100644 (file)
--- a/Changelog
+++ b/Changelog
@@ -1,3 +1,8 @@
+2009-09-18 LREM fixed, used to crash since the new object integer encoding is on the stage
+2009-09-17 maxmemory didn't worked in 64 systems for values > 4GB since it used to be an unsigned int. Fixed
+2009-09-10 incremented version number to 1.001, AKA Redis edge is no longer stable...
+2009-09-10 in-memory specialized object encoding (for now 32 signed integers only)
+2009-09-03 Latest doc changes for 1.0
 2009-09-03 Redis 1.0.0 release
 2009-09-02 Redis version pushed to 1.0
 2009-09-02 Ruby client lib updated to the latest git version
diff --git a/redis.c b/redis.c
index 78b53a9da17eea1dd3ea5969b879c28307d28208..2edc186f438e2ae36a299a4870887b563bed0b34 100644 (file)
--- a/redis.c
+++ b/redis.c
@@ -342,6 +342,7 @@ static void freeMemoryIfNeeded(void);
 static int processCommand(redisClient *c);
 static void setupSigSegvAction(void);
 static void rdbRemoveTempFile(pid_t childpid);
+static size_t stringObjectLen(robj *o);
 
 static void authCommand(redisClient *c);
 static void pingCommand(redisClient *c);
@@ -1412,7 +1413,8 @@ static void replicationFeedSlaves(list *slaves, struct redisCommand *cmd, int di
             robj *lenobj;
 
             lenobj = createObject(REDIS_STRING,
-                sdscatprintf(sdsempty(),"%d\r\n",sdslen(argv[j]->ptr)));
+                sdscatprintf(sdsempty(),"%d\r\n",
+                    stringObjectLen(argv[j])));
             lenobj->refcount = 0;
             outv[outc++] = lenobj;
         }
@@ -1919,6 +1921,17 @@ static int compareStringObjects(robj *a, robj *b) {
     }
 }
 
+static size_t stringObjectLen(robj *o) {
+    assert(o->type == REDIS_STRING);
+    if (o->encoding == REDIS_ENCODING_RAW) {
+        return sdslen(o->ptr);
+    } else {
+        char buf[32];
+
+        return snprintf(buf,32,"%ld",(long)o->ptr);
+    }
+}
+
 /*============================ DB saving/loading ============================ */
 
 static int rdbSaveType(FILE *fp, unsigned char type) {
@@ -3533,8 +3546,9 @@ static robj *lookupKeyByPattern(redisDb *db, robj *pattern, robj *subst) {
     int prefixlen, sublen, postfixlen;
     /* Expoit the internal sds representation to create a sds string allocated on the stack in order to make this function faster */
     struct {
-        long len;
-        long free;
+        int len;
+        unsigned short free;
+        unsigned short _len; /* not used here */
         char buf[REDIS_SORTKEY_MAX+1];
     } keyname;
 
@@ -3558,6 +3572,7 @@ static robj *lookupKeyByPattern(redisDb *db, robj *pattern, robj *subst) {
     memcpy(keyname.buf+prefixlen+sublen,p+1,postfixlen);
     keyname.buf[prefixlen+sublen+postfixlen] = '\0';
     keyname.len = prefixlen+sublen+postfixlen;
+    keyname._len = USHRT_MAX;
 
     keyobj.refcount = 1;
     keyobj.type = REDIS_STRING;
diff --git a/sds.c b/sds.c
index 8e9fd96d9befd2a4b4b7eb7ca9317001df24f8b8..b63a4a766173fbaed81daac13a9c272729654414 100644 (file)
--- a/sds.c
+++ b/sds.c
@@ -28,6 +28,8 @@
  * POSSIBILITY OF SUCH DAMAGE.
  */
 
+ /* TODO: check if it can happen that _len+free > USHRT_MAX */
+
 #define SDS_ABORT_ON_OOM
 
 #include "sds.h"
@@ -46,13 +48,25 @@ static void sdsOomAbort(void) {
 sds sdsnewlen(const void *init, size_t initlen) {
     struct sdshdr *sh;
 
-    sh = zmalloc(sizeof(struct sdshdr)+initlen+1);
-#ifdef SDS_ABORT_ON_OOM
-    if (sh == NULL) sdsOomAbort();
-#else
-    if (sh == NULL) return NULL;
-#endif
-    sh->len = initlen;
+    if (initlen >= USHRT_MAX) {
+        sh = zmalloc(sizeof(struct sdshdr)+initlen+1);
+        sh->len = initlen;
+        sh->_len = USHRT_MAX;
+        #ifdef SDS_ABORT_ON_OOM
+            if (sh == NULL) sdsOomAbort();
+        #else
+            if (sh == NULL) return NULL;
+        #endif
+    } else {
+        sh = zmalloc(sizeof(int)+initlen+1);
+        sh = (struct sdshdr*) (((char*)sh)-sizeof(int));
+        #ifdef SDS_ABORT_ON_OOM
+            if (sh == NULL) sdsOomAbort();
+        #else
+            if (sh == NULL) return NULL;
+        #endif
+        sh->_len = initlen;
+    }
     sh->free = 0;
     if (initlen) {
         if (init) memcpy(sh->buf, init, initlen);
@@ -73,7 +87,10 @@ sds sdsnew(const char *init) {
 
 size_t sdslen(const sds s) {
     struct sdshdr *sh = (void*) (s-(sizeof(struct sdshdr)));
-    return sh->len;
+    if (sh->_len == USHRT_MAX)
+        return sh->len;
+    else
+        return sh->_len;
 }
 
 sds sdsdup(const sds s) {
@@ -81,8 +98,14 @@ sds sdsdup(const sds s) {
 }
 
 void sdsfree(sds s) {
+    struct sdshdr *sh;
+
     if (s == NULL) return;
-    zfree(s-sizeof(struct sdshdr));
+    sh = (void*) (s-(sizeof(struct sdshdr)));
+    if (sh->_len == USHRT_MAX)
+        zfree(s-sizeof(struct sdshdr));
+    else
+        zfree(s-sizeof(struct sdshdr)+sizeof(int));
 }
 
 size_t sdsavail(sds s) {
@@ -93,40 +116,73 @@ size_t sdsavail(sds s) {
 void sdsupdatelen(sds s) {
     struct sdshdr *sh = (void*) (s-(sizeof(struct sdshdr)));
     int reallen = strlen(s);
-    sh->free += (sh->len-reallen);
-    sh->len = reallen;
+
+    if (sh->_len == USHRT_MAX) {
+        sh->free += (sh->len-reallen);
+        sh->len = reallen;
+    } else {
+        sh->free += (sh->_len-reallen);
+        sh->_len = reallen;
+    }
 }
 
 static sds sdsMakeRoomFor(sds s, size_t addlen) {
     struct sdshdr *sh, *newsh;
     size_t free = sdsavail(s);
-    size_t len, newlen;
+    size_t len, newlen, newfree;
 
-    if (free >= addlen) return s;
+    if (free >= addlen) {
+        sh = (void*) (s-(sizeof(struct sdshdr)));
+        if (sh->_len == USHRT_MAX) {
+            sh->len += addlen;
+        } else {
+            sh->_len += addlen;
+        }
+        sh->free -= addlen;
+        return s;
+    }
     len = sdslen(s);
     sh = (void*) (s-(sizeof(struct sdshdr)));
-    newlen = (len+addlen)*2;
-    newsh = zrealloc(sh, sizeof(struct sdshdr)+newlen+1);
+    newlen = (len+addlen);
+    newfree = ((addlen*2) > USHRT_MAX) ? USHRT_MAX : (addlen*2);
+    if (newlen+newfree >= USHRT_MAX || sh->_len == USHRT_MAX) {
+        if (sh->_len == USHRT_MAX) {
+            newsh = zrealloc(sh, sizeof(struct sdshdr)+newlen+1+newfree);
+        } else {
+            newsh = zmalloc(sizeof(struct sdshdr)+newlen+1+newfree);
+            if (!newsh) return NULL;
+            memcpy(newsh->buf,sh->buf,len);
+            newsh->buf[len] = '\0';
+            zfree(((char*)sh)+sizeof(int));
+        }
 #ifdef SDS_ABORT_ON_OOM
-    if (newsh == NULL) sdsOomAbort();
+        if (newsh == NULL) sdsOomAbort();
 #else
-    if (newsh == NULL) return NULL;
+        if (newsh == NULL) return NULL;
 #endif
-
-    newsh->free = newlen - len;
+        newsh->_len = USHRT_MAX;
+        newsh->free = newfree;
+        newsh->len = newlen;
+    } else {
+        newsh = zrealloc(((char*)sh)+sizeof(int), sizeof(int)+newlen+1+newfree);
+        newsh = (struct sdshdr*) (((char*)newsh)-sizeof(int));
+#ifdef SDS_ABORT_ON_OOM
+        if (newsh == NULL) sdsOomAbort();
+#else
+        if (newsh == NULL) return NULL;
+#endif
+        newsh->_len = newlen;
+        newsh->free = newfree;
+    }
     return newsh->buf;
 }
 
 sds sdscatlen(sds s, void *t, size_t len) {
-    struct sdshdr *sh;
     size_t curlen = sdslen(s);
 
     s = sdsMakeRoomFor(s,len);
     if (s == NULL) return NULL;
-    sh = (void*) (s-(sizeof(struct sdshdr)));
     memcpy(s+curlen, t, len);
-    sh->len = curlen+len;
-    sh->free = sh->free-len;
     s[curlen+len] = '\0';
     return s;
 }
@@ -137,18 +193,20 @@ sds sdscat(sds s, char *t) {
 
 sds sdscpylen(sds s, char *t, size_t len) {
     struct sdshdr *sh = (void*) (s-(sizeof(struct sdshdr)));
-    size_t totlen = sh->free+sh->len;
+    size_t totlen;
+    
+    if (sh->_len == USHRT_MAX) {
+        totlen = sh->free+sh->len;
+    } else {
+        totlen = sh->free+sh->_len;
+    }
 
     if (totlen < len) {
         s = sdsMakeRoomFor(s,len-totlen);
         if (s == NULL) return NULL;
-        sh = (void*) (s-(sizeof(struct sdshdr)));
-        totlen = sh->free+sh->len;
     }
     memcpy(s, t, len);
     s[len] = '\0';
-    sh->len = len;
-    sh->free = totlen-len;
     return s;
 }
 
@@ -196,8 +254,13 @@ sds sdstrim(sds s, const char *cset) {
     len = (sp > ep) ? 0 : ((ep-sp)+1);
     if (sh->buf != sp) memmove(sh->buf, sp, len);
     sh->buf[len] = '\0';
-    sh->free = sh->free+(sh->len-len);
-    sh->len = len;
+    if (sh->_len == USHRT_MAX) {
+        sh->free = sh->free+(sh->len-len);
+        sh->len = len;
+    } else {
+        sh->free = sh->free+(sh->_len-len);
+        sh->_len = len;
+    }
     return s;
 }
 
@@ -224,8 +287,13 @@ sds sdsrange(sds s, long start, long end) {
     }
     if (start != 0) memmove(sh->buf, sh->buf+start, newlen);
     sh->buf[newlen] = 0;
-    sh->free = sh->free+(sh->len-newlen);
-    sh->len = newlen;
+    if (sh->_len == USHRT_MAX) {
+        sh->free = sh->free+(sh->len-newlen);
+        sh->len = newlen;
+    } else {
+        sh->free = sh->free+(sh->_len-newlen);
+        sh->_len = newlen;
+    }
     return s;
 }
 
diff --git a/sds.h b/sds.h
index 0fc2c9281ba9e9153395cc0c33169fc5deb86833..582cb2f34773988d0793089687c3b4dd11537555 100644 (file)
--- a/sds.h
+++ b/sds.h
 #define __SDS_H
 
 #include <sys/types.h>
+#include <limits.h>
 
 typedef char *sds;
 
 struct sdshdr {
-    long len;
-    long free;
+    int len;
+    unsigned short free;
+    unsigned short _len; /* USHRT_MAX if it is a "long" sds string */
     char buf[];
 };