Skip to content

Commit

Permalink
Issue 69 fixed. Object integer encoding now works with replication an…
Browse files Browse the repository at this point in the history
…d MONITORing again.
  • Loading branch information
antirez committed Oct 2, 2009
1 parent 724a51b commit 0ea663e
Show file tree
Hide file tree
Showing 4 changed files with 127 additions and 37 deletions.
5 changes: 5 additions & 0 deletions Changelog
Original file line number Diff line number Diff line change
@@ -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
Expand Down
21 changes: 18 additions & 3 deletions redis.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down Expand Up @@ -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;
}
Expand Down Expand Up @@ -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) {
Expand Down Expand Up @@ -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;

Expand All @@ -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;
Expand Down
132 changes: 100 additions & 32 deletions sds.c
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand All @@ -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);
Expand All @@ -73,16 +87,25 @@ 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) {
return sdsnewlen(s, sdslen(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) {
Expand All @@ -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;
}
Expand All @@ -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;
}

Expand Down Expand Up @@ -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;
}

Expand All @@ -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;
}

Expand Down
6 changes: 4 additions & 2 deletions sds.h
Original file line number Diff line number Diff line change
Expand Up @@ -32,12 +32,14 @@
#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[];
};

Expand Down

0 comments on commit 0ea663e

Please sign in to comment.