Fix objectSetLRUOrLFU() when LFU underflows.

This commit is contained in:
antirez 2019-03-14 17:06:59 +01:00
parent d292a51618
commit 052e03495f

View File

@ -1210,16 +1210,20 @@ void objectSetLRUOrLFU(robj *val, long long lfu_freq, long long lru_idle,
val->lru = (LFUGetTimeInMinutes()<<8) | lfu_freq; val->lru = (LFUGetTimeInMinutes()<<8) | lfu_freq;
} }
} else if (lru_idle >= 0) { } else if (lru_idle >= 0) {
/* Serialized LRU idle time is in seconds. Scale /* Provided LRU idle time is in seconds. Scale
* according to the LRU clock resolution this Redis * according to the LRU clock resolution this Redis
* instance was compiled with (normally 1000 ms, so the * instance was compiled with (normally 1000 ms, so the
* below statement will expand to lru_idle*1000/1000. */ * below statement will expand to lru_idle*1000/1000. */
lru_idle = lru_idle*1000/LRU_CLOCK_RESOLUTION; lru_idle = lru_idle*1000/LRU_CLOCK_RESOLUTION;
val->lru = lru_clock - lru_idle; long lru_abs = lru_clock - lru_idle; /* Absolute access time. */
/* If the lru field overflows (since LRU it is a wrapping /* If the LRU field underflows (since LRU it is a wrapping
* clock), the best we can do is to provide the maximum * clock), the best we can do is to provide a large enough LRU
* representable idle time. */ * that is half-way in the circlular LRU clock we use: this way
if (val->lru < 0) val->lru = lru_clock+1; * the computed idle time for this object will stay high for quite
* some time. */
if (lru_abs < 0)
lru_abs = (lru_clock+(LRU_CLOCK_MAX/2)) % LRU_CLOCK_MAX;
val->lru = lru_abs;
} }
} }