int hashtable_unset(struct hashtable *ht, const void *key, size_t keylen) { int i; struct hashtableitem *item; i = hashtable_get_item(ht, key, keylen, &item); if (i != HASHTABLE_SUCCESS) { return i; } return hashtable_unset_item(ht, item); }
TEST(Hashtable, SetGetRemove) { struct t_hashtable *hashtable, *hashtable2; struct t_hashtable_item *item, *ptr_item, *ptr_item2; const char *str_key = HASHTABLE_TEST_KEY; const char *str_value = HASHTABLE_TEST_VALUE; const char *ptr_value; unsigned long long hash; int i; hashtable = hashtable_new (32, WEECHAT_HASHTABLE_STRING, WEECHAT_HASHTABLE_STRING, &test_hashtable_hash_key_cb, &test_hashtable_keycmp_cb); LONGS_EQUAL(32, hashtable->size); LONGS_EQUAL(0, hashtable->items_count); /* invalid set of items */ POINTERS_EQUAL(NULL, hashtable_set_with_size (NULL, NULL, -1, NULL, -1)); POINTERS_EQUAL(NULL, hashtable_set_with_size (NULL, NULL, -1, NULL, -1)); /* add an item in hashtable with NULL value */ item = hashtable_set (hashtable, str_key, NULL); CHECK(item); LONGS_EQUAL(1, hashtable->items_count); STRCMP_EQUAL(str_key, (const char *)item->key); LONGS_EQUAL(strlen (str_key) + 1, item->key_size); POINTERS_EQUAL(NULL, item->value); LONGS_EQUAL(0, item->value_size); POINTERS_EQUAL(NULL, item->prev_item); POINTERS_EQUAL(NULL, item->next_item); /* set a string value for the same key */ item = hashtable_set (hashtable, str_key, str_value); CHECK(item); LONGS_EQUAL(1, hashtable->items_count); STRCMP_EQUAL(str_key, (const char *)item->key); LONGS_EQUAL(strlen (str_key) + 1, item->key_size); STRCMP_EQUAL(str_value, (const char *)item->value); LONGS_EQUAL(strlen (str_value) + 1, item->value_size); POINTERS_EQUAL(NULL, item->prev_item); POINTERS_EQUAL(NULL, item->next_item); /* get item */ item = hashtable_get_item (hashtable, str_key, &hash); CHECK(item); STRCMP_EQUAL(str_key, (const char *)item->key); STRCMP_EQUAL(str_value, (const char *)item->value); LONGS_EQUAL(2, hash); /* get value */ ptr_value = (const char *)hashtable_get (hashtable, str_key); CHECK(ptr_value); STRCMP_EQUAL(ptr_value, str_value); /* check if key is in hashtable */ LONGS_EQUAL(0, hashtable_has_key (hashtable, NULL)); LONGS_EQUAL(0, hashtable_has_key (hashtable, "")); LONGS_EQUAL(0, hashtable_has_key (hashtable, "xxx")); LONGS_EQUAL(1, hashtable_has_key (hashtable, str_key)); /* delete an item */ hashtable_remove (hashtable, str_key); LONGS_EQUAL(0, hashtable->items_count); /* add an item with size in hashtable */ item = hashtable_set_with_size (hashtable, str_key, strlen (str_key) + 1, str_value, strlen (str_value) + 1); CHECK(item); LONGS_EQUAL(1, hashtable->items_count); STRCMP_EQUAL(str_key, (const char *)item->key); LONGS_EQUAL(strlen (str_key) + 1, item->key_size); STRCMP_EQUAL(str_value, (const char *)item->value); LONGS_EQUAL(strlen (str_value) + 1, item->value_size); /* add another item */ hashtable_set (hashtable, "xxx", "zzz"); LONGS_EQUAL(2, hashtable->items_count); /* * test duplication of hashtable and check that duplicated content is * exactly the same as initial hashtable */ hashtable2 = hashtable_dup (hashtable); CHECK(hashtable2); LONGS_EQUAL(hashtable->size, hashtable2->size); LONGS_EQUAL(hashtable->items_count, hashtable2->items_count); for (i = 0; i < hashtable->size; i++) { if (hashtable->htable[i]) { ptr_item = hashtable->htable[i]; ptr_item2 = hashtable2->htable[i]; while (ptr_item && ptr_item2) { LONGS_EQUAL(ptr_item->key_size, ptr_item2->key_size); LONGS_EQUAL(ptr_item->value_size, ptr_item2->value_size); if (ptr_item->key) { STRCMP_EQUAL((const char *)ptr_item->key, (const char *)ptr_item2->key); } else { POINTERS_EQUAL(ptr_item->key, ptr_item2->key); } if (ptr_item->value) { STRCMP_EQUAL((const char *)ptr_item->value, (const char *)ptr_item2->value); } else { POINTERS_EQUAL(ptr_item->value, ptr_item2->value); } ptr_item = ptr_item->next_item; ptr_item2 = ptr_item2->next_item; CHECK((ptr_item && ptr_item2) || (!ptr_item && !ptr_item2)); } } else { POINTERS_EQUAL(hashtable->htable[i], hashtable2->htable[i]); } } /* remove all items */ hashtable_remove_all (hashtable); LONGS_EQUAL(0, hashtable->items_count); /* free hashtables */ hashtable_free (hashtable); hashtable_free (hashtable2); /* * create a hashtable with size 8, and add 6 items, * to check if many items with same hashed key work fine, * the expected htable inside hashtable is: * +-----+ * | 0 | * +-----+ * | 1 | * +-----+ * | 2 | --> "extensible" * +-----+ * | 3 | --> "fast" --> "light" * +-----+ * | 4 | * +-----+ * | 5 | --> "chat" * +-----+ * | 6 | --> "client" * +-----+ * | 7 | --> "weechat" * +-----+ */ hashtable = hashtable_new (8, WEECHAT_HASHTABLE_STRING, WEECHAT_HASHTABLE_STRING, NULL, NULL); LONGS_EQUAL(8, hashtable->size); LONGS_EQUAL(0, hashtable->items_count); item = hashtable_set (hashtable, "weechat", NULL); CHECK(item); POINTERS_EQUAL(item, hashtable->htable[7]); item = hashtable_set (hashtable, "fast", NULL); CHECK(item); POINTERS_EQUAL(item, hashtable->htable[3]); item = hashtable_set (hashtable, "light", NULL); CHECK(item); POINTERS_EQUAL(item, hashtable->htable[3]->next_item); item = hashtable_set (hashtable, "extensible", NULL); CHECK(item); POINTERS_EQUAL(item, hashtable->htable[2]); item = hashtable_set (hashtable, "chat", NULL); CHECK(item); POINTERS_EQUAL(item, hashtable->htable[5]); item = hashtable_set (hashtable, "client", NULL); CHECK(item); POINTERS_EQUAL(item, hashtable->htable[6]); /* free hashtable */ hashtable_free (hashtable); }