Commit f7043604 authored by Matt Stancliff's avatar Matt Stancliff
Browse files

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 ...
parent cf76af6b
...@@ -336,10 +336,10 @@ void debugCommand(redisClient *c) { ...@@ -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;
......
...@@ -222,10 +222,10 @@ int rdbTryIntegerEncoding(char *s, size_t len, unsigned char *enc) { ...@@ -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: ...@@ -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) { ...@@ -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: ...@@ -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) { ...@@ -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) { ...@@ -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) { ...@@ -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); ...@@ -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);
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment