+}
+
+void cacheScheduleForFlush(redisDb *db, robj *key) {
+ dirtykey *dk;
+ dictEntry *de;
+
+ de = dictFind(db->dict,key->ptr);
+ if (de) {
+ robj *val = dictGetEntryVal(de);
+ if (val->storage == REDIS_DS_DIRTY)
+ return;
+ else
+ val->storage = REDIS_DS_DIRTY;
+ }
+
+ redisLog(REDIS_DEBUG,"Scheduling key %s for saving",key->ptr);
+ dk = zmalloc(sizeof(*dk));
+ dk->db = db;
+ dk->key = key;
+ incrRefCount(key);
+ dk->ctime = time(NULL);
+ listAddNodeTail(server.cache_flush_queue, key);
+}
+
+void cacheCron(void) {
+ time_t now = time(NULL);
+ listNode *ln;
+
+ /* Sync stuff on disk */
+ while((ln = listFirst(server.cache_flush_queue)) != NULL) {
+ dirtykey *dk = ln->value;
+
+ if ((now - dk->ctime) >= server.cache_flush_delay) {
+ struct dictEntry *de;
+ robj *val;
+
+ redisLog(REDIS_DEBUG,"Creating IO Job to save key %s",dk->key->ptr);
+
+ /* Lookup the key. We need to check if it's still here and
+ * possibly access to the value. */
+ de = dictFind(dk->db->dict,dk->key->ptr);
+ if (de) {
+ val = dictGetEntryVal(de);
+ redisAssert(val->storage == REDIS_DS_DIRTY);
+ val->storage = REDIS_DS_SAVING;
+ } else {
+ /* Setting the value to NULL tells the IO thread to delete
+ * the key on disk. */
+ val = NULL;
+ }
+ dsCreateIOJob(REDIS_IOJOB_SAVE,dk->db,dk->key,val);
+ listDelNode(server.cache_flush_queue,ln);
+ } else {
+ break; /* too early */
+ }
+ }
+
+ /* Reclaim memory from the object cache */
+ while (server.ds_enabled && zmalloc_used_memory() >
+ server.cache_max_memory)
+ {
+ if (cacheFreeOneEntry() == REDIS_ERR) break;
+ }