mirror of
https://codeberg.org/redict/redict.git
synced 2025-01-22 16:18:28 -05:00
LFU: Initial naive eviction cycle.
It is possible to get better results by using the pool like in the LRU case. Also from tests during the morning I believe the current implementation has issues in the frequency decay function that should decrease the counter at periodic intervals.
This commit is contained in:
parent
24dd4a8f04
commit
a8e2d0849e
9
src/db.c
9
src/db.c
@ -175,7 +175,14 @@ void dbOverwrite(redisDb *db, robj *key, robj *val) {
|
||||
dictEntry *de = dictFind(db->dict,key->ptr);
|
||||
|
||||
serverAssertWithInfo(NULL,key,de != NULL);
|
||||
dictReplace(db->dict, key->ptr, val);
|
||||
if (server.maxmemory_policy & MAXMEMORY_FLAG_LFU) {
|
||||
robj *old = dictGetVal(de);
|
||||
int saved_lru = old->lru;
|
||||
dictReplace(db->dict, key->ptr, val);
|
||||
val->lru = saved_lru;
|
||||
} else {
|
||||
dictReplace(db->dict, key->ptr, val);
|
||||
}
|
||||
}
|
||||
|
||||
/* High level Set operation. This function can be used in order to set
|
||||
|
36
src/evict.c
36
src/evict.c
@ -294,6 +294,7 @@ unsigned long LFUDecrAndReturn(robj *o) {
|
||||
if (LFUTimeElapsed(ldt) > LFU_DECR_INTERVAL && counter) {
|
||||
if (counter > LFU_INIT_VAL*2) {
|
||||
counter /= 2;
|
||||
if (counter < LFU_INIT_VAL*2) counter = LFU_INIT_VAL*2;
|
||||
} else {
|
||||
counter--;
|
||||
}
|
||||
@ -360,9 +361,7 @@ int freeMemoryIfNeeded(void) {
|
||||
dict *dict;
|
||||
dictEntry *de;
|
||||
|
||||
if (server.maxmemory_policy == MAXMEMORY_ALLKEYS_LRU ||
|
||||
server.maxmemory_policy == MAXMEMORY_VOLATILE_LRU)
|
||||
{
|
||||
if (server.maxmemory_policy & MAXMEMORY_FLAG_LRU) {
|
||||
struct evictionPoolEntry *pool = EvictionPoolLRU;
|
||||
|
||||
while(bestkey == NULL) {
|
||||
@ -470,6 +469,37 @@ int freeMemoryIfNeeded(void) {
|
||||
}
|
||||
}
|
||||
|
||||
/* allkeys-lfu and volatile-lfu */
|
||||
else if (server.maxmemory_policy & MAXMEMORY_FLAG_LFU) {
|
||||
long bestfreq = 0; /* Initialized to avoid warning. */
|
||||
|
||||
for (i = 0; i < server.dbnum; i++) {
|
||||
j = (++next_db) % server.dbnum;
|
||||
db = server.db+j;
|
||||
dict = (server.maxmemory_policy == MAXMEMORY_ALLKEYS_LFU) ?
|
||||
db->dict : db->expires;
|
||||
if (dictSize(dict) != 0) {
|
||||
for (k = 0; k < server.maxmemory_samples; k++) {
|
||||
sds thiskey;
|
||||
long thisfreq;
|
||||
|
||||
de = dictGetRandomKey(dict);
|
||||
thiskey = dictGetKey(de);
|
||||
robj *o = dictFetchValue(db->dict,thiskey);
|
||||
thisfreq = LFUDecrAndReturn(o);
|
||||
|
||||
/* Keys with a smaller access frequency are
|
||||
* better candidates for deletion */
|
||||
if (bestkey == NULL || thisfreq < bestfreq) {
|
||||
bestkey = thiskey;
|
||||
bestfreq = thisfreq;
|
||||
bestdbid = j;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Finally remove the selected key. */
|
||||
if (bestkey) {
|
||||
db = server.db+bestdbid;
|
||||
|
@ -722,10 +722,18 @@ void objectCommand(client *c) {
|
||||
} else if (!strcasecmp(c->argv[1]->ptr,"idletime") && c->argc == 3) {
|
||||
if ((o = objectCommandLookupOrReply(c,c->argv[2],shared.nullbulk))
|
||||
== NULL) return;
|
||||
if (server.maxmemory_policy & MAXMEMORY_FLAG_LFU) {
|
||||
addReplyError(c,"An LFU maxmemory policy is selected, idle time not tracked. Please note that when switching between policies at runtime LRU and LFU data will take some time to adjust.");
|
||||
return;
|
||||
}
|
||||
addReplyLongLong(c,estimateObjectIdleTime(o)/1000);
|
||||
} else if (!strcasecmp(c->argv[1]->ptr,"freq") && c->argc == 3) {
|
||||
if ((o = objectCommandLookupOrReply(c,c->argv[2],shared.nullbulk))
|
||||
== NULL) return;
|
||||
if (server.maxmemory_policy & MAXMEMORY_FLAG_LRU) {
|
||||
addReplyError(c,"An LRU maxmemory policy is selected, access frequency not tracked. Please note that when switching between policies at runtime LRU and LFU data will take some time to adjust.");
|
||||
return;
|
||||
}
|
||||
addReplyLongLong(c,o->lru&255);
|
||||
} else {
|
||||
addReplyError(c,"Syntax error. Try OBJECT (refcount|encoding|idletime|freq)");
|
||||
|
Loading…
Reference in New Issue
Block a user