Worklist items from a previous model build stay in the worklist...this causes lots...
[repair.git] / Repair / RepairCompiler / MCC / Runtime / SimpleHash.cc
1 #include "SimpleHash.h"
2 #include <stdarg.h>
3 #include <stdlib.h>
4
5 /* LINKED HASH NODE ****************************************************/
6
7 LinkedHashNode::LinkedHashNode(int key, int data, LinkedHashNode *next) {
8     this->key = key;
9     this->data = data;
10     this->next = next;
11     this->lnext=0;
12     this->lprev=0;
13 }
14
15 LinkedHashNode::LinkedHashNode() {
16     this->key = -1;
17     this->data = -1;
18     this->next = 0;
19     this->lnext=0;
20     this->lprev=0;
21 }
22
23 /* SIMPLE LIST ****************************************************/
24
25 SimpleList::SimpleList() {
26     ptr = 0;
27     head.next = 0;
28 }
29
30 void SimpleList::reset() {
31   // ptr = head.next;
32   ptr = &head;
33 }
34
35 int SimpleList::hasMoreElements() {
36   //  return (ptr != 0);
37   return (ptr->next != 0);
38 }
39
40 int SimpleList::nextElement() {
41   ptr = ptr->next;
42   return ptr->data;
43
44   //int data = ptr->data;
45   //ptr = ptr->next;
46   //return data;
47 }
48
49 void SimpleList::add(int data) {
50     LinkedHashNode *cur = &head;
51     while (cur->next) {
52         cur = cur->next;
53         if (cur->data == data) {
54             return; // no duplicates
55         }
56     }
57     cur->next = new LinkedHashNode(0, data, 0);
58     return;
59 }
60
61 int SimpleList::contains(int data) {
62     LinkedHashNode *cur = &head;
63     while (cur->next) {
64         cur = cur->next;
65         if (cur->data == data) {
66             return 1; // found!
67         }
68     }
69     return 0;    
70 }
71
72 /* WORK LIST ****************************************************/
73
74 WorkList::WorkList() {
75   head=(struct ListNode *) malloc(sizeof(struct ListNode));
76   tail=head;
77   head->next=0;
78   headoffset=0;
79   tailoffset=0;
80 }
81
82 void WorkList::reset() {
83   head=tail;
84   headoffset=0;
85   tailoffset=0;
86 }
87
88 int WorkList::hasMoreElements() {
89   //  return (ptr != 0);
90   return ((head!=tail)||(headoffset!=tailoffset));
91 }
92
93 int WorkList::getid() {
94   return tail->data[tailoffset];
95 }
96
97 int WorkList::gettype() {
98   return tail->data[tailoffset+1];
99 }
100
101 int WorkList::getlvalue() {
102   return tail->data[tailoffset+2];
103 }
104
105 int WorkList::getrvalue() {
106   return tail->data[tailoffset+3];
107 }
108
109 WorkList::~WorkList() {
110   struct ListNode *ptr=tail;
111   while(ptr) {
112     struct ListNode *oldptr=ptr;
113     ptr=ptr->next;
114     free(oldptr);
115   }
116 }
117
118 void WorkList::pop() {
119   int newoffset=tailoffset+4;
120   struct ListNode *ptr=tail;
121   if (newoffset>=WLISTSIZE) {
122     newoffset-=WLISTSIZE;
123     struct ListNode *oldptr=ptr;
124     ptr=ptr->next;
125     free(oldptr);
126   }
127   tail=ptr;
128   tailoffset=newoffset;
129 }
130
131 void WorkList::add(int id,int type, int lvalue, int rvalue) {
132   if (headoffset==WLISTSIZE) {
133     if (head->next==0) {
134       head->next=(struct ListNode *)malloc(sizeof(struct ListNode));
135       head->next=0;
136     }
137     headoffset=0;
138     head=head->next;
139   }
140   head->data[headoffset++]=id;
141   head->data[headoffset++]=type;
142   head->data[headoffset++]=lvalue;
143   head->data[headoffset++]=rvalue;
144 }
145
146 /* SIMPLE HASH ********************************************************/
147 SimpleIterator* SimpleHash::iterator() {
148   return new SimpleIterator(listhead,listtail,tailindex/*,this*/);
149 }
150
151 void SimpleHash::iterator(SimpleIterator & it) {
152   //  it.table=this;
153   it.cur=listhead;
154   it.index=0;
155   it.tailindex=tailindex;
156   it.tail=listtail;
157 }
158
159 SimpleHash::SimpleHash(int size) {
160     if (size <= 0) {
161         throw SimpleHashException();
162     }
163     this->size = size;
164     this->bucket = (struct SimpleNode **) calloc(sizeof(struct SimpleNode *)*size,1);
165     /* Set allocation blocks*/
166     this->listhead=(struct ArraySimple *) calloc(sizeof(struct ArraySimple),1);
167     this->listtail=this->listhead;
168     this->tailindex=0;
169     /*Set data counts*/
170     this->numparents = 0;
171     this->numchildren = 0;
172     this->numelements = 0;
173 }
174
175 SimpleHash::~SimpleHash() {
176   free(bucket);
177   struct ArraySimple *ptr=listhead;
178   while(ptr) {
179       struct ArraySimple *next=ptr->nextarray;
180       free(ptr);
181       ptr=next;
182   }
183 }
184
185 int SimpleHash::firstkey() {
186   struct ArraySimple *ptr=listhead;
187   int index=0;
188   while((index==ARRAYSIZE)||!ptr->nodes[index].inuse) {
189     if (index==ARRAYSIZE) {
190       index=0;
191       ptr=ptr->nextarray;
192     } else
193       index++;
194   }
195   return ptr->nodes[index].key;
196 }
197
198 void SimpleHash::addParent(SimpleHash* parent) {
199     parents[numparents++] = parent;
200     parent->addChild(this);
201 }
202
203 void SimpleHash::addChild(SimpleHash *child) {
204   children[numchildren++]=child;
205 }
206
207 int SimpleHash::remove(int key, int data) {
208     unsigned int hashkey = (unsigned int)key % size;
209     
210     struct SimpleNode **ptr = &bucket[hashkey];
211
212     for (int i = 0; i < numchildren; i++) {
213       children[i]->remove(key, data);
214     }
215
216     while (*ptr) {
217         if ((*ptr)->key == key && (*ptr)->data == data) {
218           struct SimpleNode *toremove=*ptr;
219           *ptr=(*ptr)->next;
220
221           toremove->inuse=0; /* Marked as unused */
222
223           numelements--;
224           return 1;
225         }
226         ptr = &((*ptr)->next);
227     }
228
229     return 0;
230 }
231
232
233
234 int SimpleHash::add(int key, int data) {
235     unsigned int hashkey = (unsigned int)key % size;
236     
237     struct SimpleNode **ptr = &bucket[hashkey];
238
239     /* check that this key/object pair isn't already here */
240     // TBD can be optimized for set v. relation */
241     while (*ptr) {
242         if ((*ptr)->key == key && (*ptr)->data == data) {
243             return 0;
244         }
245         ptr = &((*ptr)->next);
246     }
247     if (tailindex==ARRAYSIZE) {
248       listtail->nextarray=(struct ArraySimple *) calloc(sizeof(struct ArraySimple),1);
249       tailindex=0;
250       listtail=listtail->nextarray;
251     }
252     
253     *ptr = &listtail->nodes[tailindex++];
254     (*ptr)->key=key;
255     (*ptr)->data=data;
256     (*ptr)->inuse=1;
257
258     numelements++;
259     
260     for (int i = 0; i < numparents; i++) {
261         parents[i]->add(key, data);
262     }
263
264     return 1;
265 }
266
267 bool SimpleHash::contains(int key) {
268     unsigned int hashkey = (unsigned int)key % size;
269     
270     struct SimpleNode *ptr = bucket[hashkey];
271     while (ptr) {
272         if (ptr->key == key) {
273             // we already have this object 
274             // stored in the hash so just return
275             return true;
276         }
277         ptr = ptr->next;
278     }
279     return false;
280 }
281
282 bool SimpleHash::contains(int key, int data) {
283     unsigned int hashkey = (unsigned int)key % size;
284     
285     struct SimpleNode *ptr = bucket[hashkey];
286     while (ptr) {
287         if (ptr->key == key && ptr->data == data) {
288             // we already have this object 
289             // stored in the hash so just return
290             return true;
291         }
292         ptr = ptr->next;
293     }
294     return false;
295 }
296
297 int SimpleHash::count(int key) {
298     unsigned int hashkey = (unsigned int)key % size;
299     int count = 0;
300
301     struct SimpleNode *ptr = bucket[hashkey];
302     while (ptr) {
303         if (ptr->key == key) {
304             count++;
305         }
306         ptr = ptr->next;
307     }
308     return count;
309 }
310
311 int SimpleHash::get(int key, int&data) {
312     unsigned int hashkey = (unsigned int)key % size;
313     
314     struct SimpleNode *ptr = bucket[hashkey];
315     while (ptr) {
316         if (ptr->key == key) {
317             data = ptr->data;
318             return 1; // success
319         }
320         ptr = ptr->next;
321     }
322         
323     return 0; // failure
324 }
325
326 int SimpleHash::countdata(int data) {
327     int count = 0;
328     struct ArraySimple *ptr = listhead;
329     while(ptr) {
330       if (ptr->nextarray) {
331         for(int i=0;i<ARRAYSIZE;i++)
332           if (ptr->nodes[i].data == data
333               &&ptr->nodes[i].inuse) {
334             count++;
335           }
336       } else {
337         for(int i=0;i<tailindex;i++)
338           if (ptr->nodes[i].data == data
339               &&ptr->nodes[i].inuse) {
340             count++;
341           }
342       }
343       ptr = ptr->nextarray;
344     }
345     return count;
346 }
347
348 SimpleHashException::SimpleHashException() {}
349 // ************************************************************
350
351
352 RepairHashNode::RepairHashNode(int setrelation, int rule, int lvalue, int rvalue, int data, int data2, int ismodify){
353     this->setrelation = setrelation;
354     this->lvalue=lvalue;
355     this->rvalue=rvalue;
356     this->data = data;
357     this->data2 = data2;
358     this->next = 0;
359     this->lnext=0;
360     this->rule=rule;
361     this->ismodify=ismodify;
362 }
363
364 // ************************************************************
365
366 RepairHash::RepairHash(int size) {
367     if (size <= 0) {
368         throw SimpleHashException();
369     }
370     this->size = size;
371     this->bucket = new RepairHashNode* [size];
372     for (int i=0;i<size;i++)
373       bucket[i]=0;
374     this->nodelist=0;
375     this->numelements = 0;
376 }
377
378 #define REPAIRSIZE 100
379 RepairHash::RepairHash() {
380     this->size = REPAIRSIZE;
381     this->bucket = new RepairHashNode* [REPAIRSIZE];
382     for (int i=0;i<REPAIRSIZE;i++)
383       bucket[i]=0;
384     this->nodelist=0;
385     this->numelements = 0;
386 }
387
388 RepairHash::~RepairHash() {
389   delete [] this->bucket;
390   RepairHashNode *ptr=nodelist;
391   while(ptr) {
392       RepairHashNode *next=ptr->lnext;
393       delete ptr;
394       ptr=next;
395   }
396 }
397
398 #define SETFLAG (1<<31)
399
400 int RepairHash::addset(int setv, int rule, int value, int data) {
401   return addrelation(setv||SETFLAG, rule, value,0,data);
402 }
403
404 int RepairHash::addrelation(int relation, int rule, int lvalue, int rvalue, int data) {
405     unsigned int hashkey = ((unsigned int)(relation ^ rule ^ lvalue ^ rvalue)) % size;
406     
407     RepairHashNode **ptr = &bucket[hashkey];
408
409     /* check that this key/object pair isn't already here */
410     // TBD can be optimized for set v. relation */
411     while (*ptr) {
412         if ((*ptr)->setrelation == relation && 
413             (*ptr)->rule==rule &&
414             (*ptr)->lvalue==lvalue &&
415             (*ptr)->rvalue==rvalue &&
416             (*ptr)->data == data&&
417             (*ptr)->data2 == 0) {
418             return 0;
419         }
420         ptr = &((*ptr)->next);
421     }
422     
423     *ptr = new RepairHashNode(relation,rule,lvalue,rvalue, data,0,0);
424     (*ptr)->lnext=nodelist;
425     nodelist=*ptr;
426     numelements++;
427     return 1;
428 }
429
430 int RepairHash::addrelation(int relation, int rule, int lvalue, int rvalue, int data, int data2) {
431     unsigned int hashkey = ((unsigned int)(relation ^ rule ^ lvalue ^ rvalue)) % size;
432     
433     RepairHashNode **ptr = &bucket[hashkey];
434
435     /* check that this key/object pair isn't already here */
436     // TBD can be optimized for set v. relation */
437     while (*ptr) {
438         if ((*ptr)->setrelation == relation && 
439             (*ptr)->rule==rule &&
440             (*ptr)->lvalue==lvalue &&
441             (*ptr)->rvalue==rvalue &&
442             (*ptr)->data == data &&
443             (*ptr)->data2 == data2) {
444             return 0;
445         }
446         ptr = &((*ptr)->next);
447     }
448     
449     *ptr = new RepairHashNode(relation,rule,lvalue,rvalue, data,data2,1);
450     (*ptr)->lnext=nodelist;
451     nodelist=*ptr;
452     numelements++;
453     return 1;
454 }
455
456 bool RepairHash::containsset(int setv, int rule, int value) {
457   return containsrelation(setv||SETFLAG, rule, value,0);
458 }
459
460 bool RepairHash::containsrelation(int relation, int rule, int lvalue, int rvalue) {
461     unsigned int hashkey = ((unsigned int)(relation ^ rule ^ lvalue ^ rvalue)) % size;
462     
463     RepairHashNode **ptr = &bucket[hashkey];
464
465     /* check that this key/object pair isn't already here */
466     // TBD can be optimized for set v. relation */
467     while (*ptr) {
468         if ((*ptr)->setrelation == relation && 
469             (*ptr)->rule==rule &&
470             (*ptr)->lvalue==lvalue &&
471             (*ptr)->rvalue==rvalue) {
472             return true;
473         }
474         ptr = &((*ptr)->next);
475     }
476     return false;
477 }
478
479 int RepairHash::getset(int setv, int rule, int value) {
480   return getrelation(setv||SETFLAG, rule, value,0);
481 }
482
483 int RepairHash::ismodify(int relation, int rule, int lvalue,int rvalue) {
484     unsigned int hashkey = ((unsigned int)(relation ^ rule ^ lvalue ^ rvalue)) % size;
485     
486     RepairHashNode **ptr = &bucket[hashkey];
487
488     /* check that this key/object pair isn't already here */
489     // TBD can be optimized for set v. relation */
490     while (*ptr) {
491         if ((*ptr)->setrelation == relation && 
492             (*ptr)->rule==rule &&
493             (*ptr)->lvalue==lvalue &&
494             (*ptr)->rvalue==rvalue) {
495           return (*ptr)->ismodify;
496         }
497         ptr = &((*ptr)->next);
498     }
499     return 0;
500 }
501
502 int RepairHash::getrelation2(int relation, int rule, int lvalue,int rvalue) {
503     unsigned int hashkey = ((unsigned int)(relation ^ rule ^ lvalue ^ rvalue)) % size;
504     
505     RepairHashNode **ptr = &bucket[hashkey];
506
507     /* check that this key/object pair isn't already here */
508     // TBD can be optimized for set v. relation */
509     while (*ptr) {
510         if ((*ptr)->setrelation == relation && 
511             (*ptr)->rule==rule &&
512             (*ptr)->lvalue==lvalue &&
513             (*ptr)->rvalue==rvalue) {
514           return (*ptr)->data2;
515         }
516         ptr = &((*ptr)->next);
517     }
518     return 0;
519 }
520
521 int RepairHash::getrelation(int relation, int rule, int lvalue,int rvalue) {
522     unsigned int hashkey = ((unsigned int)(relation ^ rule ^ lvalue ^ rvalue)) % size;
523     
524     RepairHashNode **ptr = &bucket[hashkey];
525
526     /* check that this key/object pair isn't already here */
527     // TBD can be optimized for set v. relation */
528     while (*ptr) {
529         if ((*ptr)->setrelation == relation && 
530             (*ptr)->rule==rule &&
531             (*ptr)->lvalue==lvalue &&
532             (*ptr)->rvalue==rvalue) {
533           return (*ptr)->data;
534         }
535         ptr = &((*ptr)->next);
536     }
537     return 0;
538 }