summaryrefslogtreecommitdiff
path: root/src/lib/eina/eina_hash.c
diff options
context:
space:
mode:
authorMike Blumenkrantz <zmike@samsung.com>2014-04-08 19:16:44 -0400
committerMike Blumenkrantz <zmike@samsung.com>2014-04-25 10:52:15 -0400
commitb550d5becb68527e2ecf1d6eadac70a450b835e2 (patch)
treeebea03aba720766a37298337c1fc999373eee47a /src/lib/eina/eina_hash.c
parent83832d6b1dc64d336187d85e11fa337559288416 (diff)
downloadefl-b550d5becb68527e2ecf1d6eadac70a450b835e2.tar.gz
eina_hash now has helper functions for managing lists inside hashes
@feature
Diffstat (limited to 'src/lib/eina/eina_hash.c')
-rw-r--r--src/lib/eina/eina_hash.c97
1 files changed, 97 insertions, 0 deletions
diff --git a/src/lib/eina/eina_hash.c b/src/lib/eina/eina_hash.c
index 716a1d89d5..fe2ec51f23 100644
--- a/src/lib/eina/eina_hash.c
+++ b/src/lib/eina/eina_hash.c
@@ -37,6 +37,7 @@
/* undefs EINA_ARG_NONULL() so NULL checks are not compiled out! */
#include "eina_safety_checks.h"
#include "eina_hash.h"
+#include "eina_list.h"
/*============================================================================*
* Local *
@@ -1351,3 +1352,99 @@ eina_hash_superfast(const char *key, int len)
return hash;
}
+EAPI void
+eina_hash_list_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);
+
+ key_length = hash->key_length_cb ? hash->key_length_cb(key) : 0;
+ key_hash = hash->key_hash_cb(key, key_length);
+
+ 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,
+ key_length,
+ key_hash,
+ eina_list_append(NULL, data));
+}
+
+EAPI void
+eina_hash_list_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);
+
+ key_length = hash->key_length_cb ? hash->key_length_cb(key) : 0;
+ key_hash = hash->key_hash_cb(key, key_length);
+
+ 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,
+ key_length,
+ key_hash,
+ eina_list_append(NULL, data));
+}
+
+EAPI void
+eina_hash_list_remove(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);
+
+ key_length = hash->key_length_cb ? hash->key_length_cb(key) : 0;
+ key_hash = hash->key_hash_cb(key, key_length);
+
+ 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) return;
+ hash_element->tuple.data = eina_list_remove(hash_element->tuple.data, data);
+ if (!hash_element->tuple.data)
+ _eina_hash_del_by_hash_el(hash, hash_element, hash_head, key_hash);
+}