]> git.saurik.com Git - redis.git/blobdiff - dict.c
use the right object when cleaning up after zunion/zinter (fixes issue 216)
[redis.git] / dict.c
diff --git a/dict.c b/dict.c
index 7f05e3f50ea28f902680d1bd9e6e76c4eb2a8e3f..23f7933bfa43ad1a08e3f7bc373e789c793dbbe3 100644 (file)
--- a/dict.c
+++ b/dict.c
@@ -5,7 +5,7 @@
  * tables of power of two in size are used, collisions are handled by
  * chaining. See the source code for more information... :)
  *
- * Copyright (c) 2006-2009, Salvatore Sanfilippo <antirez at gmail dot com>
+ * Copyright (c) 2006-2010, Salvatore Sanfilippo <antirez at gmail dot com>
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -226,21 +226,30 @@ int dictAdd(dict *ht, void *key, void *val)
     return DICT_OK;
 }
 
-/* Add an element, discarding the old if the key already exists */
+/* Add an element, discarding the old if the key already exists.
+ * Return 1 if the key was added from scratch, 0 if there was already an
+ * element with such key and dictReplace() just performed a value update
+ * operation. */
 int dictReplace(dict *ht, void *key, void *val)
 {
-    dictEntry *entry;
+    dictEntry *entry, auxentry;
 
     /* Try to add the element. If the key
      * does not exists dictAdd will suceed. */
     if (dictAdd(ht, key, val) == DICT_OK)
-        return DICT_OK;
+        return 1;
     /* It already exists, get the entry */
     entry = dictFind(ht, key);
     /* 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);
-    return DICT_OK;
+    dictFreeEntryVal(ht, &auxentry);
+    return 0;
 }
 
 /* Search and remove an element */