Permalink
Browse files

New RDB v7 opcode: RESIZEDB.

The new opcode is an hint about the size of the dataset (keys and number
of expires) we are going to load for a given Redis database inside the
RDB file. Since hash tables are resized accordingly ASAP, useless
rehashing is avoided, speeding up load times significantly, in the order
of ~ 20% or more for larger data sets.

Related issue: #1719
  • Loading branch information...
antirez committed Jan 7, 2015
1 parent 32b1000 commit e8614a1a77d2989f7be3cb7b24cd88b01f14f17e
Showing with 26 additions and 1 deletion.
  1. +25 −1 src/rdb.c
  2. +1 −0 src/rdb.h
View
@@ -714,6 +714,21 @@ int rdbSaveRio(rio *rdb, int *error) {
if (rdbSaveType(rdb,REDIS_RDB_OPCODE_SELECTDB) == -1) goto werr;
if (rdbSaveLen(rdb,j) == -1) goto werr;
/* Write the RESIZE DB opcode. We trim the size to UINT32_MAX, which
* is currently the largest type we are able to represent in RDB sizes.
* However this does not limit the actual size of the DB to load since
* these sizes are just hints to resize the hash tables. */
uint32_t db_size, expires_size;
db_size = (dictSize(db->dict) <= UINT32_MAX) ?
dictSize(db->dict) :
UINT32_MAX;
expires_size = (dictSize(db->dict) <= UINT32_MAX) ?
dictSize(db->expires) :
UINT32_MAX;
if (rdbSaveType(rdb,REDIS_RDB_OPCODE_RESIZEDB) == -1) goto werr;
if (rdbSaveLen(rdb,db_size) == -1) goto werr;
if (rdbSaveLen(rdb,expires_size) == -1) goto werr;
/* Iterate this DB writing every entry */
while((de = dictNext(di)) != NULL) {
sds keystr = dictGetKey(de);
@@ -1226,7 +1241,7 @@ int rdbLoad(char *filename) {
if (type == REDIS_RDB_OPCODE_EOF)
break;
/* Handle SELECT DB opcode as a special case */
/* Handle special opcodes: SELECTDB, RESIZEDB, AUX. */
if (type == REDIS_RDB_OPCODE_SELECTDB) {
if ((dbid = rdbLoadLen(&rdb,NULL)) == REDIS_RDB_LENERR)
goto eoferr;
@@ -1236,6 +1251,15 @@ int rdbLoad(char *filename) {
}
db = server.db+dbid;
continue;
} else if (type == REDIS_RDB_OPCODE_RESIZEDB) {
uint32_t db_size, expires_size;
if ((db_size = rdbLoadLen(&rdb,NULL)) == REDIS_RDB_LENERR)
goto eoferr;
if ((expires_size = rdbLoadLen(&rdb,NULL)) == REDIS_RDB_LENERR)
goto eoferr;
dictExpand(db->dict,db_size);
dictExpand(db->expires,expires_size);
continue;
}
/* Read key */
if ((key = rdbLoadStringObject(&rdb)) == NULL) goto eoferr;
View
@@ -89,6 +89,7 @@
#define rdbIsObjectType(t) ((t >= 0 && t <= 4) || (t >= 9 && t <= 14))
/* Special RDB opcodes (saved/loaded with rdbSaveType/rdbLoadType). */
#define REDIS_RDB_OPCODE_RESIZEDB 251
#define REDIS_RDB_OPCODE_EXPIRETIME_MS 252
#define REDIS_RDB_OPCODE_EXPIRETIME 253
#define REDIS_RDB_OPCODE_SELECTDB 254

0 comments on commit e8614a1

Please sign in to comment.