diff --git a/src/lib/eina/eina_hash.c b/src/lib/eina/eina_hash.c index b6465c7df8..92c37e1968 100644 --- a/src/lib/eina/eina_hash.c +++ b/src/lib/eina/eina_hash.c @@ -1407,6 +1407,39 @@ eina_hash_list_append(Eina_Hash *hash, const void *key, const void *data) eina_list_append(NULL, data)); } +EAPI void +eina_hash_list_direct_append(Eina_Hash *hash, const void *key, const void *data) +{ + Eina_Hash_Tuple tuple; + Eina_Hash_Head *hash_head; + Eina_Hash_Element *hash_element; + int key_length; + int key_hash; + + EINA_SAFETY_ON_NULL_RETURN(hash); + EINA_SAFETY_ON_NULL_RETURN(hash->key_hash_cb); + EINA_SAFETY_ON_NULL_RETURN(key); + EINA_SAFETY_ON_NULL_RETURN(data); + EINA_MAGIC_CHECK_HASH(hash); + + _eina_hash_compute(hash, key, &key_length, &key_hash); + + tuple.key = key; + tuple.key_length = key_length; + tuple.data = NULL; + + hash_element = _eina_hash_find_by_hash(hash, &tuple, key_hash, &hash_head); + if (hash_element) + hash_element->tuple.data = eina_list_append(hash_element->tuple.data, data); + else + eina_hash_add_alloc_by_hash(hash, + key, + key_length, + 0, + key_hash, + eina_list_append(NULL, data)); +} + EAPI void eina_hash_list_prepend(Eina_Hash *hash, const void *key, const void *data) { @@ -1440,6 +1473,39 @@ eina_hash_list_prepend(Eina_Hash *hash, const void *key, const void *data) eina_list_append(NULL, data)); } +EAPI void +eina_hash_list_direct_prepend(Eina_Hash *hash, const void *key, const void *data) +{ + Eina_Hash_Tuple tuple; + Eina_Hash_Head *hash_head; + Eina_Hash_Element *hash_element; + int key_length; + int key_hash; + + EINA_SAFETY_ON_NULL_RETURN(hash); + EINA_SAFETY_ON_NULL_RETURN(hash->key_hash_cb); + EINA_SAFETY_ON_NULL_RETURN(key); + EINA_SAFETY_ON_NULL_RETURN(data); + EINA_MAGIC_CHECK_HASH(hash); + + _eina_hash_compute(hash, key, &key_length, &key_hash); + + tuple.key = key; + tuple.key_length = key_length; + tuple.data = NULL; + + hash_element = _eina_hash_find_by_hash(hash, &tuple, key_hash, &hash_head); + if (hash_element) + hash_element->tuple.data = eina_list_prepend(hash_element->tuple.data, data); + else + eina_hash_add_alloc_by_hash(hash, + key, + key_length, + 0, + key_hash, + eina_list_append(NULL, data)); +} + EAPI void eina_hash_list_remove(Eina_Hash *hash, const void *key, const void *data) { diff --git a/src/lib/eina/eina_hash.h b/src/lib/eina/eina_hash.h index 16344cfed4..cda625b362 100644 --- a/src/lib/eina/eina_hash.h +++ b/src/lib/eina/eina_hash.h @@ -1035,6 +1035,21 @@ EAPI void eina_hash_foreach(const Eina_Hash *hash, */ EAPI void eina_hash_list_append(Eina_Hash *hash, const void *key, const void *data) EINA_ARG_NONNULL(1, 2, 3); +/** + * @brief Appends data to an #Eina_List inside a hash using eina_hash_direct_add(). + * + * This function is identical to the sequence of calling + * eina_hash_find(), eina_list_append(), eina_hash_set(), + * but with one fewer required hash lookup. + * + * @param[in,out] hash The hash table. + * @param[in] key The key associated with the data. + * @param[in] data The data to append to the list. + * + * @since 1.23 + */ +EAPI void eina_hash_list_direct_append(Eina_Hash *hash, const void *key, const void *data) EINA_ARG_NONNULL(1, 2, 3); + /** * @brief Prepends data to an #Eina_List inside a hash. * @@ -1050,6 +1065,21 @@ EAPI void eina_hash_list_append(Eina_Hash *hash, const void *key, const void *da */ EAPI void eina_hash_list_prepend(Eina_Hash *hash, const void *key, const void *data) EINA_ARG_NONNULL(1, 2, 3); +/** + * @brief Prepends data to an #Eina_List inside a hash using eina_hash_direct_add(). + * + * This function is identical to the sequence of calling + * eina_hash_find(), eina_list_prepend(), eina_hash_set(), + * but with one fewer required hash lookup. + * + * @param[in,out] hash The hash table. + * @param[in] key The key associated with the data. + * @param[in] data The data to prepend to the list. + * + * @since 1.23 + */ +EAPI void eina_hash_list_direct_prepend(Eina_Hash *hash, const void *key, const void *data) EINA_ARG_NONNULL(1, 2, 3); + /** * @brief Removes data from an #Eina_List inside a hash. *