ht->key_destroy_func (hi.ths->key);
if (ht->value_destroy_func)
ht->value_destroy_func (hi.ths->val);
+ free (hi.ths);
}
if (ht->array)
*/
static hash_entry_t**
-find_entry (hash_t* ht, const void* key, void* val)
+find_entry (hash_t* ht, const void* key, int create)
{
hash_entry_t** hep;
hash_entry_t* he;
break;
}
- if(he || !val)
+ if(he || !create)
return hep;
/* add a new entry for non-NULL val */
he->key = (void*)key;
he->next = NULL;
he->hash = hash;
- he->val = val;
+ he->val = NULL;
*hep = he;
ht->count++;
void*
hash_get (hash_t* ht, const void *key)
{
- hash_entry_t** he = find_entry (ht, key, NULL);
+ hash_entry_t** he = find_entry (ht, key, 0);
if (he && *he)
return (void*)((*he)->val);
else
int
hash_set (hash_t* ht, void* key, void* val)
{
- hash_entry_t** hep = find_entry (ht, key, val);
+ hash_entry_t** hep = find_entry (ht, key, 1);
if(hep && *hep) {
+ if ((*hep)->val && ht->value_destroy_func)
+ ht->value_destroy_func ((*hep)->val);
+
/* replace entry */
(*hep)->val = val;
int
hash_remove (hash_t* ht, const void* key)
{
- hash_entry_t** hep = find_entry (ht, key, NULL);
+ hash_entry_t** hep = find_entry (ht, key, 0);
if (hep && *hep) {
hash_entry_t* old = *hep;
hash_intptr_hash (const void *to_int)
{
assert (to_int);
- return (unsigned int)*((unsigned long*)to_int);
+ return (unsigned int)*((int*)to_int);
}
int
{
assert (int_one);
assert (int_two);
- return *((unsigned long*)int_one) == *((unsigned long*)int_two);
+ return *((int*)int_one) == *((int*)int_two);
}
unsigned int
CuAssertIntEquals (tc, 0, value);
}
+static void
+test_hash_set_destroys (CuTest *tc)
+{
+ hash_t *ht;
+ int key = 0;
+ int value = 0;
+ int value2 = 0;
+ int ret;
+
+ ht = hash_create (hash_direct_hash, hash_direct_equal, destroy_key, destroy_value);
+ CuAssertPtrNotNull (tc, ht);
+ if (!hash_set (ht, &key, &value))
+ CuFail (tc, "should not be reached");
+
+ ret = hash_set (ht, &key, &value2);
+ CuAssertIntEquals (tc, ret, 1);
+ CuAssertIntEquals (tc, 0, key);
+ CuAssertIntEquals (tc, 2, value);
+ CuAssertIntEquals (tc, 0, value2);
+
+ key = 0;
+ value = 0;
+ value2 = 0;
+
+ hash_free (ht);
+
+ CuAssertIntEquals (tc, 1, key);
+ CuAssertIntEquals (tc, 0, value);
+ CuAssertIntEquals (tc, 2, value2);
+}
+
+
static void
test_hash_clear_destroys (CuTest *tc)
{
test_hash_intptr_with_collisions (const void *data)
{
/* lots and lots of collisions, only returns 100 values */
- return (unsigned int)(*((unsigned long*)data) % 100);
+ return (unsigned int)(*((int*)data) % 100);
}
static void
ht = hash_create (hash_ulongptr_hash, hash_ulongptr_equal, NULL, free);
for (i = 0; i < 20000; ++i) {
- value = malloc (sizeof (int));
+ value = malloc (sizeof (unsigned long));
*value = i;
if (!hash_set (ht, value, value))
CuFail (tc, "should not be reached");
SUITE_ADD_TEST (suite, test_hash_set_get_remove);
SUITE_ADD_TEST (suite, test_hash_remove_destroys);
SUITE_ADD_TEST (suite, test_hash_set_get_clear);
+ SUITE_ADD_TEST (suite, test_hash_set_destroys);
SUITE_ADD_TEST (suite, test_hash_clear_destroys);
SUITE_ADD_TEST (suite, test_hash_free_null);
SUITE_ADD_TEST (suite, test_hash_free_destroys);
printf ("%s\n", output->buffer);
ret = suite->failCount;
CuSuiteDelete (suite);
+ CuStringDelete (output);
+
return ret;
}