Skip to content

Commit e8614a1

Browse files
committed
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: redis#1719
1 parent 32b1000 commit e8614a1

File tree

2 files changed

+26
-1
lines changed

2 files changed

+26
-1
lines changed

src/rdb.c

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -714,6 +714,21 @@ int rdbSaveRio(rio *rdb, int *error) {
714714
if (rdbSaveType(rdb,REDIS_RDB_OPCODE_SELECTDB) == -1) goto werr;
715715
if (rdbSaveLen(rdb,j) == -1) goto werr;
716716

717+
/* Write the RESIZE DB opcode. We trim the size to UINT32_MAX, which
718+
* is currently the largest type we are able to represent in RDB sizes.
719+
* However this does not limit the actual size of the DB to load since
720+
* these sizes are just hints to resize the hash tables. */
721+
uint32_t db_size, expires_size;
722+
db_size = (dictSize(db->dict) <= UINT32_MAX) ?
723+
dictSize(db->dict) :
724+
UINT32_MAX;
725+
expires_size = (dictSize(db->dict) <= UINT32_MAX) ?
726+
dictSize(db->expires) :
727+
UINT32_MAX;
728+
if (rdbSaveType(rdb,REDIS_RDB_OPCODE_RESIZEDB) == -1) goto werr;
729+
if (rdbSaveLen(rdb,db_size) == -1) goto werr;
730+
if (rdbSaveLen(rdb,expires_size) == -1) goto werr;
731+
717732
/* Iterate this DB writing every entry */
718733
while((de = dictNext(di)) != NULL) {
719734
sds keystr = dictGetKey(de);
@@ -1226,7 +1241,7 @@ int rdbLoad(char *filename) {
12261241
if (type == REDIS_RDB_OPCODE_EOF)
12271242
break;
12281243

1229-
/* Handle SELECT DB opcode as a special case */
1244+
/* Handle special opcodes: SELECTDB, RESIZEDB, AUX. */
12301245
if (type == REDIS_RDB_OPCODE_SELECTDB) {
12311246
if ((dbid = rdbLoadLen(&rdb,NULL)) == REDIS_RDB_LENERR)
12321247
goto eoferr;
@@ -1236,6 +1251,15 @@ int rdbLoad(char *filename) {
12361251
}
12371252
db = server.db+dbid;
12381253
continue;
1254+
} else if (type == REDIS_RDB_OPCODE_RESIZEDB) {
1255+
uint32_t db_size, expires_size;
1256+
if ((db_size = rdbLoadLen(&rdb,NULL)) == REDIS_RDB_LENERR)
1257+
goto eoferr;
1258+
if ((expires_size = rdbLoadLen(&rdb,NULL)) == REDIS_RDB_LENERR)
1259+
goto eoferr;
1260+
dictExpand(db->dict,db_size);
1261+
dictExpand(db->expires,expires_size);
1262+
continue;
12391263
}
12401264
/* Read key */
12411265
if ((key = rdbLoadStringObject(&rdb)) == NULL) goto eoferr;

src/rdb.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,7 @@
8989
#define rdbIsObjectType(t) ((t >= 0 && t <= 4) || (t >= 9 && t <= 14))
9090

9191
/* Special RDB opcodes (saved/loaded with rdbSaveType/rdbLoadType). */
92+
#define REDIS_RDB_OPCODE_RESIZEDB 251
9293
#define REDIS_RDB_OPCODE_EXPIRETIME_MS 252
9394
#define REDIS_RDB_OPCODE_EXPIRETIME 253
9495
#define REDIS_RDB_OPCODE_SELECTDB 254

0 commit comments

Comments
 (0)