start of new file
[IRC.git] / Robust / src / Runtime / ObjectHash.c
1 #include "ObjectHash.h"
2 #ifdef RAW
3 #include <raw.h>
4 #else
5 #include <stdio.h>
6 #endif
7 #ifdef DMALLOC
8 #include "dmalloc.h"
9 #endif
10
11 /* SIMPLE HASH ********************************************************/
12 struct ObjectIterator* ObjectHashcreateiterator(struct ObjectHash * thisvar) {
13     return allocateObjectIterator(thisvar->listhead);
14 }
15
16 void ObjectHashiterator(struct ObjectHash *thisvar, struct ObjectIterator * it) {
17   it->cur=thisvar->listhead;
18 }
19
20 struct ObjectHash * noargallocateObjectHash() {
21     return allocateObjectHash(100);
22 }
23
24 struct ObjectHash * allocateObjectHash(int size) {
25     struct ObjectHash *thisvar;//=(struct ObjectHash *)RUNMALLOC(sizeof(struct ObjectHash));
26     if (size <= 0) {
27 #ifdef RAW
28                 raw_test_done(0xc001);
29 #else
30         printf("Negative Hashtable size Exception\n");
31                 exit(-1);
32 #endif
33     }
34         thisvar=(struct ObjectHash *)RUNMALLOC(sizeof(struct ObjectHash));
35     thisvar->size = size;
36     thisvar->bucket = (struct ObjectNode **) RUNMALLOC(sizeof(struct ObjectNode *)*size);
37     /* Set allocation blocks*/
38     thisvar->listhead=NULL;
39     thisvar->listtail=NULL;
40     /*Set data counts*/
41     thisvar->numelements = 0;
42     return thisvar;
43 }
44
45 void freeObjectHash(struct ObjectHash *thisvar) {
46     struct ObjectNode *ptr=thisvar->listhead;
47     RUNFREE(thisvar->bucket);
48     while(ptr) {
49         struct ObjectNode *next=ptr->lnext;
50         RUNFREE(ptr);
51         ptr=next;
52     }
53     RUNFREE(thisvar);
54 }
55
56 inline int ObjectHashcountset(struct ObjectHash * thisvar) {
57     return thisvar->numelements;
58 }
59
60 int ObjectHashfirstkey(struct ObjectHash *thisvar) {
61   struct ObjectNode *ptr=thisvar->listhead;
62   return ptr->key;
63 }
64
65 int ObjectHashremove(struct ObjectHash *thisvar, int key) {
66     unsigned int hashkey = (unsigned int)key % thisvar->size;
67
68     struct ObjectNode **ptr = &thisvar->bucket[hashkey];
69     int i;
70
71     while (*ptr) {
72       if ((*ptr)->key == key) {
73           struct ObjectNode *toremove=*ptr;
74           *ptr=(*ptr)->next;
75
76           if (toremove->lprev!=NULL) {
77             toremove->lprev->lnext=toremove->lnext;
78           } else {
79             thisvar->listhead=toremove->lnext;
80           }
81           if (toremove->lnext!=NULL) {
82             toremove->lnext->lprev=toremove->lprev;
83           } else {
84             thisvar->listtail=toremove->lprev;
85           }
86           RUNFREE(toremove);
87
88           thisvar->numelements--;
89           return 1;
90         }
91         ptr = &((*ptr)->next);
92     }
93
94     return 0;
95 }
96
97 void ObjectHashrehash(struct ObjectHash * thisvar) {
98   int newsize=thisvar->size;
99   struct ObjectNode ** newbucket = (struct ObjectNode **) RUNMALLOC(sizeof(struct ObjectNode *)*newsize);
100   int i;
101   for(i=thisvar->size-1;i>=0;i--) {
102     struct ObjectNode *ptr;
103     for(ptr=thisvar->bucket[i];ptr!=NULL;) {
104       struct ObjectNode * nextptr=ptr->next;
105       unsigned int newhashkey=(unsigned int)ptr->key % newsize;
106       ptr->next=newbucket[newhashkey];
107       newbucket[newhashkey]=ptr;
108       ptr=nextptr;
109     }
110   }
111   thisvar->size=newsize;
112   RUNFREE(thisvar->bucket);
113   thisvar->bucket=newbucket;
114 }
115
116 int ObjectHashadd(struct ObjectHash * thisvar,int key, int data, int data2, int data3, int data4) {
117   /* Rehash code */
118   unsigned int hashkey;
119   struct ObjectNode **ptr;
120
121   if (thisvar->numelements>=thisvar->size) {
122     int newsize=2*thisvar->size+1;
123     struct ObjectNode ** newbucket = (struct ObjectNode **) RUNMALLOC(sizeof(struct ObjectNode *)*newsize);
124     int i;
125     for(i=thisvar->size-1;i>=0;i--) {
126         struct ObjectNode *ptr;
127         for(ptr=thisvar->bucket[i];ptr!=NULL;) {
128             struct ObjectNode * nextptr=ptr->next;
129             unsigned int newhashkey=(unsigned int)ptr->key % newsize;
130             ptr->next=newbucket[newhashkey];
131             newbucket[newhashkey]=ptr;
132             ptr=nextptr;
133         }
134     }
135     thisvar->size=newsize;
136     RUNFREE(thisvar->bucket);
137     thisvar->bucket=newbucket;
138   }
139
140   hashkey = (unsigned int)key % thisvar->size;
141   ptr = &thisvar->bucket[hashkey];
142
143   {
144     struct ObjectNode *node=RUNMALLOC(sizeof(struct ObjectNode));
145     node->data=data;
146     node->data2=data2;
147     node->data3=data3;
148     node->data4=data4;
149     node->key=key;
150     node->next=(*ptr);
151     *ptr=node;
152     if (thisvar->listhead==NULL) {
153       thisvar->listhead=node;
154       thisvar->listtail=node;
155       node->lnext=NULL;
156       node->lprev=NULL;
157     } else {
158       node->lprev=NULL;
159       node->lnext=thisvar->listhead;
160       thisvar->listhead->lprev=node;
161       thisvar->listhead=node;
162     }
163   }
164
165   thisvar->numelements++;
166   return 1;
167 }
168
169 #ifdef RAW
170 int ObjectHashadd_I(struct ObjectHash * thisvar,int key, int data, int data2, int data3, int data4) {
171   /* Rehash code */
172   unsigned int hashkey;
173   struct ObjectNode **ptr;
174
175   if (thisvar->numelements>=thisvar->size) {
176     int newsize=2*thisvar->size+1;
177     struct ObjectNode ** newbucket = (struct ObjectNode **) RUNMALLOC_I(sizeof(struct ObjectNode *)*newsize);
178     int i;
179     for(i=thisvar->size-1;i>=0;i--) {
180         struct ObjectNode *ptr;
181         for(ptr=thisvar->bucket[i];ptr!=NULL;) {
182             struct ObjectNode * nextptr=ptr->next;
183             unsigned int newhashkey=(unsigned int)ptr->key % newsize;
184             ptr->next=newbucket[newhashkey];
185             newbucket[newhashkey]=ptr;
186             ptr=nextptr;
187         }
188     }
189     thisvar->size=newsize;
190     RUNFREE(thisvar->bucket);
191     thisvar->bucket=newbucket;
192   }
193
194   hashkey = (unsigned int)key % thisvar->size;
195   ptr = &thisvar->bucket[hashkey];
196
197   {
198     struct ObjectNode *node=RUNMALLOC_I(sizeof(struct ObjectNode));
199     node->data=data;
200     node->data2=data2;
201     node->data3=data3;
202     node->data4=data4;
203     node->key=key;
204     node->next=(*ptr);
205     *ptr=node;
206     if (thisvar->listhead==NULL) {
207       thisvar->listhead=node;
208       thisvar->listtail=node;
209       node->lnext=NULL;
210       node->lprev=NULL;
211     } else {
212       node->lprev=NULL;
213       node->lnext=thisvar->listhead;
214       thisvar->listhead->lprev=node;
215       thisvar->listhead=node;
216     }
217   }
218
219   thisvar->numelements++;
220   return 1;
221 }
222 #endif
223
224 bool ObjectHashcontainskey(struct ObjectHash *thisvar,int key) {
225     unsigned int hashkey = (unsigned int)key % thisvar->size;
226
227     struct ObjectNode *ptr = thisvar->bucket[hashkey];
228     while (ptr) {
229         if (ptr->key == key) {
230             /* we already have thisvar object
231                stored in the hash so just return */
232             return true;
233         }
234         ptr = ptr->next;
235     }
236     return false;
237 }
238
239 bool ObjectHashcontainskeydata(struct ObjectHash *thisvar, int key, int data) {
240     unsigned int hashkey = (unsigned int)key % thisvar->size;
241
242     struct ObjectNode *ptr = thisvar->bucket[hashkey];
243     while (ptr) {
244         if (ptr->key == key && ptr->data == data) {
245             /* we already have thisvar object
246                stored in the hash so just return*/
247             return true;
248         }
249         ptr = ptr->next;
250     }
251     return false;
252 }
253
254 int ObjectHashcount(struct ObjectHash *thisvar,int key) {
255     unsigned int hashkey = (unsigned int)key % thisvar->size;
256     int count = 0;
257
258     struct ObjectNode *ptr = thisvar->bucket[hashkey];
259     while (ptr) {
260         if (ptr->key == key) {
261             count++;
262         }
263         ptr = ptr->next;
264     }
265     return count;
266 }
267
268 int ObjectHashget(struct ObjectHash *thisvar, int key, int *data, int *data2, int *data3, int *data4) {
269     unsigned int hashkey = (unsigned int)key % thisvar->size;
270
271     struct ObjectNode *ptr = thisvar->bucket[hashkey];
272     while (ptr) {
273         if (ptr->key == key) {
274             *data = ptr->data;
275             *data2 = ptr->data2;
276             *data3 = ptr->data3;
277             *data4 = ptr->data4;
278             return 1; /* success */
279         }
280         ptr = ptr->next;
281     }
282
283     return 0; /* failure */
284 }
285
286 int ObjectHashupdate(struct ObjectHash *thisvar, int key, int data, int data2, int data3, int data4) {
287     unsigned int hashkey = (unsigned int)key % thisvar->size;
288
289     struct ObjectNode *ptr = thisvar->bucket[hashkey];
290     while (ptr) {
291         if (ptr->key == key) {
292           ptr->data=data;
293           ptr->data2=data2;
294           ptr->data3=data3;
295           ptr->data4=data4;
296           return 1; /* success */
297         }
298         ptr = ptr->next;
299     }
300     return 0; /* failure */
301 }
302
303
304 inline struct ObjectIterator * noargallocateObjectIterator() {
305     return (struct ObjectIterator*)RUNMALLOC(sizeof(struct ObjectIterator));
306 }
307
308 inline struct ObjectIterator * allocateObjectIterator(struct ObjectNode *start) {
309     struct ObjectIterator *thisvar=(struct ObjectIterator*)RUNMALLOC(sizeof(struct ObjectIterator));
310     thisvar->cur = start;
311     return thisvar;
312 }
313
314 inline int ObjhasNext(struct ObjectIterator *thisvar) {
315   return (thisvar->cur!=NULL);
316 }
317
318 inline int Objnext(struct ObjectIterator *thisvar) {
319   int curr=thisvar->cur->data;
320   thisvar->cur=thisvar->cur->lnext;
321   return curr;
322 }
323
324 inline int Objkey(struct ObjectIterator *thisvar) {
325   return thisvar->cur->key;
326 }
327
328 inline int Objdata(struct ObjectIterator *thisvar) {
329   return thisvar->cur->data;
330 }
331
332 inline int Objdata2(struct ObjectIterator *thisvar) {
333   return thisvar->cur->data2;
334 }
335
336 inline int Objdata3(struct ObjectIterator *thisvar) {
337   return thisvar->cur->data3;
338 }
339
340 inline int Objdata4(struct ObjectIterator *thisvar) {
341   return thisvar->cur->data4;
342 }