refactor dbOverwrite to make lazyfree work

This commit is contained in:
zhaozhao.zz 2018-07-31 12:07:57 +08:00
parent fd174cca23
commit fddeeae724
4 changed files with 27 additions and 12 deletions

View File

@ -184,14 +184,19 @@ void dbOverwrite(redisDb *db, robj *key, robj *val) {
dictEntry *de = dictFind(db->dict,key->ptr); dictEntry *de = dictFind(db->dict,key->ptr);
serverAssertWithInfo(NULL,key,de != NULL); serverAssertWithInfo(NULL,key,de != NULL);
dictEntry auxentry = *de;
robj *old = dictGetVal(de);
if (server.maxmemory_policy & MAXMEMORY_FLAG_LFU) { if (server.maxmemory_policy & MAXMEMORY_FLAG_LFU) {
robj *old = dictGetVal(de); val->lru = old->lru;
int saved_lru = old->lru;
dictReplace(db->dict, key->ptr, val);
val->lru = saved_lru;
} else {
dictReplace(db->dict, key->ptr, val);
} }
dictSetVal(db->dict, de, val);
if (server.lazyfree_lazy_server_del) {
freeObjAsync(old);
dictSetVal(db->dict, &auxentry, NULL);
}
dictFreeVal(db->dict, &auxentry);
} }
/* High level Set operation. This function can be used in order to set /* High level Set operation. This function can be used in order to set

View File

@ -90,6 +90,17 @@ int dbAsyncDelete(redisDb *db, robj *key) {
} }
} }
/* Free an object, if the object is huge enough, free it in async way. */
void freeObjAsync(robj *o) {
size_t free_effort = lazyfreeGetFreeEffort(o);
if (free_effort > LAZYFREE_THRESHOLD && o->refcount == 1) {
atomicIncr(lazyfree_objects,1);
bioCreateBackgroundJob(BIO_LAZY_FREE,o,NULL,NULL);
} else {
decrRefCount(o);
}
}
/* Empty a Redis DB asynchronously. What the function does actually is to /* Empty a Redis DB asynchronously. What the function does actually is to
* create a new empty set of hash tables and scheduling the old ones for * create a new empty set of hash tables and scheduling the old ones for
* lazy freeing. */ * lazy freeing. */

View File

@ -1824,6 +1824,7 @@ int dbAsyncDelete(redisDb *db, robj *key);
void emptyDbAsync(redisDb *db); void emptyDbAsync(redisDb *db);
void slotToKeyFlushAsync(void); void slotToKeyFlushAsync(void);
size_t lazyfreeGetPendingObjectsCount(void); size_t lazyfreeGetPendingObjectsCount(void);
void freeObjAsync(robj *o);
/* API to get key arguments from commands */ /* API to get key arguments from commands */
int *getKeysFromCommand(struct redisCommand *cmd, robj **argv, int argc, int *numkeys); int *getKeysFromCommand(struct redisCommand *cmd, robj **argv, int argc, int *numkeys);

View File

@ -516,11 +516,7 @@ void spopWithCountCommand(client *c) {
sdsfree(sdsele); sdsfree(sdsele);
} }
/* Assign the new set as the key value. */ /* Tranfer the old set to the client. */
incrRefCount(set); /* Protect the old set value. */
dbOverwrite(c->db,c->argv[1],newset);
/* Tranfer the old set to the client and release it. */
setTypeIterator *si; setTypeIterator *si;
si = setTypeInitIterator(set); si = setTypeInitIterator(set);
while((encoding = setTypeNext(si,&sdsele,&llele)) != -1) { while((encoding = setTypeNext(si,&sdsele,&llele)) != -1) {
@ -539,7 +535,9 @@ void spopWithCountCommand(client *c) {
decrRefCount(objele); decrRefCount(objele);
} }
setTypeReleaseIterator(si); setTypeReleaseIterator(si);
decrRefCount(set);
/* Assign the new set as the key value. */
dbOverwrite(c->db,c->argv[1],newset);
} }
/* Don't propagate the command itself even if we incremented the /* Don't propagate the command itself even if we incremented the