summaryrefslogtreecommitdiffstats
path: root/src/hashtable.c
diff options
context:
space:
mode:
authorGravatar Nikias Bassen2016-11-18 03:22:25 +0100
committerGravatar Nikias Bassen2016-11-18 03:22:25 +0100
commit582c59bf7dcf37270c2fd7e99b4982ebc9bcbc74 (patch)
tree91b8c594acd89e4c53a8c00bd730446bbfc0c6cf /src/hashtable.c
parentf1f2bcebc8690c9b420288aeede2e52c5bf18ccd (diff)
downloadlibplist-582c59bf7dcf37270c2fd7e99b4982ebc9bcbc74.tar.gz
libplist-582c59bf7dcf37270c2fd7e99b4982ebc9bcbc74.tar.bz2
Improve plist_dict_set_item performance for large dictionaries with hash table
Diffstat (limited to 'src/hashtable.c')
-rw-r--r--src/hashtable.c40
1 files changed, 37 insertions, 3 deletions
diff --git a/src/hashtable.c b/src/hashtable.c
index 3568f3c..dd6dbfc 100644
--- a/src/hashtable.c
+++ b/src/hashtable.c
@@ -2,7 +2,7 @@
2 * hashtable.c 2 * hashtable.c
3 * really simple hash table implementation 3 * really simple hash table implementation
4 * 4 *
5 * Copyright (c) 2011 Nikias Bassen, All Rights Reserved. 5 * Copyright (c) 2011-2016 Nikias Bassen, All Rights Reserved.
6 * 6 *
7 * This library is free software; you can redistribute it and/or 7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public 8 * modify it under the terms of the GNU Lesser General Public
@@ -20,7 +20,7 @@
20 */ 20 */
21#include "hashtable.h" 21#include "hashtable.h"
22 22
23hashtable_t* hash_table_new(hash_func_t hash_func, compare_func_t compare_func) 23hashtable_t* hash_table_new(hash_func_t hash_func, compare_func_t compare_func, free_func_t free_func)
24{ 24{
25 hashtable_t* ht = (hashtable_t*)malloc(sizeof(hashtable_t)); 25 hashtable_t* ht = (hashtable_t*)malloc(sizeof(hashtable_t));
26 int i; 26 int i;
@@ -30,6 +30,7 @@ hashtable_t* hash_table_new(hash_func_t hash_func, compare_func_t compare_func)
30 ht->count = 0; 30 ht->count = 0;
31 ht->hash_func = hash_func; 31 ht->hash_func = hash_func;
32 ht->compare_func = compare_func; 32 ht->compare_func = compare_func;
33 ht->free_func = free_func;
33 return ht; 34 return ht;
34} 35}
35 36
@@ -42,7 +43,9 @@ void hash_table_destroy(hashtable_t *ht)
42 if (ht->entries[i]) { 43 if (ht->entries[i]) {
43 hashentry_t* e = ht->entries[i]; 44 hashentry_t* e = ht->entries[i];
44 while (e) { 45 while (e) {
45 free(e->value); 46 if (ht->free_func) {
47 ht->free_func(e->value);
48 }
46 hashentry_t* old = e; 49 hashentry_t* old = e;
47 e = e->next; 50 e = e->next;
48 free(old); 51 free(old);
@@ -104,3 +107,34 @@ void* hash_table_lookup(hashtable_t* ht, void *key)
104 } 107 }
105 return NULL; 108 return NULL;
106} 109}
110
111void hash_table_remove(hashtable_t* ht, void *key)
112{
113 if (!ht || !key) return;
114
115 unsigned int hash = ht->hash_func(key);
116
117 int idx0 = hash & 0xFFF;
118
119 // get the idx0 list
120 hashentry_t* e = ht->entries[idx0];
121 hashentry_t* last = e;
122 while (e) {
123 if (ht->compare_func(e->key, key)) {
124 // found element, remove it from the list
125 hashentry_t* old = e;
126 if (e == ht->entries[idx0]) {
127 ht->entries[idx0] = e->next;
128 } else {
129 last->next = e->next;
130 }
131 if (ht->free_func) {
132 ht->free_func(old->value);
133 }
134 free(old);
135 return;
136 }
137 last = e;
138 e = e->next;
139 }
140}