Various bug fixes related to the C switch.
[repair.git] / Repair / RepairCompiler / MCC / CRuntime / SimpleHash.c
1 #include "SimpleHash.h"
2 #include <stdio.h>
3
4 /* LINKED HASH NODE ****************************************************/
5
6 struct LinkedHashNode * allocateLinkedHashNode(int key, int data, struct LinkedHashNode *next) {
7     struct LinkedHashNode *thisvar=(struct LinkedHashNode *)malloc(sizeof(struct LinkedHashNode));
8     thisvar->key = key;
9     thisvar->data = data;
10     thisvar->next = next;
11     thisvar->lnext=0;
12     thisvar->lprev=0;
13     return thisvar;
14 }
15
16 struct LinkedHashNode * noargallocateLinkedHashNode() {
17     struct LinkedHashNode *thisvar=(struct LinkedHashNode *)malloc(sizeof(struct LinkedHashNode));
18     thisvar->key = -1;
19     thisvar->data = -1;
20     thisvar->next = 0;
21     thisvar->lnext=0;
22     thisvar->lprev=0;
23     return thisvar;
24 }
25
26 /* SIMPLE LIST ****************************************************/
27
28 struct SimpleList * allocateSimpleList() {
29     struct SimpleList *thisvar=(struct SimpleList *)malloc(sizeof(struct SimpleList));
30     thisvar->ptr = 0;
31     thisvar->head.next = 0;
32     return thisvar;
33 }
34
35 void SimpleListreset(struct SimpleList *thisvar) {
36     thisvar->ptr = &thisvar->head;
37 }
38
39 int SimpleListhasMoreElements(struct SimpleList *thisvar) {
40     return (thisvar->ptr->next != 0);
41 }
42
43 int SimpleListnextElement(struct SimpleList *thisvar) {
44   thisvar->ptr = thisvar->ptr->next;
45   return thisvar->ptr->data;
46 }
47
48 void SimpleListadd(struct SimpleList *thisvar,int data) {
49     struct LinkedHashNode *cur = &thisvar->head;
50     while (cur->next) {
51         cur = cur->next;
52         if (cur->data == data) {
53             return; /* no duplicates */
54         }
55     }
56     cur->next = allocateLinkedHashNode(0, data, 0);
57     return;
58 }
59
60 int SimpleListcontains(struct SimpleList *thisvar,int data) {
61     struct LinkedHashNode *cur = &thisvar->head;
62     while (cur->next) {
63         cur = cur->next;
64         if (cur->data == data) {
65             return 1; /* found! */
66         }
67     }
68     return 0;
69 }
70
71 /* WORK LIST ****************************************************/
72
73 struct WorkList * allocateWorkList() {
74     struct WorkList *thisvar=(struct WorkList *)malloc(sizeof(struct WorkList));
75     thisvar->head=(struct ListNode *) malloc(sizeof(struct ListNode));
76     thisvar->tail=thisvar->head;
77     thisvar->head->next=0;
78     thisvar->headoffset=0;
79     thisvar->tailoffset=0;
80     return thisvar;
81 }
82
83 void WorkListreset(struct WorkList *thisvar) {
84     thisvar->head=thisvar->tail;
85     thisvar->headoffset=0;
86     thisvar->tailoffset=0;
87 }
88
89 int WorkListhasMoreElements(struct WorkList *thisvar) {
90   return ((thisvar->head!=thisvar->tail)||(thisvar->headoffset!=thisvar->tailoffset));
91 }
92
93 int WorkListgetid(struct WorkList *thisvar) {
94   return thisvar->tail->data[thisvar->tailoffset];
95 }
96
97 int WorkListgettype(struct WorkList *thisvar) {
98   return thisvar->tail->data[thisvar->tailoffset+1];
99 }
100
101 int WorkListgetlvalue(struct WorkList *thisvar) {
102   return thisvar->tail->data[thisvar->tailoffset+2];
103 }
104
105 int WorkListgetrvalue(struct WorkList *thisvar) {
106   return thisvar->tail->data[thisvar->tailoffset+3];
107 }
108
109 void freeWorkList(struct WorkList *thisvar) {
110   struct ListNode *ptr=thisvar->tail;
111   while(ptr) {
112     struct ListNode *oldptr=ptr;
113     ptr=ptr->next;
114     free(oldptr);
115   }
116   free(thisvar);
117 }
118
119 void WorkListpop(struct WorkList *thisvar) {
120   int newoffset=thisvar->tailoffset+4;
121   struct ListNode *ptr=thisvar->tail;
122   if (newoffset>=WLISTSIZE) {
123     if (newoffset!=WLISTSIZE||thisvar->head!=thisvar->tail) {
124       struct ListNode *oldptr=ptr;
125       newoffset-=WLISTSIZE;
126       ptr=ptr->next;
127       free(oldptr);
128     }
129   }
130   thisvar->tail=ptr;
131   thisvar->tailoffset=newoffset;
132 }
133
134 void WorkListadd(struct WorkList *thisvar, int id,int type, int lvalue, int rvalue) {
135   if (thisvar->headoffset==WLISTSIZE) {
136     if (thisvar->head->next==0) {
137       thisvar->head->next=(struct ListNode *)malloc(sizeof(struct ListNode));
138       thisvar->head->next->next=0;
139     }
140     thisvar->headoffset=0;
141     thisvar->head=thisvar->head->next;
142     if (thisvar->tailoffset==WLISTSIZE) { /* roll the tail over also */
143         thisvar->tailoffset=0;
144         thisvar->tail=thisvar->tail->next;
145     }
146   }
147   thisvar->head->data[thisvar->headoffset++]=id;
148   thisvar->head->data[thisvar->headoffset++]=type;
149   thisvar->head->data[thisvar->headoffset++]=lvalue;
150   thisvar->head->data[thisvar->headoffset++]=rvalue;
151 }
152
153 /* SIMPLE HASH ********************************************************/
154 struct SimpleIterator* SimpleHashcreateiterator(struct SimpleHash * thisvar) {
155     return allocateSimpleIterator(thisvar->listhead,thisvar->listtail,thisvar->tailindex/*,thisvar*/);
156 }
157
158 void SimpleHashiterator(struct SimpleHash *thisvar, struct SimpleIterator * it) {
159   it->cur=thisvar->listhead;
160   it->index=0;
161   it->tailindex=thisvar->tailindex;
162   it->tail=thisvar->listtail;
163 }
164
165 struct SimpleHash * noargallocateSimpleHash() {
166     return allocateSimpleHash(100);
167 }
168
169 struct SimpleHash * allocateSimpleHash(int size) {
170     struct SimpleHash *thisvar=(struct SimpleHash *)malloc(sizeof(struct SimpleHash));
171     if (size <= 0) {
172         printf("Negative Hashtable size Exception\n");
173         exit(-1);
174     }
175     thisvar->size = size;
176     thisvar->bucket = (struct SimpleNode **) calloc(sizeof(struct SimpleNode *)*size,1);
177     /* Set allocation blocks*/
178     thisvar->listhead=(struct ArraySimple *) calloc(sizeof(struct ArraySimple),1);
179     thisvar->listtail=thisvar->listhead;
180     thisvar->tailindex=0;
181     /*Set data counts*/
182     thisvar->numparents = 0;
183     thisvar->numchildren = 0;
184     thisvar->numelements = 0;
185     return thisvar;
186 }
187
188 void freeSimpleHash(struct SimpleHash *thisvar) {
189     struct ArraySimple *ptr=thisvar->listhead;
190     free(thisvar->bucket);
191     while(ptr) {
192         struct ArraySimple *next=ptr->nextarray;
193         free(ptr);
194         ptr=next;
195     }
196     free(thisvar);
197 }
198
199 inline int SimpleHashcountset(struct SimpleHash * thisvar) {
200     return thisvar->numelements;
201 }
202
203 int SimpleHashfirstkey(struct SimpleHash *thisvar) {
204   struct ArraySimple *ptr=thisvar->listhead;
205   int index=0;
206   while((index==ARRAYSIZE)||!ptr->nodes[index].inuse) {
207     if (index==ARRAYSIZE) {
208       index=0;
209       ptr=ptr->nextarray;
210     } else
211       index++;
212   }
213   return ptr->nodes[index].key;
214 }
215
216 void SimpleHashaddParent(struct SimpleHash *thisvar,struct SimpleHash* parent) {
217     thisvar->parents[thisvar->numparents++] = parent;
218     SimpleHashaddChild(parent,thisvar);
219 }
220
221 void SimpleHashaddChild(struct SimpleHash *thisvar, struct SimpleHash *child) {
222     thisvar->children[thisvar->numchildren++]=child;
223 }
224
225 int SimpleHashremove(struct SimpleHash *thisvar, int key, int data) {
226     unsigned int hashkey = (unsigned int)key % thisvar->size;
227
228     struct SimpleNode **ptr = &thisvar->bucket[hashkey];
229     int i;
230     for (i = 0; i < thisvar->numchildren; i++) {
231         SimpleHashremove(thisvar->children[i], key, data);
232     }
233
234     while (*ptr) {
235         if ((*ptr)->key == key && (*ptr)->data == data) {
236           struct SimpleNode *toremove=*ptr;
237           *ptr=(*ptr)->next;
238
239           toremove->inuse=0; /* Marked as unused */
240
241           thisvar->numelements--;
242           return 1;
243         }
244         ptr = &((*ptr)->next);
245     }
246
247     return 0;
248 }
249
250 void SimpleHashaddAll(struct SimpleHash *thisvar, struct SimpleHash * set) {
251     struct SimpleIterator it;
252     SimpleHashiterator(set, &it);
253     while(hasNext(&it)) {
254         int keyv=key(&it);
255         int data=next(&it);
256         SimpleHashadd(thisvar,keyv,data);
257     }
258 }
259
260 int SimpleHashadd(struct SimpleHash * thisvar,int key, int data) {
261   /* Rehash code */
262   unsigned int hashkey;
263   struct SimpleNode **ptr;
264
265   if (thisvar->numelements>=thisvar->size) {
266     int newsize=2*thisvar->size+1;
267     struct SimpleNode ** newbucket = (struct SimpleNode **) calloc(sizeof(struct SimpleNode *)*newsize,1);
268     int i;
269     for(i=thisvar->size-1;i>=0;i--) {
270         struct SimpleNode *ptr;
271         for(ptr=thisvar->bucket[i];ptr!=NULL;) {
272             struct SimpleNode * nextptr=ptr->next;
273             unsigned int newhashkey=(unsigned int)ptr->key % newsize;
274             ptr->next=newbucket[newhashkey];
275             newbucket[newhashkey]=ptr;
276             ptr=nextptr;
277         }
278     }
279     thisvar->size=newsize;
280     free(thisvar->bucket);
281     thisvar->bucket=newbucket;
282   }
283
284   hashkey = (unsigned int)key % thisvar->size;
285   ptr = &thisvar->bucket[hashkey];
286
287   /* check that thisvar key/object pair isn't already here */
288   /* TBD can be optimized for set v. relation */
289
290   while (*ptr) {
291     if ((*ptr)->key == key && (*ptr)->data == data) {
292       return 0;
293     }
294     ptr = &((*ptr)->next);
295   }
296   if (thisvar->tailindex==ARRAYSIZE) {
297     thisvar->listtail->nextarray=(struct ArraySimple *) calloc(sizeof(struct ArraySimple),1);
298     thisvar->tailindex=0;
299     thisvar->listtail=thisvar->listtail->nextarray;
300   }
301
302   *ptr = &thisvar->listtail->nodes[thisvar->tailindex++];
303   (*ptr)->key=key;
304   (*ptr)->data=data;
305   (*ptr)->inuse=1;
306
307   thisvar->numelements++;
308   {
309       int i;
310       for (i = 0; i < thisvar->numparents; i++) {
311           SimpleHashadd(thisvar->parents[i], key, data);
312       }
313   }
314   return 1;
315 }
316
317 bool SimpleHashcontainskey(struct SimpleHash *thisvar,int key) {
318     unsigned int hashkey = (unsigned int)key % thisvar->size;
319
320     struct SimpleNode *ptr = thisvar->bucket[hashkey];
321     while (ptr) {
322         if (ptr->key == key) {
323             /* we already have thisvar object
324                stored in the hash so just return */
325             return true;
326         }
327         ptr = ptr->next;
328     }
329     return false;
330 }
331
332 bool SimpleHashcontainskeydata(struct SimpleHash *thisvar, int key, int data) {
333     unsigned int hashkey = (unsigned int)key % thisvar->size;
334
335     struct SimpleNode *ptr = thisvar->bucket[hashkey];
336     while (ptr) {
337         if (ptr->key == key && ptr->data == data) {
338             /* we already have thisvar object
339                stored in the hash so just return*/
340             return true;
341         }
342         ptr = ptr->next;
343     }
344     return false;
345 }
346
347 int SimpleHashcount(struct SimpleHash *thisvar,int key) {
348     unsigned int hashkey = (unsigned int)key % thisvar->size;
349     int count = 0;
350
351     struct SimpleNode *ptr = thisvar->bucket[hashkey];
352     while (ptr) {
353         if (ptr->key == key) {
354             count++;
355         }
356         ptr = ptr->next;
357     }
358     return count;
359 }
360
361 struct SimpleHash * SimpleHashimageSet(struct SimpleHash *thisvar, int key) {
362   struct SimpleHash * newset=allocateSimpleHash(2*SimpleHashcount(thisvar,key)+4);
363   unsigned int hashkey = (unsigned int)key % thisvar->size;
364
365   struct SimpleNode *ptr = thisvar->bucket[hashkey];
366   while (ptr) {
367     if (ptr->key == key) {
368         SimpleHashadd(newset,ptr->data,ptr->data);
369     }
370     ptr = ptr->next;
371   }
372   return newset;
373 }
374
375 int SimpleHashget(struct SimpleHash *thisvar, int key, int *data) {
376     unsigned int hashkey = (unsigned int)key % thisvar->size;
377
378     struct SimpleNode *ptr = thisvar->bucket[hashkey];
379     while (ptr) {
380         if (ptr->key == key) {
381             *data = ptr->data;
382             return 1; /* success */
383         }
384         ptr = ptr->next;
385     }
386
387     return 0; /* failure */
388 }
389
390 int SimpleHashcountdata(struct SimpleHash *thisvar,int data) {
391     int count = 0;
392     struct ArraySimple *ptr = thisvar->listhead;
393     while(ptr) {
394       if (ptr->nextarray) {
395           int i;
396           for(i=0;i<ARRAYSIZE;i++)
397               if (ptr->nodes[i].data == data
398                   &&ptr->nodes[i].inuse) {
399                   count++;
400               }
401       } else {
402           int i;
403           for(i=0;i<thisvar->tailindex;i++)
404               if (ptr->nodes[i].data == data
405                   &&ptr->nodes[i].inuse) {
406                   count++;
407               }
408       }
409       ptr = ptr->nextarray;
410     }
411     return count;
412 }
413
414 struct RepairHashNode * allocateRepairHashNode(int setrelation, int rule, int lvalue, int rvalue, int data, int data2, int ismodify){
415     struct RepairHashNode * thisvar=(struct RepairHashNode *)malloc(sizeof(struct RepairHashNode));
416     thisvar->setrelation = setrelation;
417     thisvar->lvalue=lvalue;
418     thisvar->rvalue=rvalue;
419     thisvar->data = data;
420     thisvar->data2 = data2;
421     thisvar->next = 0;
422     thisvar->lnext=0;
423     thisvar->rule=rule;
424     thisvar->ismodify=ismodify;
425     return thisvar;
426 }
427
428 struct RepairHash * allocateRepairHash(int size) {
429     struct RepairHash *thisvar=(struct RepairHash*)malloc(sizeof(struct RepairHash));
430     if (size <= 0) {
431         printf("Negative size for RepairHash\n");
432         exit(-1);
433     }
434
435     thisvar->size = size;
436     thisvar->bucket = (struct RepairHashNode **) calloc(1,sizeof(struct RepairHashNode*)*size);
437     thisvar->nodelist=0;
438     thisvar->numelements = 0;
439     return thisvar;
440 }
441
442 #define REPAIRSIZE 100
443 struct RepairHash * noargallocateRepairHash() {
444     return allocateRepairHash(REPAIRSIZE);
445 }
446
447 void freeRepairHash(struct RepairHash *thisvar) {
448   struct RepairHashNode *ptr=thisvar->nodelist;
449   free(thisvar->bucket);
450   while(ptr) {
451       struct RepairHashNode *next=ptr->lnext;
452       free(ptr);
453       ptr=next;
454   }
455   free(thisvar);
456 }
457
458 #define SETFLAG (1<<31)
459
460 int RepairHashaddset(struct RepairHash *thisvar, int setv, int rule, int value, int data) {
461   return RepairHashaddrelation(thisvar, setv||SETFLAG, rule, value,0,data);
462 }
463
464 int RepairHashaddrelation(struct RepairHash *thisvar, int relation, int rule, int lvalue, int rvalue, int data) {
465     unsigned int hashkey = ((unsigned int)(relation ^ rule ^ lvalue ^ rvalue)) % thisvar->size;
466
467     struct RepairHashNode **ptr = &thisvar->bucket[hashkey];
468
469     /* check that thisvar key/object pair isn't already here */
470     /* TBD can be optimized for set v. relation */
471     while (*ptr) {
472         if ((*ptr)->setrelation == relation &&
473             (*ptr)->rule==rule &&
474             (*ptr)->lvalue==lvalue &&
475             (*ptr)->rvalue==rvalue &&
476             (*ptr)->data == data&&
477             (*ptr)->data2 == 0) {
478             return 0;
479         }
480         ptr = &((*ptr)->next);
481     }
482
483     *ptr = allocateRepairHashNode(relation,rule,lvalue,rvalue, data,0,0);
484     (*ptr)->lnext=thisvar->nodelist;
485     thisvar->nodelist=*ptr;
486     thisvar->numelements++;
487     return 1;
488 }
489
490 int RepairHashaddrelation2(struct RepairHash *thisvar, int relation, int rule, int lvalue, int rvalue, int data, int data2) {
491     unsigned int hashkey = ((unsigned int)(relation ^ rule ^ lvalue ^ rvalue)) % thisvar->size;
492
493     struct RepairHashNode **ptr = &thisvar->bucket[hashkey];
494
495     /* check that thisvar key/object pair isn't already here */
496     /* TBD can be optimized for set v. relation */
497     while (*ptr) {
498         if ((*ptr)->setrelation == relation &&
499             (*ptr)->rule==rule &&
500             (*ptr)->lvalue==lvalue &&
501             (*ptr)->rvalue==rvalue &&
502             (*ptr)->data == data &&
503             (*ptr)->data2 == data2) {
504             return 0;
505         }
506         ptr = &((*ptr)->next);
507     }
508
509     *ptr = allocateRepairHashNode(relation,rule,lvalue,rvalue, data,data2,1);
510     (*ptr)->lnext=thisvar->nodelist;
511     thisvar->nodelist=*ptr;
512     thisvar->numelements++;
513     return 1;
514 }
515
516 bool RepairHashcontainsset(struct RepairHash *thisvar, int setv, int rule, int value) {
517   return RepairHashcontainsrelation(thisvar, setv||SETFLAG, rule, value,0);
518 }
519
520 bool RepairHashcontainsrelation(struct RepairHash *thisvar, int relation, int rule, int lvalue, int rvalue) {
521     unsigned int hashkey = ((unsigned int)(relation ^ rule ^ lvalue ^ rvalue)) % thisvar->size;
522
523     struct RepairHashNode **ptr = &thisvar->bucket[hashkey];
524
525     /* check that thisvar key/object pair isn't already here */
526     /*  TBD can be optimized for set v. relation */
527     while (*ptr) {
528         if ((*ptr)->setrelation == relation &&
529             (*ptr)->rule==rule &&
530             (*ptr)->lvalue==lvalue &&
531             (*ptr)->rvalue==rvalue) {
532             return true;
533         }
534         ptr = &((*ptr)->next);
535     }
536     return false;
537 }
538
539 int RepairHashgetset(struct RepairHash *thisvar, int setv, int rule, int value) {
540   return RepairHashgetrelation(thisvar, setv||SETFLAG, rule, value,0);
541 }
542
543 int RepairHashismodify(struct RepairHash *thisvar, int relation, int rule, int lvalue,int rvalue) {
544     unsigned int hashkey = ((unsigned int)(relation ^ rule ^ lvalue ^ rvalue)) % thisvar->size;
545
546     struct RepairHashNode **ptr = &thisvar->bucket[hashkey];
547
548     /* check that thisvar key/object pair isn't already here */
549     /* TBD can be optimized for set v. relation */
550     while (*ptr) {
551         if ((*ptr)->setrelation == relation &&
552             (*ptr)->rule==rule &&
553             (*ptr)->lvalue==lvalue &&
554             (*ptr)->rvalue==rvalue) {
555           return (*ptr)->ismodify;
556         }
557         ptr = &((*ptr)->next);
558     }
559     return 0;
560 }
561
562 int RepairHashgetrelation2(struct RepairHash *thisvar, int relation, int rule, int lvalue,int rvalue) {
563     unsigned int hashkey = ((unsigned int)(relation ^ rule ^ lvalue ^ rvalue)) % thisvar->size;
564
565     struct RepairHashNode **ptr = &thisvar->bucket[hashkey];
566
567     /* check that thisvar key/object pair isn't already here */
568     /* TBD can be optimized for set v. relation */
569     while (*ptr) {
570         if ((*ptr)->setrelation == relation &&
571             (*ptr)->rule==rule &&
572             (*ptr)->lvalue==lvalue &&
573             (*ptr)->rvalue==rvalue) {
574           return (*ptr)->data2;
575         }
576         ptr = &((*ptr)->next);
577     }
578     return 0;
579 }
580
581 int RepairHashgetrelation(struct RepairHash *thisvar, int relation, int rule, int lvalue,int rvalue) {
582     unsigned int hashkey = ((unsigned int)(relation ^ rule ^ lvalue ^ rvalue)) % thisvar->size;
583
584     struct RepairHashNode **ptr = &thisvar->bucket[hashkey];
585
586     /* check that this key/object pair isn't already here */
587     /* TBD can be optimized for set v. relation */
588     while (*ptr) {
589         if ((*ptr)->setrelation == relation &&
590             (*ptr)->rule==rule &&
591             (*ptr)->lvalue==lvalue &&
592             (*ptr)->rvalue==rvalue) {
593           return (*ptr)->data;
594         }
595         ptr = &((*ptr)->next);
596     }
597     return 0;
598 }
599
600 inline struct SimpleIterator * noargallocateSimpleIterator() {
601     return (struct SimpleIterator*)malloc(sizeof(struct SimpleIterator));
602 }
603
604 inline struct SimpleIterator * allocateSimpleIterator(struct ArraySimple *start, struct ArraySimple *tl, int tlindex) {
605     struct SimpleIterator *thisvar=(struct SimpleIterator*)malloc(sizeof(struct SimpleIterator));
606     thisvar->cur = start;
607     thisvar->index=0;
608     thisvar->tailindex=tlindex;
609     thisvar->tail=tl;
610     return thisvar;
611 }
612
613 inline int hasNext(struct SimpleIterator *thisvar) {
614     if (thisvar->cur==thisvar->tail &&
615         thisvar->index==thisvar->tailindex)
616         return 0;
617     while((thisvar->index==ARRAYSIZE)||!thisvar->cur->nodes[thisvar->index].inuse) {
618         if (thisvar->index==ARRAYSIZE) {
619             thisvar->index=0;
620             thisvar->cur=thisvar->cur->nextarray;
621         } else
622             thisvar->index++;
623     }
624     if (thisvar->cur->nodes[thisvar->index].inuse)
625         return 1;
626     else
627         return 0;
628 }
629
630 inline int next(struct SimpleIterator *thisvar) {
631     return thisvar->cur->nodes[thisvar->index++].data;
632 }
633
634 inline int key(struct SimpleIterator *thisvar) {
635     return thisvar->cur->nodes[thisvar->index].key;
636 }