/* Key not found in the in memory hash table, but if disk store is
* enabled we may have this key on disk. If so load it in memory
- * in a blocking way.
- *
- * FIXME: race condition here. If there was an already scheduled
- * async loading of this key, what may happen is that the old
- * key is loaded in memory if this gets deleted in the meantime. */
+ * in a blocking way. */
if (server.ds_enabled && cacheKeyMayExist(db,key)) {
+ if (cacheScheduleIOGetFlags(db,key) & REDIS_IO_SAVEINPROG) {
+ /* There is a save in progress for this object!
+ * Wait for it to get out. */
+ waitEmptyIOJobsQueue();
+ processAllPendingIOJobs();
+ redisAssert((cacheScheduleIOGetFlags(db,key) & REDIS_IO_SAVEINPROG) == 0);
+ }
+
redisLog(REDIS_DEBUG,"Force loading key %s via lookup",
key->ptr);
val = dsGet(db,key,&expire);
} else {
sds copy = sdsdup(key->ptr);
dictAdd(db->dict, copy, val);
- if (server.ds_enabled) {
- /* FIXME: remove entry from negative cache */
- }
+ if (server.ds_enabled) cacheSetKeyMayExist(db,key);
return REDIS_OK;
}
}
* On update (key already existed) 0 is returned. Otherwise 1. */
int dbReplace(redisDb *db, robj *key, robj *val) {
robj *oldval;
+ int retval;
if ((oldval = dictFetchValue(db->dict,key->ptr)) == NULL) {
sds copy = sdsdup(key->ptr);
dictAdd(db->dict, copy, val);
- return 1;
+ retval = 1;
} else {
dictReplace(db->dict, key->ptr, val);
- return 0;
+ retval = 0;
}
+ if (server.ds_enabled) cacheSetKeyMayExist(db,key);
+ return retval;
}
int dbExists(redisDb *db, robj *key) {
/* If diskstore is enabled make sure to awake waiting clients for this key
* as it is not really useful to wait for a key already deleted to be
* loaded from disk. */
- if (server.ds_enabled) handleClientsBlockedOnSwappedKey(db,key);
-
- /* FIXME: we should mark this key as non existing on disk in the negative
- * cache. */
+ if (server.ds_enabled) {
+ handleClientsBlockedOnSwappedKey(db,key);
+ cacheSetKeyDoesNotExist(db,key);
+ }
/* Deleting an entry from the expires dict will not free the sds of
* the key, because it is shared with the main dictionary. */
void signalFlushedDb(int dbid) {
touchWatchedKeysOnFlush(dbid);
- if (server.ds_enabled)
- dsFlushDb(dbid);
}
/*-----------------------------------------------------------------------------
signalFlushedDb(c->db->id);
dictEmpty(c->db->dict);
dictEmpty(c->db->expires);
+ if (server.ds_enabled) dsFlushDb(c->db->id);
addReply(c,shared.ok);
}
kill(server.bgsavechildpid,SIGKILL);
rdbRemoveTempFile(server.bgsavechildpid);
}
- rdbSave(server.dbfilename);
+ if (server.ds_enabled)
+ dsFlushDb(-1);
+ else
+ rdbSave(server.dbfilename);
server.dirty++;
}