diff --git a/src/rdb.c b/src/rdb.c index e5cc163f..79dd7d6b 100644 --- a/src/rdb.c +++ b/src/rdb.c @@ -973,6 +973,9 @@ size_t rdbSavedObjectLen(robj *o) { int rdbSaveKeyValuePair(rio *rdb, robj *key, robj *val, long long expiretime, long long now) { + int savelru = server.maxmemory_policy & MAXMEMORY_FLAG_LRU; + int savelfu = server.maxmemory_policy & MAXMEMORY_FLAG_LFU; + /* Save the expire time */ if (expiretime != -1) { /* If this key is already expired skip it */ @@ -981,6 +984,26 @@ int rdbSaveKeyValuePair(rio *rdb, robj *key, robj *val, if (rdbSaveMillisecondTime(rdb,expiretime) == -1) return -1; } + /* Save the LRU info. */ + if (savelru) { + int idletime = estimateObjectIdleTime(val); + idletime /= 1000; /* Using seconds is enough and requires less space.*/ + if (rdbSaveType(rdb,RDB_OPCODE_IDLE) == -1) return -1; + if (rdbSaveLen(rdb,idletime) == -1) return -1; + } + + /* Save the LFU info. */ + if (savelfu) { + uint8_t buf[1]; + buf[0] = LFUDecrAndReturn(val); + /* We can encode this in exactly two bytes: the opcode and an 8 + * bit counter, since the frequency is logarithmic with a 0-255 range. + * Note that we do not store the halving time because to reset it + * a single time when loading does not affect the frequency much. */ + if (rdbSaveType(rdb,RDB_OPCODE_FREQ) == -1) return -1; + if (rdbWriteRaw(rdb,buf,1) == -1) return -1; + } + /* Save type, key, value */ if (rdbSaveObjectType(rdb,val) == -1) return -1; if (rdbSaveStringObject(rdb,key) == -1) return -1; diff --git a/src/rdb.h b/src/rdb.h index 2456cfb5..321c9a89 100644 --- a/src/rdb.h +++ b/src/rdb.h @@ -97,12 +97,14 @@ #define rdbIsObjectType(t) ((t >= 0 && t <= 7) || (t >= 9 && t <= 15)) /* Special RDB opcodes (saved/loaded with rdbSaveType/rdbLoadType). */ -#define RDB_OPCODE_AUX 250 -#define RDB_OPCODE_RESIZEDB 251 -#define RDB_OPCODE_EXPIRETIME_MS 252 -#define RDB_OPCODE_EXPIRETIME 253 -#define RDB_OPCODE_SELECTDB 254 -#define RDB_OPCODE_EOF 255 +#define RDB_OPCODE_IDLE 248 /* LRU idle time. */ +#define RDB_OPCODE_FREQ 249 /* LFU frequency. */ +#define RDB_OPCODE_AUX 250 /* RDB aux field. */ +#define RDB_OPCODE_RESIZEDB 251 /* Hash table resize hint. */ +#define RDB_OPCODE_EXPIRETIME_MS 252 /* Expire time in milliseconds. */ +#define RDB_OPCODE_EXPIRETIME 253 /* Old expire time in seconds. */ +#define RDB_OPCODE_SELECTDB 254 /* DB number of the following keys. */ +#define RDB_OPCODE_EOF 255 /* End of the RDB file. */ /* Module serialized values sub opcodes */ #define RDB_MODULE_OPCODE_EOF 0 /* End of module value. */