Skip to content

Commit 5d73d7c

Browse files
author
michalbiesek
committed
Optimize dictFind call in db module: genericSetKey
In case of overwrite scenario there are 3 calls for dictFind *1st in genericSetKey -> lookupKeyWrite -> dictFind *2nd in dbOverwrite *3rd in removeExpire -> assertWithInfo This change limit dictfind function call to 1
1 parent 5fb70a6 commit 5d73d7c

File tree

1 file changed

+37
-3
lines changed

1 file changed

+37
-3
lines changed

src/db.c

Lines changed: 37 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -230,6 +230,12 @@ void dbOverwrite(redisDb *db, robj *key, robj *val) {
230230
dictFreeVal(db->dict, &auxentry);
231231
}
232232

233+
static int removeExpireOptim(redisDb *db, robj *key) {
234+
/* An expire may only be removed if there is a corresponding entry in the
235+
* main dict. Otherwise, the key will never be freed. */
236+
return dictDelete(db->expires,key->ptr) == DICT_OK;
237+
}
238+
233239
/* High level Set operation. This function can be used in order to set
234240
* a key, whatever it was existing or not, to a new object.
235241
*
@@ -242,13 +248,41 @@ void dbOverwrite(redisDb *db, robj *key, robj *val) {
242248
* The client 'c' argument may be set to NULL if the operation is performed
243249
* in a context where there is no clear client performing the operation. */
244250
void genericSetKey(client *c, redisDb *db, robj *key, robj *val, int keepttl, int signal) {
245-
if (lookupKeyWrite(db,key) == NULL) {
251+
expireIfNeeded(db,key);
252+
robj *old = NULL;
253+
dictEntry *de = dictFind(db->dict, key->ptr);
254+
if (de) {
255+
old= dictGetVal(de);
256+
257+
/* Update the access time for the ageing algorithm.
258+
* Don't do it if we have a saving child, as this will trigger
259+
* a copy on write madness. */
260+
if (!hasActiveChildProcess()) {
261+
if (server.maxmemory_policy & MAXMEMORY_FLAG_LFU) {
262+
updateLFU(val);
263+
} else {
264+
val->lru = LRU_CLOCK();
265+
}
266+
}
267+
}
268+
if (old == NULL) {
246269
dbAdd(db,key,val);
247270
} else {
248-
dbOverwrite(db,key,val);
271+
dictEntry auxentry = *de;
272+
if (server.maxmemory_policy & MAXMEMORY_FLAG_LFU) {
273+
val->lru = old->lru;
274+
}
275+
dictSetVal(db->dict, de, val);
276+
277+
if (server.lazyfree_lazy_server_del) {
278+
freeObjAsync(old);
279+
dictSetVal(db->dict, &auxentry, NULL);
280+
}
281+
282+
dictFreeVal(db->dict, &auxentry);
249283
}
250284
incrRefCount(val);
251-
if (!keepttl) removeExpire(db,key);
285+
if (!keepttl) removeExpireOptim(db,key);
252286
if (signal) signalModifiedKey(c,db,key);
253287
}
254288

0 commit comments

Comments
 (0)