mirror of
https://github.com/fluencelabs/redis
synced 2025-03-19 17:10:50 +00:00
RDB: Ability to load LFU/LRU info.
This commit is contained in:
parent
d7a5c0eb71
commit
1ce50a7adf
57
src/rdb.c
57
src/rdb.c
@ -1811,7 +1811,6 @@ int rdbLoadRio(rio *rdb, rdbSaveInfo *rsi) {
|
|||||||
int type, rdbver;
|
int type, rdbver;
|
||||||
redisDb *db = server.db+0;
|
redisDb *db = server.db+0;
|
||||||
char buf[1024];
|
char buf[1024];
|
||||||
long long expiretime, now = mstime();
|
|
||||||
|
|
||||||
rdb->update_cksum = rdbLoadProgressCallback;
|
rdb->update_cksum = rdbLoadProgressCallback;
|
||||||
rdb->max_processing_chunk = server.loading_process_events_interval_bytes;
|
rdb->max_processing_chunk = server.loading_process_events_interval_bytes;
|
||||||
@ -1829,9 +1828,14 @@ int rdbLoadRio(rio *rdb, rdbSaveInfo *rsi) {
|
|||||||
return C_ERR;
|
return C_ERR;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Key-specific attributes, set by opcodes before the key type. */
|
||||||
|
long long expiretime = -1, now = mstime();
|
||||||
|
long long lru_clock = LRU_CLOCK();
|
||||||
|
uint64_t lru_idle = -1;
|
||||||
|
int lfu_freq = -1;
|
||||||
|
|
||||||
while(1) {
|
while(1) {
|
||||||
robj *key, *val;
|
robj *key, *val;
|
||||||
expiretime = -1;
|
|
||||||
|
|
||||||
/* Read type. */
|
/* Read type. */
|
||||||
if ((type = rdbLoadType(rdb)) == -1) goto eoferr;
|
if ((type = rdbLoadType(rdb)) == -1) goto eoferr;
|
||||||
@ -1842,24 +1846,27 @@ int rdbLoadRio(rio *rdb, rdbSaveInfo *rsi) {
|
|||||||
* to load. Note that after loading an expire we need to
|
* to load. Note that after loading an expire we need to
|
||||||
* load the actual type, and continue. */
|
* load the actual type, and continue. */
|
||||||
expiretime = rdbLoadTime(rdb);
|
expiretime = rdbLoadTime(rdb);
|
||||||
/* We read the time so we need to read the object type again. */
|
|
||||||
if ((type = rdbLoadType(rdb)) == -1) goto eoferr;
|
|
||||||
/* the EXPIRETIME opcode specifies time in seconds, so convert
|
|
||||||
* into milliseconds. */
|
|
||||||
expiretime *= 1000;
|
expiretime *= 1000;
|
||||||
|
continue; /* Read next opcode. */
|
||||||
} else if (type == RDB_OPCODE_EXPIRETIME_MS) {
|
} else if (type == RDB_OPCODE_EXPIRETIME_MS) {
|
||||||
/* EXPIRETIME_MS: milliseconds precision expire times introduced
|
/* EXPIRETIME_MS: milliseconds precision expire times introduced
|
||||||
* with RDB v3. Like EXPIRETIME but no with more precision. */
|
* with RDB v3. Like EXPIRETIME but no with more precision. */
|
||||||
expiretime = rdbLoadMillisecondTime(rdb);
|
expiretime = rdbLoadMillisecondTime(rdb);
|
||||||
/* We read the time so we need to read the object type again. */
|
continue; /* Read next opcode. */
|
||||||
if ((type = rdbLoadType(rdb)) == -1) goto eoferr;
|
} else if (type == RDB_OPCODE_FREQ) {
|
||||||
|
/* FREQ: LFU frequency. */
|
||||||
|
uint8_t byte;
|
||||||
|
if (rioRead(rdb,&byte,1) == 0) goto eoferr;
|
||||||
|
lfu_freq = byte;
|
||||||
|
} else if (type == RDB_OPCODE_IDLE) {
|
||||||
|
/* IDLE: LRU idle time. */
|
||||||
|
if ((lru_idle = rdbLoadLen(rdb,NULL)) == RDB_LENERR) goto eoferr;
|
||||||
} else if (type == RDB_OPCODE_EOF) {
|
} else if (type == RDB_OPCODE_EOF) {
|
||||||
/* EOF: End of file, exit the main loop. */
|
/* EOF: End of file, exit the main loop. */
|
||||||
break;
|
break;
|
||||||
} else if (type == RDB_OPCODE_SELECTDB) {
|
} else if (type == RDB_OPCODE_SELECTDB) {
|
||||||
/* SELECTDB: Select the specified database. */
|
/* SELECTDB: Select the specified database. */
|
||||||
if ((dbid = rdbLoadLen(rdb,NULL)) == RDB_LENERR)
|
if ((dbid = rdbLoadLen(rdb,NULL)) == RDB_LENERR) goto eoferr;
|
||||||
goto eoferr;
|
|
||||||
if (dbid >= (unsigned)server.dbnum) {
|
if (dbid >= (unsigned)server.dbnum) {
|
||||||
serverLog(LL_WARNING,
|
serverLog(LL_WARNING,
|
||||||
"FATAL: Data file was created with a Redis "
|
"FATAL: Data file was created with a Redis "
|
||||||
@ -1868,7 +1875,7 @@ int rdbLoadRio(rio *rdb, rdbSaveInfo *rsi) {
|
|||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
db = server.db+dbid;
|
db = server.db+dbid;
|
||||||
continue; /* Read type again. */
|
continue; /* Read next opcode. */
|
||||||
} else if (type == RDB_OPCODE_RESIZEDB) {
|
} else if (type == RDB_OPCODE_RESIZEDB) {
|
||||||
/* RESIZEDB: Hint about the size of the keys in the currently
|
/* RESIZEDB: Hint about the size of the keys in the currently
|
||||||
* selected data base, in order to avoid useless rehashing. */
|
* selected data base, in order to avoid useless rehashing. */
|
||||||
@ -1879,7 +1886,7 @@ int rdbLoadRio(rio *rdb, rdbSaveInfo *rsi) {
|
|||||||
goto eoferr;
|
goto eoferr;
|
||||||
dictExpand(db->dict,db_size);
|
dictExpand(db->dict,db_size);
|
||||||
dictExpand(db->expires,expires_size);
|
dictExpand(db->expires,expires_size);
|
||||||
continue; /* Read type again. */
|
continue; /* Read next opcode. */
|
||||||
} else if (type == RDB_OPCODE_AUX) {
|
} else if (type == RDB_OPCODE_AUX) {
|
||||||
/* AUX: generic string-string fields. Use to add state to RDB
|
/* AUX: generic string-string fields. Use to add state to RDB
|
||||||
* which is backward compatible. Implementations of RDB loading
|
* which is backward compatible. Implementations of RDB loading
|
||||||
@ -1937,16 +1944,38 @@ int rdbLoadRio(rio *rdb, rdbSaveInfo *rsi) {
|
|||||||
if (server.masterhost == NULL && expiretime != -1 && expiretime < now) {
|
if (server.masterhost == NULL && expiretime != -1 && expiretime < now) {
|
||||||
decrRefCount(key);
|
decrRefCount(key);
|
||||||
decrRefCount(val);
|
decrRefCount(val);
|
||||||
continue;
|
} else {
|
||||||
}
|
|
||||||
/* Add the new object in the hash table */
|
/* Add the new object in the hash table */
|
||||||
dbAdd(db,key,val);
|
dbAdd(db,key,val);
|
||||||
|
|
||||||
/* Set the expire time if needed */
|
/* Set the expire time if needed */
|
||||||
if (expiretime != -1) setExpire(NULL,db,key,expiretime);
|
if (expiretime != -1) setExpire(NULL,db,key,expiretime);
|
||||||
|
if (lfu_freq != -1) {
|
||||||
|
val->lru = (LFUGetTimeInMinutes()<<8) | lfu_freq;
|
||||||
|
} else {
|
||||||
|
/* LRU idle time loaded from RDB is in seconds. Scale
|
||||||
|
* according to the LRU clock resolution this Redis
|
||||||
|
* instance was compiled with (normaly 1000 ms, so the
|
||||||
|
* below statement will expand to lru_idle*1000/1000. */
|
||||||
|
lru_idle = lru_idle*1000/LRU_CLOCK_RESOLUTION;
|
||||||
|
val->lru = lru_clock - lru_idle;
|
||||||
|
/* If the lru field overflows (since LRU it is a wrapping
|
||||||
|
* clock), the best we can do is to provide the maxium
|
||||||
|
* representable idle time. */
|
||||||
|
if (val->lru < 0) val->lru = lru_clock+1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Decrement the key refcount since dbAdd() will take its
|
||||||
|
* own reference. */
|
||||||
decrRefCount(key);
|
decrRefCount(key);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Reset the state that is key-specified and is populated by
|
||||||
|
* opcodes before the key, so that we start from scratch again. */
|
||||||
|
expiretime = -1;
|
||||||
|
lfu_freq = -1;
|
||||||
|
lru_idle = -1;
|
||||||
|
}
|
||||||
/* Verify the checksum if RDB version is >= 5 */
|
/* Verify the checksum if RDB version is >= 5 */
|
||||||
if (rdbver >= 5 && server.rdb_checksum) {
|
if (rdbver >= 5 && server.rdb_checksum) {
|
||||||
uint64_t cksum, expected = rdb->cksum;
|
uint64_t cksum, expected = rdb->cksum;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user