mirror of
https://github.com/fluencelabs/redis
synced 2025-03-19 17:10:50 +00:00
RDB refactored to load plain strings from RDB.
This commit is contained in:
parent
05ba119fbb
commit
68bc02c36c
78
src/rdb.c
78
src/rdb.c
@ -40,6 +40,10 @@
|
|||||||
#include <arpa/inet.h>
|
#include <arpa/inet.h>
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
|
|
||||||
|
#define RDB_LOAD_NONE 0
|
||||||
|
#define RDB_LOAD_ENC (1<<0)
|
||||||
|
#define RDB_LOAD_PLAIN (1<<1)
|
||||||
|
|
||||||
static int rdbWriteRaw(rio *rdb, void *p, size_t len) {
|
static int rdbWriteRaw(rio *rdb, void *p, size_t len) {
|
||||||
if (rdb && rioWrite(rdb,p,len) == 0)
|
if (rdb && rioWrite(rdb,p,len) == 0)
|
||||||
return -1;
|
return -1;
|
||||||
@ -161,9 +165,11 @@ int rdbEncodeInteger(long long value, unsigned char *enc) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Loads an integer-encoded object with the specified encoding type "enctype".
|
/* Loads an integer-encoded object with the specified encoding type "enctype".
|
||||||
* If the "encode" argument is set the function may return an integer-encoded
|
* The returned value changes according to the flags, see
|
||||||
* string object, otherwise it always returns a raw string object. */
|
* rdbGenerincLoadStringObject() for more info. */
|
||||||
robj *rdbLoadIntegerObject(rio *rdb, int enctype, int encode) {
|
void *rdbLoadIntegerObject(rio *rdb, int enctype, int flags) {
|
||||||
|
int plain = flags & RDB_LOAD_PLAIN;
|
||||||
|
int encode = flags & RDB_LOAD_ENC;
|
||||||
unsigned char enc[4];
|
unsigned char enc[4];
|
||||||
long long val;
|
long long val;
|
||||||
|
|
||||||
@ -184,11 +190,18 @@ robj *rdbLoadIntegerObject(rio *rdb, int enctype, int encode) {
|
|||||||
val = 0; /* anti-warning */
|
val = 0; /* anti-warning */
|
||||||
redisPanic("Unknown RDB integer encoding type");
|
redisPanic("Unknown RDB integer encoding type");
|
||||||
}
|
}
|
||||||
if (encode)
|
if (plain) {
|
||||||
|
char buf[REDIS_LONGSTR_SIZE], *p;
|
||||||
|
int len = ll2string(buf,sizeof(buf),val);
|
||||||
|
p = zmalloc(len);
|
||||||
|
memcpy(p,buf,len);
|
||||||
|
return p;
|
||||||
|
} else if (encode) {
|
||||||
return createStringObjectFromLongLong(val);
|
return createStringObjectFromLongLong(val);
|
||||||
else
|
} else {
|
||||||
return createObject(REDIS_STRING,sdsfromlonglong(val));
|
return createObject(REDIS_STRING,sdsfromlonglong(val));
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* String objects in the form "2391" "-100" without any space and with a
|
/* String objects in the form "2391" "-100" without any space and with a
|
||||||
* range of values that can fit in an 8, 16 or 32 bit signed value can be
|
* range of values that can fit in an 8, 16 or 32 bit signed value can be
|
||||||
@ -252,7 +265,11 @@ int rdbSaveLzfStringObject(rio *rdb, unsigned char *s, size_t len) {
|
|||||||
return nwritten;
|
return nwritten;
|
||||||
}
|
}
|
||||||
|
|
||||||
robj *rdbLoadLzfStringObject(rio *rdb) {
|
/* Load an LZF compressed string in RDB format. The returned value
|
||||||
|
* changes according to 'flags'. For more info check the
|
||||||
|
* rdbGenericLoadStringObject() function. */
|
||||||
|
void *rdbLoadLzfStringObject(rio *rdb, int flags) {
|
||||||
|
int plain = flags & RDB_LOAD_PLAIN;
|
||||||
unsigned int len, clen;
|
unsigned int len, clen;
|
||||||
unsigned char *c = NULL;
|
unsigned char *c = NULL;
|
||||||
sds val = NULL;
|
sds val = NULL;
|
||||||
@ -260,13 +277,28 @@ robj *rdbLoadLzfStringObject(rio *rdb) {
|
|||||||
if ((clen = rdbLoadLen(rdb,NULL)) == REDIS_RDB_LENERR) return NULL;
|
if ((clen = rdbLoadLen(rdb,NULL)) == REDIS_RDB_LENERR) return NULL;
|
||||||
if ((len = rdbLoadLen(rdb,NULL)) == REDIS_RDB_LENERR) return NULL;
|
if ((len = rdbLoadLen(rdb,NULL)) == REDIS_RDB_LENERR) return NULL;
|
||||||
if ((c = zmalloc(clen)) == NULL) goto err;
|
if ((c = zmalloc(clen)) == NULL) goto err;
|
||||||
|
|
||||||
|
/* Allocate our target according to the uncompressed size. */
|
||||||
|
if (plain) {
|
||||||
|
val = zmalloc(len);
|
||||||
|
} else {
|
||||||
if ((val = sdsnewlen(NULL,len)) == NULL) goto err;
|
if ((val = sdsnewlen(NULL,len)) == NULL) goto err;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Load the compressed representation and uncompress it to target. */
|
||||||
if (rioRead(rdb,c,clen) == 0) goto err;
|
if (rioRead(rdb,c,clen) == 0) goto err;
|
||||||
if (lzf_decompress(c,clen,val,len) == 0) goto err;
|
if (lzf_decompress(c,clen,val,len) == 0) goto err;
|
||||||
zfree(c);
|
zfree(c);
|
||||||
|
|
||||||
|
if (plain)
|
||||||
|
return val;
|
||||||
|
else
|
||||||
return createObject(REDIS_STRING,val);
|
return createObject(REDIS_STRING,val);
|
||||||
err:
|
err:
|
||||||
zfree(c);
|
zfree(c);
|
||||||
|
if (plain)
|
||||||
|
zfree(val);
|
||||||
|
else
|
||||||
sdsfree(val);
|
sdsfree(val);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
@ -336,10 +368,21 @@ int rdbSaveStringObject(rio *rdb, robj *obj) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
robj *rdbGenericLoadStringObject(rio *rdb, int encode) {
|
/* Load a string object from an RDB file according to flags:
|
||||||
|
*
|
||||||
|
* RDB_LOAD_NONE (no flags): load an RDB object, unencoded.
|
||||||
|
* RDB_LOAD_ENC: If the returned type is a Redis object, try to
|
||||||
|
* encode it in a special way to be more memory
|
||||||
|
* efficient. When this flag is passed the function
|
||||||
|
* no longer guarantees that obj->ptr is an SDS string.
|
||||||
|
* RDB_LOAD_PLAIN: Return a plain string allocated with zmalloc()
|
||||||
|
* instead of a Redis object.
|
||||||
|
*/
|
||||||
|
void *rdbGenericLoadStringObject(rio *rdb, int flags) {
|
||||||
|
int encode = flags & RDB_LOAD_ENC;
|
||||||
|
int plain = flags & RDB_LOAD_PLAIN;
|
||||||
int isencoded;
|
int isencoded;
|
||||||
uint32_t len;
|
uint32_t len;
|
||||||
robj *o;
|
|
||||||
|
|
||||||
len = rdbLoadLen(rdb,&isencoded);
|
len = rdbLoadLen(rdb,&isencoded);
|
||||||
if (isencoded) {
|
if (isencoded) {
|
||||||
@ -347,30 +390,39 @@ robj *rdbGenericLoadStringObject(rio *rdb, int encode) {
|
|||||||
case REDIS_RDB_ENC_INT8:
|
case REDIS_RDB_ENC_INT8:
|
||||||
case REDIS_RDB_ENC_INT16:
|
case REDIS_RDB_ENC_INT16:
|
||||||
case REDIS_RDB_ENC_INT32:
|
case REDIS_RDB_ENC_INT32:
|
||||||
return rdbLoadIntegerObject(rdb,len,encode);
|
return rdbLoadIntegerObject(rdb,len,flags);
|
||||||
case REDIS_RDB_ENC_LZF:
|
case REDIS_RDB_ENC_LZF:
|
||||||
return rdbLoadLzfStringObject(rdb);
|
return rdbLoadLzfStringObject(rdb,flags);
|
||||||
default:
|
default:
|
||||||
redisPanic("Unknown RDB encoding type");
|
redisPanic("Unknown RDB encoding type");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (len == REDIS_RDB_LENERR) return NULL;
|
if (len == REDIS_RDB_LENERR) return NULL;
|
||||||
o = encode ? createStringObject(NULL,len) :
|
if (!plain) {
|
||||||
|
robj *o = encode ? createStringObject(NULL,len) :
|
||||||
createRawStringObject(NULL,len);
|
createRawStringObject(NULL,len);
|
||||||
if (len && rioRead(rdb,o->ptr,len) == 0) {
|
if (len && rioRead(rdb,o->ptr,len) == 0) {
|
||||||
decrRefCount(o);
|
decrRefCount(o);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
return o;
|
return o;
|
||||||
|
} else {
|
||||||
|
void *buf = zmalloc(len);
|
||||||
|
if (len && rioRead(rdb,buf,len) == 0) {
|
||||||
|
zfree(buf);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
return buf;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
robj *rdbLoadStringObject(rio *rdb) {
|
robj *rdbLoadStringObject(rio *rdb) {
|
||||||
return rdbGenericLoadStringObject(rdb,0);
|
return rdbGenericLoadStringObject(rdb,RDB_LOAD_NONE);
|
||||||
}
|
}
|
||||||
|
|
||||||
robj *rdbLoadEncodedStringObject(rio *rdb) {
|
robj *rdbLoadEncodedStringObject(rio *rdb) {
|
||||||
return rdbGenericLoadStringObject(rdb,1);
|
return rdbGenericLoadStringObject(rdb,RDB_LOAD_ENC);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Save a double value. Doubles are saved as strings prefixed by an unsigned
|
/* Save a double value. Doubles are saved as strings prefixed by an unsigned
|
||||||
|
Loading…
x
Reference in New Issue
Block a user