From ad01a25553ed32b33efe036bb10450852f91478f Mon Sep 17 00:00:00 2001 From: antirez Date: Fri, 31 Dec 2010 00:18:17 +0100 Subject: [PATCH] blocking load of keys on lookup -- nor tested, nor finished --- src/db.c | 24 ++++++++++++++++++++---- src/dscache.c | 10 +++++++--- 2 files changed, 27 insertions(+), 7 deletions(-) diff --git a/src/db.c b/src/db.c index 1b0289bc..7ae23fa0 100644 --- a/src/db.c +++ b/src/db.c @@ -27,10 +27,26 @@ robj *lookupKey(redisDb *db, robj *key) { 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. + * + * 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. */ + if (server.ds_enabled && cacheKeyMayExist(db,key)) { + 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; } diff --git a/src/dscache.c b/src/dscache.c index 9fc0f5e5..03be8ffa 100644 --- a/src/dscache.c +++ b/src/dscache.c @@ -292,9 +292,13 @@ void vmThreadedIOCompletedJob(aeEventLoop *el, int fd, void *privdata, if (j->type == REDIS_IOJOB_LOAD) { /* Create the key-value pair in the in-memory database */ if (j->val != NULL) { - dbAdd(j->db,j->key,j->val); - incrRefCount(j->val); - if (j->expire != -1) setExpire(j->db,j->key,j->expire); + /* Note: the key may already be here if between the time + * this key loading was scheduled and now there was the + * need to blocking load the key for a key lookup. */ + if (dbAdd(j->db,j->key,j->val) == REDIS_OK) { + incrRefCount(j->val); + if (j->expire != -1) setExpire(j->db,j->key,j->expire); + } } else { /* The key does not exist. Create a negative cache entry * for this key. */ -- 2.47.2