Append only file support for hashes

This commit is contained in:
antirez 2010-03-14 13:40:41 +01:00
parent 08af4d5c96
commit 9c8e3cee26
2 changed files with 64 additions and 11 deletions

64
redis.c
View File

@ -7551,7 +7551,7 @@ fmterr:
}
/* Write an object into a file in the bulk format $<count>\r\n<payload>\r\n */
static int fwriteBulk(FILE *fp, robj *obj) {
static int fwriteBulkObject(FILE *fp, robj *obj) {
char buf[128];
int decrrc = 0;
@ -7576,6 +7576,18 @@ err:
return 0;
}
/* Write binary-safe string into a file in the bulkformat
* $<count>\r\n<payload>\r\n */
static int fwriteBulkString(FILE *fp, char *s, unsigned long len) {
char buf[128];
snprintf(buf,sizeof(buf),"$%ld\r\n",(unsigned long)len);
if (fwrite(buf,strlen(buf),1,fp) == 0) return 0;
if (len && fwrite(s,len,1,fp) == 0) return 0;
if (fwrite("\r\n",2,1,fp) == 0) return 0;
return 1;
}
/* Write a double value in bulk format $<count>\r\n<payload>\r\n */
static int fwriteBulkDouble(FILE *fp, double d) {
char buf[128], dbuf[128];
@ -7658,8 +7670,8 @@ static int rewriteAppendOnlyFile(char *filename) {
char cmd[]="*3\r\n$3\r\nSET\r\n";
if (fwrite(cmd,sizeof(cmd)-1,1,fp) == 0) goto werr;
/* Key and value */
if (fwriteBulk(fp,key) == 0) goto werr;
if (fwriteBulk(fp,o) == 0) goto werr;
if (fwriteBulkObject(fp,key) == 0) goto werr;
if (fwriteBulkObject(fp,o) == 0) goto werr;
} else if (o->type == REDIS_LIST) {
/* Emit the RPUSHes needed to rebuild the list */
list *list = o->ptr;
@ -7672,8 +7684,8 @@ static int rewriteAppendOnlyFile(char *filename) {
robj *eleobj = listNodeValue(ln);
if (fwrite(cmd,sizeof(cmd)-1,1,fp) == 0) goto werr;
if (fwriteBulk(fp,key) == 0) goto werr;
if (fwriteBulk(fp,eleobj) == 0) goto werr;
if (fwriteBulkObject(fp,key) == 0) goto werr;
if (fwriteBulkObject(fp,eleobj) == 0) goto werr;
}
} else if (o->type == REDIS_SET) {
/* Emit the SADDs needed to rebuild the set */
@ -7686,8 +7698,8 @@ static int rewriteAppendOnlyFile(char *filename) {
robj *eleobj = dictGetEntryKey(de);
if (fwrite(cmd,sizeof(cmd)-1,1,fp) == 0) goto werr;
if (fwriteBulk(fp,key) == 0) goto werr;
if (fwriteBulk(fp,eleobj) == 0) goto werr;
if (fwriteBulkObject(fp,key) == 0) goto werr;
if (fwriteBulkObject(fp,eleobj) == 0) goto werr;
}
dictReleaseIterator(di);
} else if (o->type == REDIS_ZSET) {
@ -7702,11 +7714,43 @@ static int rewriteAppendOnlyFile(char *filename) {
double *score = dictGetEntryVal(de);
if (fwrite(cmd,sizeof(cmd)-1,1,fp) == 0) goto werr;
if (fwriteBulk(fp,key) == 0) goto werr;
if (fwriteBulkObject(fp,key) == 0) goto werr;
if (fwriteBulkDouble(fp,*score) == 0) goto werr;
if (fwriteBulk(fp,eleobj) == 0) goto werr;
if (fwriteBulkObject(fp,eleobj) == 0) goto werr;
}
dictReleaseIterator(di);
} else if (o->type == REDIS_HASH) {
char cmd[]="*4\r\n$4\r\nHSET\r\n";
/* Emit the HSETs needed to rebuild the hash */
if (o->encoding == REDIS_ENCODING_ZIPMAP) {
unsigned char *p = zipmapRewind(o->ptr);
unsigned char *field, *val;
unsigned int flen, vlen;
while((p = zipmapNext(p,&field,&flen,&val,&vlen)) != NULL) {
if (fwrite(cmd,sizeof(cmd)-1,1,fp) == 0) goto werr;
if (fwriteBulkObject(fp,key) == 0) goto werr;
if (fwriteBulkString(fp,(char*)field,flen) == -1)
return -1;
if (fwriteBulkString(fp,(char*)val,vlen) == -1)
return -1;
}
} else {
dictIterator *di = dictGetIterator(o->ptr);
dictEntry *de;
while((de = dictNext(di)) != NULL) {
robj *field = dictGetEntryKey(de);
robj *val = dictGetEntryVal(de);
if (fwrite(cmd,sizeof(cmd)-1,1,fp) == 0) goto werr;
if (fwriteBulkObject(fp,key) == 0) goto werr;
if (fwriteBulkObject(fp,field) == -1) return -1;
if (fwriteBulkObject(fp,val) == -1) return -1;
}
dictReleaseIterator(di);
}
} else {
redisAssert(0 != 0);
}
@ -7716,7 +7760,7 @@ static int rewriteAppendOnlyFile(char *filename) {
/* If this key is already expired skip it */
if (expiretime < now) continue;
if (fwrite(cmd,sizeof(cmd)-1,1,fp) == 0) goto werr;
if (fwriteBulk(fp,key) == 0) goto werr;
if (fwriteBulkObject(fp,key) == 0) goto werr;
if (fwriteBulkLong(fp,expiretime) == 0) goto werr;
}
if (swapped) decrRefCount(o);

View File

@ -24,6 +24,7 @@ static struct redisFunctionSym symsTable[] = {
{"closeTimedoutClients",(unsigned long)closeTimedoutClients},
{"compareStringObjects",(unsigned long)compareStringObjects},
{"computeObjectSwappability",(unsigned long)computeObjectSwappability},
{"convertToRealHash",(unsigned long)convertToRealHash},
{"createClient",(unsigned long)createClient},
{"createHashObject",(unsigned long)createHashObject},
{"createListObject",(unsigned long)createListObject},
@ -75,9 +76,10 @@ static struct redisFunctionSym symsTable[] = {
{"freeSetObject",(unsigned long)freeSetObject},
{"freeStringObject",(unsigned long)freeStringObject},
{"freeZsetObject",(unsigned long)freeZsetObject},
{"fwriteBulk",(unsigned long)fwriteBulk},
{"fwriteBulkDouble",(unsigned long)fwriteBulkDouble},
{"fwriteBulkLong",(unsigned long)fwriteBulkLong},
{"fwriteBulkObject",(unsigned long)fwriteBulkObject},
{"fwriteBulkString",(unsigned long)fwriteBulkString},
{"genRedisInfoString",(unsigned long)genRedisInfoString},
{"genericZrangebyscoreCommand",(unsigned long)genericZrangebyscoreCommand},
{"getCommand",(unsigned long)getCommand},
@ -131,6 +133,7 @@ static struct redisFunctionSym symsTable[] = {
{"processInputBuffer",(unsigned long)processInputBuffer},
{"pushGenericCommand",(unsigned long)pushGenericCommand},
{"qsortCompareSetsByCardinality",(unsigned long)qsortCompareSetsByCardinality},
{"qsortCompareZsetopsrcByCardinality",(unsigned long)qsortCompareZsetopsrcByCardinality},
{"queueIOJob",(unsigned long)queueIOJob},
{"queueMultiCommand",(unsigned long)queueMultiCommand},
{"randomkeyCommand",(unsigned long)randomkeyCommand},
@ -250,13 +253,17 @@ static struct redisFunctionSym symsTable[] = {
{"zcardCommand",(unsigned long)zcardCommand},
{"zcountCommand",(unsigned long)zcountCommand},
{"zincrbyCommand",(unsigned long)zincrbyCommand},
{"zinterCommand",(unsigned long)zinterCommand},
{"zrangeCommand",(unsigned long)zrangeCommand},
{"zrangeGenericCommand",(unsigned long)zrangeGenericCommand},
{"zrangebyscoreCommand",(unsigned long)zrangebyscoreCommand},
{"zrankCommand",(unsigned long)zrankCommand},
{"zrankGenericCommand",(unsigned long)zrankGenericCommand},
{"zremCommand",(unsigned long)zremCommand},
{"zremrangebyrankCommand",(unsigned long)zremrangebyrankCommand},
{"zremrangebyscoreCommand",(unsigned long)zremrangebyscoreCommand},
{"zrevrangeCommand",(unsigned long)zrevrangeCommand},
{"zrevrankCommand",(unsigned long)zrevrankCommand},
{"zscoreCommand",(unsigned long)zscoreCommand},
{"zslCreate",(unsigned long)zslCreate},
{"zslCreateNode",(unsigned long)zslCreateNode},
@ -266,5 +273,7 @@ static struct redisFunctionSym symsTable[] = {
{"zslFreeNode",(unsigned long)zslFreeNode},
{"zslInsert",(unsigned long)zslInsert},
{"zslRandomLevel",(unsigned long)zslRandomLevel},
{"zunionCommand",(unsigned long)zunionCommand},
{"zunionInterGenericCommand",(unsigned long)zunionInterGenericCommand},
{NULL,0}
};