summaryrefslogtreecommitdiffabout
path: root/libetpan/src/data-types/cinthash.c
Unidiff
Diffstat (limited to 'libetpan/src/data-types/cinthash.c') (more/less context) (ignore whitespace changes)
-rw-r--r--libetpan/src/data-types/cinthash.c248
1 files changed, 248 insertions, 0 deletions
diff --git a/libetpan/src/data-types/cinthash.c b/libetpan/src/data-types/cinthash.c
new file mode 100644
index 0000000..b59eb86
--- a/dev/null
+++ b/libetpan/src/data-types/cinthash.c
@@ -0,0 +1,248 @@
1/*
2 * libEtPan! -- a mail stuff library
3 *
4 * Copyright (C) 2001, 2005 - DINH Viet Hoa
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. Neither the name of the libEtPan! project nor the names of its
16 * contributors may be used to endorse or promote products derived
17 * from this software without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * SUCH DAMAGE.
30 */
31
32/*
33 * $Id$
34 */
35
36#include <stdlib.h>
37#include "cinthash.h"
38
39struct cinthash_list {
40 unsigned long hash;
41 void * data;
42 struct cinthash_list * next;
43};
44
45static struct cinthash_list HASH_LISTHEAD_NEW = { 0, NULL, NULL };
46
47static inline int hash_list_add(cinthash_t * table,
48 unsigned long hash, void * data)
49{
50 struct cinthash_list * ht;
51 int index;
52
53 index = hash % table->hashtable_size;
54
55 ht = malloc(sizeof(struct cinthash_list));
56 if (ht == NULL)
57 return -1;
58
59 ht->hash = hash;
60 ht->data = data;
61 ht->next = table->table[index].next;
62
63 table->table[index].next = ht;
64
65 return 0;
66}
67
68static inline void hash_list_free(struct cinthash_list * list)
69{
70 struct cinthash_list * cur;
71 struct cinthash_list * next;
72
73 next = list;
74 while (next != NULL) {
75 cur = next;
76 next = cur->next;
77 free(cur);
78 }
79}
80
81static inline int hash_list_remove(cinthash_t * table, unsigned long hash)
82{
83 struct cinthash_list * cur;
84 int index;
85
86 index = hash % table->hashtable_size;
87
88 for(cur = &table->table[index] ; cur->next != NULL ; cur = cur->next) {
89 if (cur->next->hash == hash) {
90 struct cinthash_list * hash_data;
91
92 hash_data = cur->next;
93 cur->next = cur->next->next;
94
95 free(hash_data);
96
97 return 0;
98 }
99 }
100
101 return -1;
102}
103
104static inline void * hash_list_find(cinthash_t * table, unsigned long hash)
105{
106 struct cinthash_list * cur;
107 int index;
108
109 index = hash % table->hashtable_size;
110
111 for(cur = table->table[index].next ; cur != NULL ; cur = cur->next) {
112 if (cur->hash == hash)
113 return cur->data;
114 }
115
116 return NULL;
117}
118
119cinthash_t * cinthash_new(unsigned long hashtable_size)
120{
121 cinthash_t * ht;
122 unsigned long i;
123
124 ht = malloc(sizeof(cinthash_t));
125 if (ht == NULL)
126 return NULL;
127
128 ht->table = malloc(sizeof(struct cinthash_list) * hashtable_size);
129 if (ht->table == NULL)
130 return NULL;
131
132 ht->hashtable_size = hashtable_size;
133 ht->count = 0;
134
135 for(i = 0 ; i < hashtable_size ; i++)
136 ht->table[i] = HASH_LISTHEAD_NEW;
137
138 return ht;
139}
140
141void cinthash_free(cinthash_t * table)
142{
143 unsigned long i;
144
145 for(i = 0 ; i < table->hashtable_size ; i++)
146 hash_list_free(table->table[i].next);
147
148 free(table->table);
149
150 free(table);
151}
152
153int cinthash_add(cinthash_t * table, unsigned long hash, void * data)
154{
155 int index;
156
157 index = hash % table->hashtable_size;
158
159 if (table->table[index].data == NULL) {
160 table->table[index].hash = hash;
161 table->table[index].data = data;
162 table->table[index].next = NULL;
163
164 table->count ++;
165
166 return 0;
167 }
168 else {
169 int r;
170
171 r = hash_list_add(table, hash, data);
172 if (r == -1)
173 return -1;
174
175 table->count ++;
176
177 return 0;
178 }
179}
180
181int cinthash_remove(cinthash_t * table, unsigned long hash)
182{
183 int index;
184
185 index = hash % table->hashtable_size;
186
187 if (table->table[index].hash == hash) {
188 table->table[index].hash = 0;
189 table->table[index].data = NULL;
190
191 table->count --;
192
193 return 0;
194 }
195 else {
196 int r;
197
198 r = hash_list_remove(table, hash);
199
200 table->count --;
201
202 return 0;
203 }
204}
205
206void * cinthash_find(cinthash_t * table, unsigned long hash)
207{
208 int index;
209
210 index = hash % table->hashtable_size;
211
212 if (table->table[index].hash == hash)
213 return table->table[index].data;
214
215 return hash_list_find(table, hash);
216}
217
218void cinthash_foreach_key(cinthash_t * table,
219 void (* func)(unsigned long, void *),
220 void * data)
221{
222 unsigned long index;
223 struct cinthash_list * cur;
224
225 for(index = 0 ; index < table->hashtable_size ; index ++) {
226 if (table->table[index].data != NULL) {
227 func(table->table[index].hash, data);
228 for(cur = table->table[index].next ; cur != NULL ; cur = cur->next)
229 func(cur->hash, data);
230 }
231 }
232}
233
234void cinthash_foreach_data(cinthash_t * table,
235 void (* func)(void *, void *),
236 void * data)
237{
238 unsigned long index;
239 struct cinthash_list * cur;
240
241 for(index = 0 ; index < table->hashtable_size ; index ++) {
242 if (table->table[index].data != NULL) {
243 func(table->table[index].data, data);
244 for(cur = table->table[index].next ; cur != NULL ; cur = cur->next)
245 func(cur->data, data);
246 }
247 }
248}