+
+ for (j = 0; j < server.dbnum; j++) {
+ long bestval;
+ sds bestkey = NULL;
+ struct dictEntry *de;
+ redisDb *db = server.db+j;
+ dict *dict;
+
+ if (server.maxmemory_policy == REDIS_MAXMEMORY_ALLKEYS_LRU ||
+ server.maxmemory_policy == REDIS_MAXMEMORY_ALLKEYS_RANDOM)
+ {
+ dict = server.db[j].dict;
+ } else {
+ dict = server.db[j].expires;
+ }
+ if (dictSize(dict) == 0) continue;
+
+ /* volatile-random and allkeys-random policy */
+ if (server.maxmemory_policy == REDIS_MAXMEMORY_ALLKEYS_RANDOM ||
+ server.maxmemory_policy == REDIS_MAXMEMORY_VOLATILE_RANDOM)
+ {
+ de = dictGetRandomKey(dict);
+ bestkey = dictGetEntryKey(de);
+ }
+
+ /* volatile-lru and allkeys-lru policy */
+ else if (server.maxmemory_policy == REDIS_MAXMEMORY_ALLKEYS_LRU ||
+ server.maxmemory_policy == REDIS_MAXMEMORY_VOLATILE_LRU)
+ {
+ for (k = 0; k < server.maxmemory_samples; k++) {
+ sds thiskey;
+ long thisval;
+ robj *o;
+
+ de = dictGetRandomKey(dict);
+ thiskey = dictGetEntryKey(de);
+ o = dictGetEntryVal(de);
+ thisval = estimateObjectIdleTime(o);
+
+ /* Higher idle time is better candidate for deletion */
+ if (bestkey == NULL || thisval > bestval) {
+ bestkey = thiskey;
+ bestval = thisval;
+ }
+ }
+ }
+
+ /* volatile-ttl */
+ else if (server.maxmemory_policy == REDIS_MAXMEMORY_VOLATILE_TTL) {
+ for (k = 0; k < server.maxmemory_samples; k++) {
+ sds thiskey;
+ long thisval;
+
+ de = dictGetRandomKey(dict);
+ thiskey = dictGetEntryKey(de);
+ thisval = (long) dictGetEntryVal(de);
+
+ /* Expire sooner (minor expire unix timestamp) is better
+ * candidate for deletion */
+ if (bestkey == NULL || thisval < bestval) {
+ bestkey = thiskey;
+ bestval = thisval;
+ }
+ }
+ }
+
+ /* Finally remove the selected key. */
+ if (bestkey) {
+ robj *keyobj = createStringObject(bestkey,sdslen(bestkey));
+ dbDelete(db,keyobj);
+ server.stat_expiredkeys++;
+ decrRefCount(keyobj);
+ freed++;
+ }
+ }
+ if (!freed) return; /* nothing to free... */
+ }
+
+ while(0) {
+ int j, k, freed = 0;