X-Git-Url: https://git.saurik.com/redis.git/blobdiff_plain/71aee3e959e205d3acc906c1c1cc91d7e4d87f14..8bca8773b4e2542f9537b8403764867aa76273a5:/dict.c diff --git a/dict.c b/dict.c index 7f05e3f5..23f7933b 100644 --- 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 + * Copyright (c) 2006-2010, Salvatore Sanfilippo * 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 */