Fixed a bug in HSET, a memory leak, and a theoretical bug in dict.c

This commit is contained in:
antirez 2010-03-17 02:00:03 +01:00
parent b1d9c91ca8
commit 2069d06a0b
2 changed files with 9 additions and 3 deletions

10
dict.c
View File

@ -232,7 +232,7 @@ int dictAdd(dict *ht, void *key, void *val)
* operation. */ * operation. */
int dictReplace(dict *ht, void *key, void *val) int dictReplace(dict *ht, void *key, void *val)
{ {
dictEntry *entry; dictEntry *entry, auxentry;
/* Try to add the element. If the key /* Try to add the element. If the key
* does not exists dictAdd will suceed. */ * does not exists dictAdd will suceed. */
@ -241,8 +241,14 @@ int dictReplace(dict *ht, void *key, void *val)
/* It already exists, get the entry */ /* It already exists, get the entry */
entry = dictFind(ht, key); entry = dictFind(ht, key);
/* Free the old value and set the new one */ /* Free the old value and set the new one */
dictFreeEntryVal(ht, entry); /* Set the new value and free the old one. Note that it is important
* to do that in this order, as the value may just be exactly the same
* as the previous one. In this context, think to reference counting,
* you want to increment (set), and then decrement (free), and not the
* reverse. */
auxentry = *entry;
dictSetHashVal(ht, entry, val); dictSetHashVal(ht, entry, val);
dictFreeEntryVal(ht, &auxentry);
return 0; return 0;
} }

View File

@ -5849,7 +5849,7 @@ static void hsetCommand(redisClient *c) {
tryObjectEncoding(c->argv[2]); tryObjectEncoding(c->argv[2]);
/* note that c->argv[3] is already encoded, as the latest arg /* note that c->argv[3] is already encoded, as the latest arg
* of a bulk command is always integer encoded if possible. */ * of a bulk command is always integer encoded if possible. */
if (dictAdd(o->ptr,c->argv[2],c->argv[3]) == DICT_OK) { if (dictReplace(o->ptr,c->argv[2],c->argv[3])) {
incrRefCount(c->argv[2]); incrRefCount(c->argv[2]);
} else { } else {
update = 1; update = 1;