#endif
static inline int
-_eina_hash_rbtree_key(const Eina_Hash_El *el, const char *key, int key_length, Eina_Key_Cmp cmp)
+_eina_hash_rbtree_key(const Eina_Hash_El *el, const Eina_Hash_Tuple *tuple, __UNUSED__ int key_length, Eina_Key_Cmp cmp)
{
- return cmp(el->tuple.key, el->tuple.key_length, key, key_length);
+ int result;
+
+ result = cmp(el->tuple.key, el->tuple.key_length, tuple->key, tuple->key_length);
+ if (result == 0)
+ if (tuple->data && el->tuple.data != tuple->data)
+ return 1;
+ return result;
}
static Eina_Rbtree_Direction
}
static inline Eina_Hash_El *
-_eina_hash_find_by_hash(const Eina_Hash *hash, const char *key, int key_length, int key_hash)
+_eina_hash_find_by_hash(const Eina_Hash *hash, Eina_Hash_Tuple *tuple, int key_hash)
{
Eina_Hash_El *el;
key_hash &= 0xFF;
- el = (Eina_Hash_El*) eina_rbtree_inline_lookup(hash->buckets[key_hash], key, key_length, EINA_RBTREE_CMP_KEY_CB(_eina_hash_rbtree_key), hash->key_cmp_cb);
+ el = (Eina_Hash_El*) eina_rbtree_inline_lookup(hash->buckets[key_hash], tuple, sizeof (Eina_Hash_Tuple), EINA_RBTREE_CMP_KEY_CB(_eina_hash_rbtree_key), hash->key_cmp_cb);
return el;
}
eina_hash_del_by_hash(Eina_Hash *hash, const void *key, int key_length, int key_hash, const void *data)
{
Eina_Hash_El *el = NULL;
+ Eina_Hash_Tuple tuple;
+
+ tuple.key = (void *) key;
+ tuple.key_length = key_length;
+ tuple.data = (void *) data;
if (!hash) return EINA_FALSE;
if (!key) el = _eina_hash_find_by_data(hash, data, &key_hash);
- else el = _eina_hash_find_by_hash(hash, key, key_length, key_hash);
+ else el = _eina_hash_find_by_hash(hash, &tuple, key_hash);
if (!el) return EINA_FALSE;
+ if (data && el->tuple.data != data) return EINA_FALSE;
key_hash &= 0xFF;
eina_hash_find_by_hash(const Eina_Hash *hash, const void *key, int key_length, int key_hash)
{
Eina_Hash_El *el;
+ Eina_Hash_Tuple tuple;
if ((!hash) || (!key)) return NULL;
- el = _eina_hash_find_by_hash(hash, key, key_length, key_hash);
+ tuple.key = key;
+ tuple.key_length = key_length;
+ tuple.data = NULL;
+
+ el = _eina_hash_find_by_hash(hash, &tuple, key_hash);
if (el) return el->tuple.data;
return NULL;
}
{
Eina_Hash_El *el;
void *old_data = NULL;
+ Eina_Hash_Tuple tuple;
if (!hash) return NULL;
- el = _eina_hash_find_by_hash(hash, key, key_length, key_hash);
+ tuple.key = key;
+ tuple.key_length = key_length;
+ tuple.data = NULL;
+
+ el = _eina_hash_find_by_hash(hash, &tuple, key_hash);
if (el)
{
old_data = el->tuple.data;
}
END_TEST
+START_TEST(eina_hash_double_item)
+{
+ Eina_Hash *hash = NULL;
+ int i[] = { 7, 7 };
+ int *test;
+
+ fail_if(eina_hash_init() <= 0);
+
+ hash = eina_hash_string_superfast_new();
+ fail_if(hash == NULL);
+
+ fail_if(eina_hash_add(hash, "7", &i[0]) != EINA_TRUE);
+ fail_if(eina_hash_add(hash, "7", &i[1]) != EINA_TRUE);
+
+ fail_if(eina_hash_del(hash, "7", &i[1]) != EINA_TRUE);
+ test = eina_hash_find(hash, "7");
+ fail_if(test != &i[0]);
+
+ eina_hash_free(hash);
+
+ fail_if(eina_hash_shutdown() > 0);
+}
+END_TEST
+
void eina_test_hash(TCase *tc)
{
tcase_add_test(tc, eina_hash_init_shutdown);
tcase_add_test(tc, eina_hash_simple);
tcase_add_test(tc, eina_hash_extended);
+ tcase_add_test(tc, eina_hash_double_item);
}