Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
tesh version 2
[simgrid.git] / tools / tesh2 / src / htable.c
1
2 #include <htable.h>
3
4 #include <errno.h>
5 #include <stdlib.h>     /* calloc()     free() */
6
7 #define __DEFAULT_BLOCK_CAPACITY        ((int)512)
8 #define __DEFAULT_TABLE_SIZE            ((int)256)
9
10
11 static hassoc_t
12 get_assoc(htable_t htable, const void* key, unsigned int* hval)
13 {
14         register hassoc_t hassoc;
15         hassoc_t* content = htable->content;
16         fn_cmp_key_t fn_cmp_key = htable->fn_cmp_key;
17         
18         *hval = (*(htable->fn_hfunc))(key) % htable->size;
19
20         for (hassoc = content[*hval]; hassoc; hassoc = hassoc->next)
21                 if((*fn_cmp_key)(hassoc->key,key))
22                         return hassoc;
23         
24         return NULL;
25 }
26
27
28 htable_t
29 htable_new(
30                                 int block_capacity, 
31                                 int size, 
32                                 fn_hfunc_t fn_hfunc, 
33                                 fn_cmp_key_t fn_cmp_key, 
34                                 fn_finalize_t fn_finalize
35 )
36 {
37         htable_t htable;
38         
39         if((block_capacity < 0) || (size < 0) ||!fn_hfunc || !fn_cmp_key)
40         {
41                 errno = EINVAL;
42                 return NULL;
43         }
44         
45                 
46         if(!(htable = (htable_t)calloc(1, sizeof(s_htable_t))))
47                 return NULL;
48         
49         if(!(htable->content = (hassoc_t*)calloc(size ? size : __DEFAULT_TABLE_SIZE, sizeof(hassoc_t))))
50         {
51                 free(htable);
52                 return NULL;
53         }
54         
55         if(!(htable->allocator = allocator_new(block_capacity ? block_capacity : __DEFAULT_BLOCK_CAPACITY, sizeof(s_hassoc_t),NULL)))
56         {
57                 free(htable->content);
58                 free(htable);
59                 return NULL;
60         }
61         
62         htable->size = size;
63         htable->fn_hfunc = fn_hfunc;
64         htable->fn_cmp_key = fn_cmp_key;
65         htable->fn_finalize = fn_finalize;
66         
67         return htable;
68 }
69
70 int
71 htable_set(htable_t htable, const void* key, const void* val)
72 {
73         hassoc_t hassoc;
74         unsigned int hval;
75         
76         if(!htable || !key || !val)
77                 return EINVAL;
78         
79         
80         if(!(hassoc = get_assoc(htable, key, &hval)))
81         {
82                 if(!(hassoc = (hassoc_t)allocator_alloc(htable->allocator)))
83                         return errno;
84                 
85                 hassoc->key = key;
86                 hassoc->val = val;
87                 
88                 hassoc->next = (htable->content)[hval];
89                 (htable->content)[hval] = hassoc;
90                 
91         }
92         else
93                 hassoc->val = val; 
94         
95         return 0;  
96 }
97
98 void*
99 htable_lookup(htable_t htable, const void* key)
100 {
101         hassoc_t hassoc;
102         unsigned int hval;
103         
104         if(!htable || !key)
105         {
106                 errno = EINVAL;
107                 return NULL;
108         }
109         
110         if(!(hassoc = get_assoc(htable, key, &hval)))
111         {
112                 errno = ESRCH;
113                 return NULL;
114         }
115         
116         return (void*)(hassoc->val);
117         
118 }
119
120 void*
121 htable_remove(htable_t htable, const void* key)
122 {
123         register hassoc_t hassoc;
124         hassoc_t* prev;
125         fn_cmp_key_t fn_cmp_key;
126         void* val;
127         
128         if(!htable || !key)
129         {
130                 errno = EINVAL;
131                 return NULL;
132         }
133         
134         prev = &(((htable->content)[(*(htable->fn_hfunc))(key) % htable->size]));
135         fn_cmp_key =htable->fn_cmp_key;
136
137         for (hassoc = *prev; hassoc; hassoc = hassoc->next)
138         {
139                 if((*fn_cmp_key)((hassoc->key),key))
140                 {
141                         *prev = hassoc->next;  
142                         val = (void*)hassoc->val;
143                         
144                         if((errno = allocator_dealloc(htable->allocator,hassoc)))
145                                 return NULL;
146                                 
147                         return val;
148                 }
149                 
150                 prev = &(hassoc->next);
151         }
152         
153         
154         errno = ESRCH;
155         return NULL;
156 }
157
158 int
159 htable_erase(htable_t htable, const void* key)
160 {
161         register hassoc_t hassoc;
162         hassoc_t* prev;
163         fn_cmp_key_t fn_cmp_key;
164         void* val;
165         
166         if(!htable || !key)
167                 return EINVAL;
168          
169         prev = &(((htable->content)[(*(htable->fn_hfunc))(key) % htable->size]));
170         
171         fn_cmp_key =htable->fn_cmp_key;
172
173         for(hassoc = *prev; hassoc; hassoc = hassoc->next)
174         {
175                 if((*fn_cmp_key)((hassoc->key),key))
176                 {
177                         *prev = hassoc->next;  
178                         val = (void*)hassoc->val;
179                         
180                         if((errno = allocator_dealloc(htable->allocator,hassoc)))
181                                 return errno;
182                                 
183                         if(htable->fn_finalize)
184                         {       
185                                 if((errno = (*(htable->fn_finalize))(&val)))
186                                         return errno;
187                         }
188                         
189                         return 0;
190                 }
191                 
192                 prev = &(hassoc->next);
193         }
194         
195         return ESRCH;
196 }
197
198 int
199 htable_free(htable_t* htableptr)
200 {
201         htable_t htable;
202         
203         if(!(*htableptr))
204                 return EINVAL;
205         
206         htable = (htable_t)(*htableptr);
207         
208         if(htable->fn_finalize)
209         {
210                 hassoc_t* content;
211                 register hassoc_t hassoc;
212                 register int pos;
213                 int size;
214                 void* val;
215         
216                 content = htable->content;
217                 size = htable->size;
218         
219                 for(pos = 0; pos < size; pos++)
220                 {
221                         for(hassoc = content[pos]; hassoc; hassoc = hassoc->next)
222                         {
223                                 val = (void*)hassoc->val;
224                                 if((errno = (*(htable->fn_finalize))(&val)))
225                                         return errno;
226                         }
227                 }
228         }
229         
230         free(htable->content);
231         
232         if((errno = allocator_free(&(htable->allocator))))
233                 return errno;
234                 
235         free(*htableptr);
236         *htableptr = NULL;
237         
238         return 0;
239 }
240
241 int
242 htable_clear(htable_t htable)
243 {
244         hassoc_t* content;
245         register hassoc_t hassoc;
246         register int pos;
247         int size;
248         void* val;
249         
250         if(!htable)
251                 return EINVAL;
252         
253         
254         content = htable->content;
255         size = htable->size;
256         
257         if(htable->fn_finalize)
258         {
259                 for(pos = 0; pos < size; pos++)
260                 {
261                         for(hassoc = content[pos]; hassoc; hassoc = hassoc->next)
262                         {
263                                 val = (void*)hassoc->val;
264                                 if((errno = (*(htable->fn_finalize))(&val)))
265                                         return errno;
266                         }
267                         
268                         content[pos] = NULL;
269                 }
270         }
271         else
272         {
273                 for(pos = 0; pos < size; pos++)
274                         content[pos] = NULL;
275         }
276         
277         return allocator_clear(htable->allocator);
278 }
279
280 int
281 htable_get_size(htable_t htable)
282 {
283         
284         if(!htable)
285         {
286                 errno = EINVAL;
287                 return -1;
288         }
289         
290         return allocator_get_size(htable->allocator);
291 }
292
293 int
294 htable_is_empty(htable_t htable)
295 {
296         if(!htable)
297         {
298                 errno = EINVAL;
299                 return 0;
300         }
301         
302         return  allocator_get_size(htable->allocator);
303 }
304
305 int
306 htable_is_autodelete(htable_t htable)
307 {
308         
309         if(!htable)
310         {
311                 errno = EINVAL;
312                 return 0;
313         }
314         
315         return (NULL != htable->fn_finalize);
316 }
317