if (server.bgsavechildpid == -1 && server.bgrewritechildpid == -1)
val->lru = server.lruclock;
- if (server.ds_enabled && val->storage == REDIS_DS_SAVING) {
- /* FIXME: change this code to just wait for our object to
- * get out of the IO Job. */
+ if (server.ds_enabled &&
+ cacheScheduleIOGetFlags(db,key) & REDIS_IO_SAVEINPROG)
+ {
+ /* There is a save in progress for this object!
+ * Wait for it to get out. */
waitEmptyIOJobsQueue();
processAllPendingIOJobs();
- redisAssert(val->storage != REDIS_DS_SAVING);
+ redisAssert(!(cacheScheduleIOGetFlags(db,key) & REDIS_IO_SAVEINPROG));
}
server.stat_keyspace_hits++;
return val;
} else {
- /* FIXME: Check if the object is on disk, if it is, load it
- * in a blocking way now. If we are sure there are no collisions
- * it would be cool to load this directly here without IO thread
- * help. */
+ time_t expire;
+ robj *val;
+
+ /* 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. */
+ 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);
+ if (val) {
+ int retval = dbAdd(db,key,val);
+ redisAssert(retval == REDIS_OK);
+ if (expire != -1) setExpire(db,key,expire);
+ server.stat_keyspace_hits++;
+ return val;
+ }
+ }
server.stat_keyspace_misses++;
return NULL;
}
} 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) {
- if (dictFind(db->dict,key->ptr) == NULL) {
+ 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) {
/* Delete a key, value, and associated expiration entry if any, from the DB */
int dbDelete(redisDb *db, robj *key) {
- /* If VM is enabled make sure to awake waiting clients for this key:
- * deleting the key will kill the I/O thread bringing the key from swap
- * to memory, so the client will never be notified and unblocked if we
- * don't do it now. */
- if (server.ds_enabled) handleClientsBlockedOnSwappedKey(db,key);
-
- /* FIXME: we need to delete the IO Job loading the key, or simply we can
- * wait for it to finish. */
+ /* 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);
+ 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 signalModifiedKey(redisDb *db, robj *key) {
touchWatchedKey(db,key);
if (server.ds_enabled)
- cacheScheduleForFlush(db,key);
+ cacheScheduleIO(db,key,REDIS_IO_SAVE);
}
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++;
}
if (cacheKeyMayExist(c->db,c->argv[j]) &&
dsExists(c->db,c->argv[j]))
{
- cacheScheduleForFlush(c->db,c->argv[j]);
+ cacheScheduleIO(c->db,c->argv[j],REDIS_IO_SAVE);
deleted = 1;
}
}