From: Pieter Noordhuis Date: Sun, 21 Nov 2010 14:39:34 +0000 (+0100) Subject: Return number of bytes written from rdbSave* functions X-Git-Url: https://git.saurik.com/redis.git/commitdiff_plain/8a623a98c31bda69c05f2c7c94bad2d131060b02 Return number of bytes written from rdbSave* functions --- diff --git a/src/rdb.c b/src/rdb.c index ce4b3566..f89ce270 100644 --- a/src/rdb.c +++ b/src/rdb.c @@ -11,36 +11,40 @@ int rdbSaveType(FILE *fp, unsigned char type) { if (fwrite(&type,1,1,fp) == 0) return -1; - return 0; + return 1; /* bytes written */ } int rdbSaveTime(FILE *fp, time_t t) { int32_t t32 = (int32_t) t; if (fwrite(&t32,4,1,fp) == 0) return -1; - return 0; + return 4; /* bytes written */ } /* check rdbLoadLen() comments for more info */ int rdbSaveLen(FILE *fp, uint32_t len) { unsigned char buf[2]; + int nwritten; if (len < (1<<6)) { /* Save a 6 bit len */ buf[0] = (len&0xFF)|(REDIS_RDB_6BITLEN<<6); if (fwrite(buf,1,1,fp) == 0) return -1; + nwritten = 1; } else if (len < (1<<14)) { /* Save a 14 bit len */ buf[0] = ((len>>8)&0xFF)|(REDIS_RDB_14BITLEN<<6); buf[1] = len&0xFF; if (fwrite(buf,2,1,fp) == 0) return -1; + nwritten = 2; } else { /* Save a 32 bit len */ buf[0] = (REDIS_RDB_32BITLEN<<6); if (fwrite(buf,1,1,fp) == 0) return -1; len = htonl(len); if (fwrite(&len,4,1,fp) == 0) return -1; + nwritten = 1+4; } - return 0; + return nwritten; } /* Encode 'value' as an integer if possible (if integer will fit the @@ -93,6 +97,7 @@ int rdbTryIntegerEncoding(char *s, size_t len, unsigned char *enc) { int rdbSaveLzfStringObject(FILE *fp, unsigned char *s, size_t len) { size_t comprlen, outlen; unsigned char byte; + int n, nwritten = 0; void *out; /* We require at least four bytes compression for this to be worth it */ @@ -107,11 +112,19 @@ int rdbSaveLzfStringObject(FILE *fp, unsigned char *s, size_t len) { /* Data compressed! Let's save it on disk */ byte = (REDIS_RDB_ENCVAL<<6)|REDIS_RDB_ENC_LZF; if (fwrite(&byte,1,1,fp) == 0) goto writeerr; - if (rdbSaveLen(fp,comprlen) == -1) goto writeerr; - if (rdbSaveLen(fp,len) == -1) goto writeerr; + nwritten += 1; + + if ((n = rdbSaveLen(fp,comprlen)) == -1) goto writeerr; + nwritten += n; + + if ((n = rdbSaveLen(fp,len)) == -1) goto writeerr; + nwritten += n; + if (fwrite(out,comprlen,1,fp) == 0) goto writeerr; + nwritten += comprlen; + zfree(out); - return comprlen; + return nwritten; writeerr: zfree(out); @@ -122,47 +135,54 @@ writeerr: * representation of an integer value we try to safe it in a special form */ int rdbSaveRawString(FILE *fp, unsigned char *s, size_t len) { int enclen; + int n, nwritten = 0; /* Try integer encoding */ if (len <= 11) { unsigned char buf[5]; if ((enclen = rdbTryIntegerEncoding((char*)s,len,buf)) > 0) { if (fwrite(buf,enclen,1,fp) == 0) return -1; - return 0; + return enclen; } } /* Try LZF compression - under 20 bytes it's unable to compress even * aaaaaaaaaaaaaaaaaa so skip it */ if (server.rdbcompression && len > 20) { - int retval; - - retval = rdbSaveLzfStringObject(fp,s,len); - if (retval == -1) return -1; - if (retval > 0) return 0; - /* retval == 0 means data can't be compressed, save the old way */ + n = rdbSaveLzfStringObject(fp,s,len); + if (n == -1) return -1; + if (n > 0) return n; + /* Return value of 0 means data can't be compressed, save the old way */ } /* Store verbatim */ - if (rdbSaveLen(fp,len) == -1) return -1; - if (len && fwrite(s,len,1,fp) == 0) return -1; - return 0; + if ((n = rdbSaveLen(fp,len)) == -1) return -1; + nwritten += n; + if (len > 0) { + if (fwrite(s,len,1,fp) == 0) return -1; + nwritten += len; + } + return nwritten; } /* Save a long long value as either an encoded string or a string. */ int rdbSaveLongLongAsStringObject(FILE *fp, long long value) { unsigned char buf[32]; + int n, nwritten = 0; int enclen = rdbEncodeInteger(value,buf); if (enclen > 0) { if (fwrite(buf,enclen,1,fp) == 0) return -1; + nwritten = enclen; } else { /* Encode as string */ enclen = ll2string((char*)buf,32,value); redisAssert(enclen < 32); - if (rdbSaveLen(fp,enclen) == -1) return -1; + if ((n = rdbSaveLen(fp,enclen)) == -1) return -1; + nwritten += n; if (fwrite(buf,enclen,1,fp) == 0) return -1; + nwritten += enclen; } - return 0; + return nwritten; } /* Like rdbSaveStringObjectRaw() but handle encoded objects */ @@ -217,14 +237,17 @@ int rdbSaveDoubleValue(FILE *fp, double val) { len = buf[0]+1; } if (fwrite(buf,len,1,fp) == 0) return -1; - return 0; + return len; } /* Save a Redis object. */ int rdbSaveObject(FILE *fp, robj *o) { + int n, nwritten = 0; + if (o->type == REDIS_STRING) { /* Save a string value */ - if (rdbSaveStringObject(fp,o) == -1) return -1; + if ((n = rdbSaveStringObject(fp,o)) == -1) return -1; + nwritten += n; } else if (o->type == REDIS_LIST) { /* Save a list value */ if (o->encoding == REDIS_ENCODING_ZIPLIST) { @@ -233,15 +256,19 @@ int rdbSaveObject(FILE *fp, robj *o) { unsigned int vlen; long long vlong; - if (rdbSaveLen(fp,ziplistLen(o->ptr)) == -1) return -1; + if ((n = rdbSaveLen(fp,ziplistLen(o->ptr))) == -1) return -1; + nwritten += n; + p = ziplistIndex(o->ptr,0); while(ziplistGet(p,&vstr,&vlen,&vlong)) { if (vstr) { - if (rdbSaveRawString(fp,vstr,vlen) == -1) + if ((n = rdbSaveRawString(fp,vstr,vlen)) == -1) return -1; + nwritten += n; } else { - if (rdbSaveLongLongAsStringObject(fp,vlong) == -1) + if ((n = rdbSaveLongLongAsStringObject(fp,vlong)) == -1) return -1; + nwritten += n; } p = ziplistNext(o->ptr,p); } @@ -250,11 +277,14 @@ int rdbSaveObject(FILE *fp, robj *o) { listIter li; listNode *ln; - if (rdbSaveLen(fp,listLength(list)) == -1) return -1; + if ((n = rdbSaveLen(fp,listLength(list))) == -1) return -1; + nwritten += n; + listRewind(list,&li); while((ln = listNext(&li))) { robj *eleobj = listNodeValue(ln); - if (rdbSaveStringObject(fp,eleobj) == -1) return -1; + if ((n = rdbSaveStringObject(fp,eleobj)) == -1) return -1; + nwritten += n; } } else { redisPanic("Unknown list encoding"); @@ -266,10 +296,13 @@ int rdbSaveObject(FILE *fp, robj *o) { dictIterator *di = dictGetIterator(set); dictEntry *de; - if (rdbSaveLen(fp,dictSize(set)) == -1) return -1; + if ((n = rdbSaveLen(fp,dictSize(set))) == -1) return -1; + nwritten += n; + while((de = dictNext(di)) != NULL) { robj *eleobj = dictGetEntryKey(de); - if (rdbSaveStringObject(fp,eleobj) == -1) return -1; + if ((n = rdbSaveStringObject(fp,eleobj)) == -1) return -1; + nwritten += n; } dictReleaseIterator(di); } else if (o->encoding == REDIS_ENCODING_INTSET) { @@ -277,9 +310,12 @@ int rdbSaveObject(FILE *fp, robj *o) { int64_t llval; int i = 0; - if (rdbSaveLen(fp,intsetLen(is)) == -1) return -1; + if ((n = rdbSaveLen(fp,intsetLen(is))) == -1) return -1; + nwritten += n; + while(intsetGet(is,i++,&llval)) { - if (rdbSaveLongLongAsStringObject(fp,llval) == -1) return -1; + if ((n = rdbSaveLongLongAsStringObject(fp,llval)) == -1) return -1; + nwritten += n; } } else { redisPanic("Unknown set encoding"); @@ -290,13 +326,17 @@ int rdbSaveObject(FILE *fp, robj *o) { dictIterator *di = dictGetIterator(zs->dict); dictEntry *de; - if (rdbSaveLen(fp,dictSize(zs->dict)) == -1) return -1; + if ((n = rdbSaveLen(fp,dictSize(zs->dict))) == -1) return -1; + nwritten += n; + while((de = dictNext(di)) != NULL) { robj *eleobj = dictGetEntryKey(de); double *score = dictGetEntryVal(de); - if (rdbSaveStringObject(fp,eleobj) == -1) return -1; - if (rdbSaveDoubleValue(fp,*score) == -1) return -1; + if ((n = rdbSaveStringObject(fp,eleobj)) == -1) return -1; + nwritten += n; + if ((n = rdbSaveDoubleValue(fp,*score)) == -1) return -1; + nwritten += n; } dictReleaseIterator(di); } else if (o->type == REDIS_HASH) { @@ -307,29 +347,37 @@ int rdbSaveObject(FILE *fp, robj *o) { unsigned char *key, *val; unsigned int klen, vlen; - if (rdbSaveLen(fp,count) == -1) return -1; + if ((n = rdbSaveLen(fp,count)) == -1) return -1; + nwritten += n; + while((p = zipmapNext(p,&key,&klen,&val,&vlen)) != NULL) { - if (rdbSaveRawString(fp,key,klen) == -1) return -1; - if (rdbSaveRawString(fp,val,vlen) == -1) return -1; + if ((n = rdbSaveRawString(fp,key,klen)) == -1) return -1; + nwritten += n; + if ((n = rdbSaveRawString(fp,val,vlen)) == -1) return -1; + nwritten += n; } } else { dictIterator *di = dictGetIterator(o->ptr); dictEntry *de; - if (rdbSaveLen(fp,dictSize((dict*)o->ptr)) == -1) return -1; + if ((n = rdbSaveLen(fp,dictSize((dict*)o->ptr))) == -1) return -1; + nwritten += n; + while((de = dictNext(di)) != NULL) { robj *key = dictGetEntryKey(de); robj *val = dictGetEntryVal(de); - if (rdbSaveStringObject(fp,key) == -1) return -1; - if (rdbSaveStringObject(fp,val) == -1) return -1; + if ((n = rdbSaveStringObject(fp,key)) == -1) return -1; + nwritten += n; + if ((n = rdbSaveStringObject(fp,val)) == -1) return -1; + nwritten += n; } dictReleaseIterator(di); } } else { redisPanic("Unknown object type"); } - return 0; + return nwritten; } /* Return the length the object will have on disk if saved with @@ -337,10 +385,13 @@ int rdbSaveObject(FILE *fp, robj *o) { * this length with very little changes to the code. In the future * we could switch to a faster solution. */ off_t rdbSavedObjectLen(robj *o, FILE *fp) { + int nwritten; if (fp == NULL) fp = server.devnull; rewind(fp); - redisAssert(rdbSaveObject(fp,o) != 1); - return ftello(fp); + + /* Determining the saved length of an object should never return -1 */ + redisAssert((nwritten = rdbSaveObject(fp,o)) != -1); + return nwritten; } /* Return the number of pages required to save this object in the swap file */