support rdb saving/loading with dual list encoding

This commit is contained in:
Pieter Noordhuis 2010-05-31 22:25:22 +02:00
parent b6eb970394
commit 23f964946b

68
redis.c
View File

@ -3622,6 +3622,25 @@ static int rdbSaveObject(FILE *fp, robj *o) {
if (rdbSaveStringObject(fp,o) == -1) return -1; if (rdbSaveStringObject(fp,o) == -1) return -1;
} else if (o->type == REDIS_LIST) { } else if (o->type == REDIS_LIST) {
/* Save a list value */ /* Save a list value */
if (o->encoding == REDIS_ENCODING_ZIPLIST) {
unsigned char *p;
unsigned char *vstr;
unsigned int vlen;
long long vlong;
if (rdbSaveLen(fp,ziplistLen(o->ptr)) == -1) return -1;
p = ziplistIndex(o->ptr,0);
while(ziplistGet(p,&vstr,&vlen,&vlong)) {
if (vstr) {
if (rdbSaveRawString(fp,vstr,vlen) == -1)
return -1;
} else {
if (rdbSaveLongLongAsStringObject(fp,vlong) == -1)
return -1;
}
p = ziplistNext(o->ptr,p);
}
} else if (o->encoding == REDIS_ENCODING_LIST) {
list *list = o->ptr; list *list = o->ptr;
listIter li; listIter li;
listNode *ln; listNode *ln;
@ -3630,9 +3649,11 @@ static int rdbSaveObject(FILE *fp, robj *o) {
listRewind(list,&li); listRewind(list,&li);
while((ln = listNext(&li))) { while((ln = listNext(&li))) {
robj *eleobj = listNodeValue(ln); robj *eleobj = listNodeValue(ln);
if (rdbSaveStringObject(fp,eleobj) == -1) return -1; if (rdbSaveStringObject(fp,eleobj) == -1) return -1;
} }
} else {
redisPanic("Unknown list encoding");
}
} else if (o->type == REDIS_SET) { } else if (o->type == REDIS_SET) {
/* Save a set value */ /* Save a set value */
dict *set = o->ptr; dict *set = o->ptr;
@ -3998,35 +4019,50 @@ static int rdbLoadDoubleValue(FILE *fp, double *val) {
/* Load a Redis object of the specified type from the specified file. /* Load a Redis object of the specified type from the specified file.
* On success a newly allocated object is returned, otherwise NULL. */ * On success a newly allocated object is returned, otherwise NULL. */
static robj *rdbLoadObject(int type, FILE *fp) { static robj *rdbLoadObject(int type, FILE *fp) {
robj *o; robj *o, *ele, *dec;
size_t len;
redisLog(REDIS_DEBUG,"LOADING OBJECT %d (at %d)\n",type,ftell(fp)); redisLog(REDIS_DEBUG,"LOADING OBJECT %d (at %d)\n",type,ftell(fp));
if (type == REDIS_STRING) { if (type == REDIS_STRING) {
/* Read string value */ /* Read string value */
if ((o = rdbLoadEncodedStringObject(fp)) == NULL) return NULL; if ((o = rdbLoadEncodedStringObject(fp)) == NULL) return NULL;
o = tryObjectEncoding(o); o = tryObjectEncoding(o);
} else if (type == REDIS_LIST || type == REDIS_SET) { } else if (type == REDIS_LIST) {
/* Read list/set value */ /* Read list value */
uint32_t listlen; if ((len = rdbLoadLen(fp,NULL)) == REDIS_RDB_LENERR) return NULL;
if ((listlen = rdbLoadLen(fp,NULL)) == REDIS_RDB_LENERR) return NULL; o = createObject(REDIS_LIST,ziplistNew());
o = (type == REDIS_LIST) ? createListObject() : createSetObject(); o->encoding = REDIS_ENCODING_ZIPLIST;
/* Load every single element of the list */
while(len--) {
if ((ele = rdbLoadEncodedStringObject(fp)) == NULL) return NULL;
if (o->encoding == REDIS_ENCODING_ZIPLIST) {
dec = getDecodedObject(ele);
o->ptr = ziplistPush(o->ptr,dec->ptr,sdslen(dec->ptr),REDIS_TAIL);
decrRefCount(dec);
decrRefCount(ele);
} else {
ele = tryObjectEncoding(ele);
listAddNodeTail(o->ptr,ele);
incrRefCount(ele);
}
}
} else if (type == REDIS_SET) {
/* Read list/set value */
if ((len = rdbLoadLen(fp,NULL)) == REDIS_RDB_LENERR) return NULL;
o = createSetObject();
/* It's faster to expand the dict to the right size asap in order /* It's faster to expand the dict to the right size asap in order
* to avoid rehashing */ * to avoid rehashing */
if (type == REDIS_SET && listlen > DICT_HT_INITIAL_SIZE) if (len > DICT_HT_INITIAL_SIZE)
dictExpand(o->ptr,listlen); dictExpand(o->ptr,len);
/* Load every single element of the list/set */ /* Load every single element of the list/set */
while(listlen--) { while(len--) {
robj *ele;
if ((ele = rdbLoadEncodedStringObject(fp)) == NULL) return NULL; if ((ele = rdbLoadEncodedStringObject(fp)) == NULL) return NULL;
ele = tryObjectEncoding(ele); ele = tryObjectEncoding(ele);
if (type == REDIS_LIST) {
listAddNodeTail((list*)o->ptr,ele);
} else {
dictAdd((dict*)o->ptr,ele,NULL); dictAdd((dict*)o->ptr,ele,NULL);
} }
}
} else if (type == REDIS_ZSET) { } else if (type == REDIS_ZSET) {
/* Read list/set value */ /* Read list/set value */
size_t zsetlen; size_t zsetlen;