mirror of
https://github.com/fluencelabs/redis
synced 2025-03-19 17:10:50 +00:00
Improve RDB type correctness
It's possible large objects could be larger than 'int', so let's upgrade all size counters to ssize_t. This also fixes rdbSaveObject serialized bytes calculation. Since entire serializations of data structures can be large, so we don't want to limit their calculated size to a 32 bit signed max. This commit increases object size calculation and cascades the change back up to serializedlength printing. Before: 127.0.0.1:6379> debug object hihihi ... encoding:quicklist serializedlength:-2147483559 ... After: 127.0.0.1:6379> debug object hihihi ... encoding:quicklist serializedlength:2147483737 ...
This commit is contained in:
parent
cf76af6b9f
commit
f704360462
@ -336,10 +336,10 @@ void debugCommand(redisClient *c) {
|
|||||||
|
|
||||||
addReplyStatusFormat(c,
|
addReplyStatusFormat(c,
|
||||||
"Value at:%p refcount:%d "
|
"Value at:%p refcount:%d "
|
||||||
"encoding:%s serializedlength:%lld "
|
"encoding:%s serializedlength:%zu "
|
||||||
"lru:%d lru_seconds_idle:%llu%s",
|
"lru:%d lru_seconds_idle:%llu%s",
|
||||||
(void*)val, val->refcount,
|
(void*)val, val->refcount,
|
||||||
strenc, (long long) rdbSavedObjectLen(val),
|
strenc, rdbSavedObjectLen(val),
|
||||||
val->lru, estimateObjectIdleTime(val)/1000, extra);
|
val->lru, estimateObjectIdleTime(val)/1000, extra);
|
||||||
} else if (!strcasecmp(c->argv[1]->ptr,"sdslen") && c->argc == 3) {
|
} else if (!strcasecmp(c->argv[1]->ptr,"sdslen") && c->argc == 3) {
|
||||||
dictEntry *de;
|
dictEntry *de;
|
||||||
|
24
src/rdb.c
24
src/rdb.c
@ -222,10 +222,10 @@ int rdbTryIntegerEncoding(char *s, size_t len, unsigned char *enc) {
|
|||||||
return rdbEncodeInteger(value,enc);
|
return rdbEncodeInteger(value,enc);
|
||||||
}
|
}
|
||||||
|
|
||||||
int rdbSaveLzfBlob(rio *rdb, void *data, size_t compress_len,
|
ssize_t rdbSaveLzfBlob(rio *rdb, void *data, size_t compress_len,
|
||||||
size_t original_len) {
|
size_t original_len) {
|
||||||
unsigned char byte;
|
unsigned char byte;
|
||||||
int n, nwritten = 0;
|
ssize_t n, nwritten = 0;
|
||||||
|
|
||||||
/* Data compressed! Let's save it on disk */
|
/* Data compressed! Let's save it on disk */
|
||||||
byte = (REDIS_RDB_ENCVAL<<6)|REDIS_RDB_ENC_LZF;
|
byte = (REDIS_RDB_ENCVAL<<6)|REDIS_RDB_ENC_LZF;
|
||||||
@ -247,7 +247,7 @@ writeerr:
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
int rdbSaveLzfStringObject(rio *rdb, unsigned char *s, size_t len) {
|
ssize_t rdbSaveLzfStringObject(rio *rdb, unsigned char *s, size_t len) {
|
||||||
size_t comprlen, outlen;
|
size_t comprlen, outlen;
|
||||||
void *out;
|
void *out;
|
||||||
|
|
||||||
@ -260,7 +260,7 @@ int rdbSaveLzfStringObject(rio *rdb, unsigned char *s, size_t len) {
|
|||||||
zfree(out);
|
zfree(out);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
size_t nwritten = rdbSaveLzfBlob(rdb, out, comprlen, len);
|
ssize_t nwritten = rdbSaveLzfBlob(rdb, out, comprlen, len);
|
||||||
zfree(out);
|
zfree(out);
|
||||||
return nwritten;
|
return nwritten;
|
||||||
}
|
}
|
||||||
@ -305,9 +305,9 @@ err:
|
|||||||
|
|
||||||
/* Save a string object as [len][data] on disk. If the object is a string
|
/* Save a string object as [len][data] on disk. If the object is a string
|
||||||
* representation of an integer value we try to save it in a special form */
|
* representation of an integer value we try to save it in a special form */
|
||||||
int rdbSaveRawString(rio *rdb, unsigned char *s, size_t len) {
|
ssize_t rdbSaveRawString(rio *rdb, unsigned char *s, size_t len) {
|
||||||
int enclen;
|
int enclen;
|
||||||
int n, nwritten = 0;
|
ssize_t n, nwritten = 0;
|
||||||
|
|
||||||
/* Try integer encoding */
|
/* Try integer encoding */
|
||||||
if (len <= 11) {
|
if (len <= 11) {
|
||||||
@ -338,9 +338,9 @@ int rdbSaveRawString(rio *rdb, unsigned char *s, size_t len) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Save a long long value as either an encoded string or a string. */
|
/* Save a long long value as either an encoded string or a string. */
|
||||||
int rdbSaveLongLongAsStringObject(rio *rdb, long long value) {
|
ssize_t rdbSaveLongLongAsStringObject(rio *rdb, long long value) {
|
||||||
unsigned char buf[32];
|
unsigned char buf[32];
|
||||||
int n, nwritten = 0;
|
ssize_t n, nwritten = 0;
|
||||||
int enclen = rdbEncodeInteger(value,buf);
|
int enclen = rdbEncodeInteger(value,buf);
|
||||||
if (enclen > 0) {
|
if (enclen > 0) {
|
||||||
return rdbWriteRaw(rdb,buf,enclen);
|
return rdbWriteRaw(rdb,buf,enclen);
|
||||||
@ -532,8 +532,8 @@ int rdbLoadObjectType(rio *rdb) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Save a Redis object. Returns -1 on error, number of bytes written on success. */
|
/* Save a Redis object. Returns -1 on error, number of bytes written on success. */
|
||||||
int rdbSaveObject(rio *rdb, robj *o) {
|
ssize_t rdbSaveObject(rio *rdb, robj *o) {
|
||||||
int n = 0, nwritten = 0;
|
ssize_t n = 0, nwritten = 0;
|
||||||
|
|
||||||
if (o->type == REDIS_STRING) {
|
if (o->type == REDIS_STRING) {
|
||||||
/* Save a string value */
|
/* Save a string value */
|
||||||
@ -654,8 +654,8 @@ int rdbSaveObject(rio *rdb, robj *o) {
|
|||||||
* the rdbSaveObject() function. Currently we use a trick to get
|
* the rdbSaveObject() function. Currently we use a trick to get
|
||||||
* this length with very little changes to the code. In the future
|
* this length with very little changes to the code. In the future
|
||||||
* we could switch to a faster solution. */
|
* we could switch to a faster solution. */
|
||||||
off_t rdbSavedObjectLen(robj *o) {
|
size_t rdbSavedObjectLen(robj *o) {
|
||||||
int len = rdbSaveObject(NULL,o);
|
ssize_t len = rdbSaveObject(NULL,o);
|
||||||
redisAssertWithInfo(NULL,o,len != -1);
|
redisAssertWithInfo(NULL,o,len != -1);
|
||||||
return len;
|
return len;
|
||||||
}
|
}
|
||||||
|
@ -109,9 +109,8 @@ int rdbSaveBackground(char *filename);
|
|||||||
int rdbSaveToSlavesSockets(void);
|
int rdbSaveToSlavesSockets(void);
|
||||||
void rdbRemoveTempFile(pid_t childpid);
|
void rdbRemoveTempFile(pid_t childpid);
|
||||||
int rdbSave(char *filename);
|
int rdbSave(char *filename);
|
||||||
int rdbSaveObject(rio *rdb, robj *o);
|
ssize_t rdbSaveObject(rio *rdb, robj *o);
|
||||||
off_t rdbSavedObjectLen(robj *o);
|
size_t rdbSavedObjectLen(robj *o);
|
||||||
off_t rdbSavedObjectPages(robj *o);
|
|
||||||
robj *rdbLoadObject(int type, rio *rdb);
|
robj *rdbLoadObject(int type, rio *rdb);
|
||||||
void backgroundSaveDoneHandler(int exitcode, int bysignal);
|
void backgroundSaveDoneHandler(int exitcode, int bysignal);
|
||||||
int rdbSaveKeyValuePair(rio *rdb, robj *key, robj *val, long long expiretime, long long now);
|
int rdbSaveKeyValuePair(rio *rdb, robj *key, robj *val, long long expiretime, long long now);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user