summaryrefslogtreecommitdiffstats
path: root/src/hashtable.c
diff options
context:
space:
mode:
authorGravatar Nikias Bassen2011-05-27 14:55:31 +0200
committerGravatar Nikias Bassen2011-05-27 14:55:31 +0200
commit024e755d9f3c33e742ce158542b1ded057a88f4f (patch)
tree7f80705e0c3dd35fd86fcd943dbf0d0c6b9b78ab /src/hashtable.c
parent94cb55d34dd9cb9bda539999dc017af76ec64a4f (diff)
downloadlibplist-024e755d9f3c33e742ce158542b1ded057a88f4f.tar.gz
libplist-024e755d9f3c33e742ce158542b1ded057a88f4f.tar.bz2
Make libplist glib free
Diffstat (limited to 'src/hashtable.c')
-rw-r--r--src/hashtable.c107
1 files changed, 107 insertions, 0 deletions
diff --git a/src/hashtable.c b/src/hashtable.c
new file mode 100644
index 0000000..9716c25
--- /dev/null
+++ b/src/hashtable.c
@@ -0,0 +1,107 @@
+/*
+ * hashtable.c
+ * really simple hash table implementation
+ *
+ * Copyright (c) 2011 Nikias Bassen, All Rights Reserved.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+#include "hashtable.h"
+
+hashtable_t* hash_table_new(hash_func_t hash_func, compare_func_t compare_func)
+{
+ hashtable_t* ht = (hashtable_t*)malloc(sizeof(hashtable_t));
+ int i;
+ for (i = 0; i < 256; i++) {
+ ht->entries[i] = NULL;
+ }
+ ht->count = 0;
+ ht->hash_func = hash_func;
+ ht->compare_func = compare_func;
+ return ht;
+}
+
+void hash_table_destroy(hashtable_t *ht)
+{
+ if (!ht) return;
+
+ int i = 0;
+ for (i = 0; i < 256; i++) {
+ if (ht->entries[i]) {
+ hashentry_t* e = ht->entries[i];
+ while (e) {
+ free(e->value);
+ hashentry_t* old = e;
+ e = e->next;
+ free(old);
+ }
+ }
+ }
+ free(ht);
+}
+
+void hash_table_insert(hashtable_t* ht, void *key, void *value)
+{
+ if (!ht || !key) return;
+ int i;
+
+ unsigned int hash = ht->hash_func(key);
+
+ int idx0 = hash & 0xFF;
+
+ // get the idx0 list
+ hashentry_t* e = ht->entries[idx0];
+ while (e) {
+ if (ht->compare_func(e->key, key)) {
+ // element already present. replace value.
+ e->value = value;
+ return;
+ }
+ e = e->next;
+ }
+
+ // if we get here, the element is not yet in the list.
+
+ // make a new entry.
+ hashentry_t* entry = (hashentry_t*)malloc(sizeof(hashentry_t));
+ entry->key = key;
+ entry->value = value;
+ if (!ht->entries[idx0]) {
+ // first entry
+ entry->next = NULL;
+ } else {
+ // add to list
+ entry->next = ht->entries[idx0];
+ }
+ ht->entries[idx0] = entry;
+ ht->count++;
+}
+
+void* hash_table_lookup(hashtable_t* ht, void *key)
+{
+ if (!ht || !key) return NULL;
+ unsigned int hash = ht->hash_func(key);
+
+ int idx0 = hash & 0xFF;
+
+ hashentry_t* e = ht->entries[idx0];
+ while (e) {
+ if (ht->compare_func(e->key, key)) {
+ return e->value;
+ }
+ e = e->next;
+ }
+ return NULL;
+}