Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
last version of tesh
[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(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         int rv;
166         
167         if(!htable || !key)
168                 return EINVAL;
169          
170         prev = &(((htable->content)[(*(htable->fn_hfunc))(key) % htable->size]));
171         
172         fn_cmp_key =htable->fn_cmp_key;
173
174         for(hassoc = *prev; hassoc; hassoc = hassoc->next)
175         {
176                 if((*fn_cmp_key)((hassoc->key),key))
177                 {
178                         *prev = hassoc->next;  
179                         val = (void*)hassoc->val;
180                         
181                         if((rv = allocator_dealloc(htable->allocator,hassoc)))
182                                 return rv;
183                                 
184                         if(htable->fn_finalize)
185                         {       
186                                 if((rv = (*(htable->fn_finalize))(&val)))
187                                         return rv;
188                         }
189                         
190                         return 0;
191                 }
192                 
193                 prev = &(hassoc->next);
194         }
195         
196         return ESRCH;
197 }
198
199 int
200 htable_free(htable_t* htableptr)
201 {
202         htable_t htable;
203         int rv;
204         
205         if(!(*htableptr))
206                 return EINVAL;
207         
208         htable = (htable_t)(*htableptr);
209         
210         if(htable->fn_finalize)
211         {
212                 hassoc_t* content;
213                 register hassoc_t hassoc;
214                 register int pos;
215                 int size;
216                 void* val;
217         
218                 content = htable->content;
219                 size = htable->size;
220         
221                 for(pos = 0; pos < size; pos++)
222                 {
223                         for(hassoc = content[pos]; hassoc; hassoc = hassoc->next)
224                         {
225                                 val = (void*)hassoc->val;
226                                 if((rv = (*(htable->fn_finalize))(&val)))
227                                         return rv;
228                         }
229                 }
230         }
231         
232         free(htable->content);
233         
234         if((rv = allocator_free(&(htable->allocator))))
235                 return rv;
236                 
237         free(*htableptr);
238         *htableptr = NULL;
239         
240         return 0;
241 }
242
243 int
244 htable_clear(htable_t htable)
245 {
246         hassoc_t* content;
247         register hassoc_t hassoc;
248         register int pos;
249         int size;
250         void* val;
251         int rv;
252         
253         if(!htable)
254                 return EINVAL;
255         
256         
257         content = htable->content;
258         size = htable->size;
259         
260         if(htable->fn_finalize)
261         {
262                 for(pos = 0; pos < size; pos++)
263                 {
264                         for(hassoc = content[pos]; hassoc; hassoc = hassoc->next)
265                         {
266                                 val = (void*)hassoc->val;
267                                 if((rv = (*(htable->fn_finalize))(&val)))
268                                         return rv;
269                         }
270                         
271                         content[pos] = NULL;
272                 }
273         }
274         else
275         {
276                 for(pos = 0; pos < size; pos++)
277                         content[pos] = NULL;
278         }
279         
280         return allocator_clear(htable->allocator);
281 }
282
283 int
284 htable_get_size(htable_t htable)
285 {
286         
287         if(!htable)
288         {
289                 errno = EINVAL;
290                 return -1;
291         }
292         
293         return allocator_get_size(htable->allocator);
294 }
295
296 int
297 htable_is_empty(htable_t htable)
298 {
299         if(!htable)
300         {
301                 errno = EINVAL;
302                 return 0;
303         }
304         
305         return  allocator_get_size(htable->allocator);
306 }
307
308 int
309 htable_is_autodelete(htable_t htable)
310 {
311         
312         if(!htable)
313         {
314                 errno = EINVAL;
315                 return 0;
316         }
317         
318         return (NULL != htable->fn_finalize);
319 }
320