add new features...they don't break the build, but need to check if they work...
[IRC.git] / Robust / src / Runtime / STM / stmlookup.c
1 #include "stmlookup.h"
2 #include "strings.h"
3
4 __thread chashlistnode_t *c_table;
5 __thread chashlistnode_t *c_list;
6 __thread unsigned int c_size;
7 __thread unsigned INTPTR c_mask;
8 __thread unsigned int c_numelements;
9 __thread unsigned int c_threshold;
10 __thread double c_loadfactor;
11 __thread cliststruct_t *c_structs;
12
13 #ifdef READSET
14 __thread rdchashlistnode_t *rd_c_table;
15 __thread rdchashlistnode_t *rd_c_list;
16 __thread unsigned int rd_c_size;
17 __thread unsigned INTPTR rd_c_mask;
18 __thread unsigned int rd_c_numelements;
19 __thread unsigned int rd_c_threshold;
20 __thread double rd_c_loadfactor;
21 __thread rdcliststruct_t *rd_c_structs;
22
23 void rd_t_chashCreate(unsigned int size, double loadfactor) {
24   chashtable_t *ctable;
25   chashlistnode_t *nodes;
26   int i;
27
28   // Allocate space for the hash table
29   rd_c_table = calloc(size, sizeof(rdchashlistnode_t));
30   rd_c_loadfactor = loadfactor;
31   rd_c_size = size;
32   rd_c_threshold=size*loadfactor;
33   rd_c_mask = (size << 4)-1;
34   rd_c_structs=calloc(1, sizeof(rdcliststruct_t));
35   rd_c_numelements = 0; // Initial number of elements in the hash
36   rd_c_list=NULL;
37 }
38
39 void rd_t_chashreset() {
40   rdchashlistnode_t *ptr = rd_c_table;
41   int i;
42
43   if (rd_c_numelements<(rd_c_size>>4)) {
44     rdchashlistnode_t *top=&ptr[rd_c_size];
45     rdchashlistnode_t *tmpptr=rd_c_list;
46     while(tmpptr!=NULL) {
47       rdchashlistnode_t *next=tmpptr->lnext;
48       if (tmpptr>=ptr&&tmpptr<top) {
49         //zero in list
50         tmpptr->key=NULL;
51         tmpptr->next=NULL;
52       }
53       tmpptr=next;
54     }
55   } else {
56     bzero(rd_c_table, sizeof(rdchashlistnode_t)*rd_c_size);
57   }
58   while(rd_c_structs->next!=NULL) {
59     rdcliststruct_t *next=rd_c_structs->next;
60     free(rd_c_structs);
61     rd_c_structs=next;
62   }
63   rd_c_structs->num = 0;
64   rd_c_numelements = 0;
65   rd_c_list=NULL;
66 }
67
68 //Store objects and their pointers into hash
69 void rd_t_chashInsertOnce(void * key, unsigned int version) {
70   rdchashlistnode_t *ptr;
71
72   if (key==NULL)
73     return;
74
75   if(rd_c_numelements > (rd_c_threshold)) {
76     //Resize
77     unsigned int newsize = rd_c_size << 1;
78     rd_t_chashResize(newsize);
79   }
80
81   ptr = &rd_c_table[(((unsigned INTPTR)key)&rd_c_mask)>>4];
82
83   if(ptr->key==0) {
84     ptr->key=key;
85     ptr->version=version;
86     ptr->lnext=rd_c_list;
87     rd_c_list=ptr;
88     rd_c_numelements++;
89   } else { // Insert in the beginning of linked list
90     rdchashlistnode_t * node;
91     rdchashlistnode_t *search=ptr;
92     
93     //make sure it isn't here
94     do {
95       if(search->key == key) {
96         return;
97       }
98       search=search->next;
99     } while(search != NULL);
100
101     rd_c_numelements++;    
102     if (rd_c_structs->num<NUMCLIST) {
103       node=&rd_c_structs->array[rd_c_structs->num];
104       rd_c_structs->num++;
105     } else {
106       //get new list
107       rdcliststruct_t *tcl=calloc(1,sizeof(rdcliststruct_t));
108       tcl->next=rd_c_structs;
109       rd_c_structs=tcl;
110       node=&tcl->array[0];
111       tcl->num=1;
112     }
113     node->key = key;
114     node->version = version;
115     node->next = ptr->next;
116     ptr->next=node;
117     node->lnext=rd_c_list;
118     rd_c_list=node;
119   }
120 }
121
122 unsigned int rd_t_chashResize(unsigned int newsize) {
123   rdchashlistnode_t *node, *ptr, *curr;    // curr and next keep track of the current and the next chashlistnodes in a linked list
124   unsigned int oldsize;
125   int isfirst;    // Keeps track of the first element in the chashlistnode_t for each bin in hashtable
126   unsigned int i,index;
127   unsigned int mask;
128
129   ptr = rd_c_table;
130   oldsize = rd_c_size;
131   rd_c_list=NULL;
132
133   if((node = calloc(newsize, sizeof(rdchashlistnode_t))) == NULL) {
134     printf("Calloc error %s %d\n", __FILE__, __LINE__);
135     return 1;
136   }
137
138   rd_c_table = node;          //Update the global hashtable upon resize()
139   rd_c_size = newsize;
140   rd_c_threshold = newsize * rd_c_loadfactor;
141   mask=rd_c_mask = (newsize << 4)-1;
142
143   for(i = 0; i < oldsize; i++) {                        //Outer loop for each bin in hash table
144     curr = &ptr[i];
145     isfirst = 1;
146     do {                      //Inner loop to go through linked lists
147       void * key;
148       rdchashlistnode_t *tmp,*next;
149
150       if ((key=curr->key) == 0) {             //Exit inner loop if there the first element is 0
151         break;                  //key = val =0 for element if not present within the hash table
152       }
153       index = (((unsigned INTPTR)key) & mask) >>4;
154       tmp=&node[index];
155       next = curr->next;
156       // Insert into the new table
157       if(tmp->key == 0) {
158         tmp->key = key;
159         tmp->version = curr->version;
160         tmp->lnext=rd_c_list;
161         rd_c_list=tmp;
162       } /*
163           NOTE:  Add this case if you change this...
164           This case currently never happens because of the way things rehash....
165           else if (isfirst) {
166           chashlistnode_t *newnode= calloc(1, sizeof(chashlistnode_t));
167           newnode->key = curr->key;
168           newnode->val = curr->val;
169           newnode->next = tmp->next;
170           tmp->next=newnode;
171           } */
172       else {
173         curr->next=tmp->next;
174         tmp->next=curr;
175         curr->lnext=rd_c_list;
176         rd_c_list=curr;
177       }
178
179       isfirst = 0;
180       curr = next;
181     } while(curr!=NULL);
182   }
183
184   free(ptr);            //Free the memory of the old hash table
185   return 0;
186 }
187
188 //Delete the entire hash table
189 void rd_t_chashDelete() {
190   int i;
191   rdcliststruct_t *ptr=rd_c_structs;
192   while(ptr!=NULL) {
193     rdcliststruct_t *next=ptr->next;
194     free(ptr);
195     ptr=next;
196   }
197   free(rd_c_table);
198   rd_c_table=NULL;
199   rd_c_structs=NULL;
200   rd_c_list=NULL;
201 }
202 #endif
203
204 #ifdef DELAYCOMP
205 __thread dchashlistnode_t *dc_c_table;
206 __thread dchashlistnode_t *dc_c_list;
207 __thread unsigned int dc_c_size;
208 __thread unsigned INTPTR dc_c_mask;
209 __thread unsigned int dc_c_numelements;
210 __thread unsigned int dc_c_threshold;
211 __thread double dc_c_loadfactor;
212 __thread dcliststruct_t *dc_c_structs;
213
214 void dc_t_chashCreate(unsigned int size, double loadfactor) {
215   dchashlistnode_t *nodes;
216   int i;
217
218   // Allocate space for the hash table
219
220   dc_c_table = calloc(size, sizeof(dchashlistnode_t));
221   dc_c_loadfactor = loadfactor;
222   dc_c_size = size;
223   dc_c_threshold=size*loadfactor;
224   dc_c_mask = (size << 4)-1;
225   dc_c_structs=calloc(1, sizeof(dcliststruct_t));
226   dc_c_numelements = 0; // Initial number of elements in the hash
227   dc_c_list=NULL;
228 }
229
230 void dc_t_chashreset() {
231   dchashlistnode_t *ptr = dc_c_table;
232   int i;
233
234   if (dc_c_numelements<(dc_c_size>>4)) {
235     dchashlistnode_t *top=&ptr[dc_c_size];
236     dchashlistnode_t *tmpptr=dc_c_list;
237     while(tmpptr!=NULL) {
238       dchashlistnode_t *next=tmpptr->lnext;
239       if (tmpptr>=ptr&&tmpptr<top) {
240         //zero in list
241         tmpptr->key=NULL;
242         tmpptr->next=NULL;
243       }
244       tmpptr=next;
245     }
246   } else {
247     bzero(dc_c_table, sizeof(dchashlistnode_t)*dc_c_size);
248   }
249   while(dc_c_structs->next!=NULL) {
250     dcliststruct_t *next=dc_c_structs->next;
251     free(dc_c_structs);
252     dc_c_structs=next;
253   }
254   dc_c_structs->num = 0;
255   dc_c_numelements = 0;
256   dc_c_list=NULL;
257 }
258
259 //Store objects and their pointers into hash
260 void dc_t_chashInsertOnce(void * key, void *val) {
261   dchashlistnode_t *ptr;
262
263   if (key==NULL)
264     return;
265
266   if(dc_c_numelements > (dc_c_threshold)) {
267     //Resize
268     unsigned int newsize = dc_c_size << 1;
269     dc_t_chashResize(newsize);
270   }
271
272   ptr = &dc_c_table[(((unsigned INTPTR)key)&dc_c_mask)>>4];
273
274   if(ptr->key==0) {
275     ptr->key=key;
276     ptr->val=val;
277     ptr->lnext=dc_c_list;
278     dc_c_list=ptr;
279     dc_c_numelements++;
280   } else { // Insert in the beginning of linked list
281     dchashlistnode_t * node;
282     dchashlistnode_t *search=ptr;
283     
284     //make sure it isn't here
285     do {
286       if(search->key == key) {
287         return;
288       }
289       search=search->next;
290     } while(search != NULL);
291
292     dc_c_numelements++;    
293     if (dc_c_structs->num<NUMCLIST) {
294       node=&dc_c_structs->array[dc_c_structs->num];
295       dc_c_structs->num++;
296     } else {
297       //get new list
298       dcliststruct_t *tcl=calloc(1,sizeof(dcliststruct_t));
299       tcl->next=dc_c_structs;
300       dc_c_structs=tcl;
301       node=&tcl->array[0];
302       tcl->num=1;
303     }
304     node->key = key;
305     node->val = val;
306     node->next = ptr->next;
307     ptr->next=node;
308     node->lnext=dc_c_list;
309     dc_c_list=node;
310   }
311 }
312
313 #ifdef STMARRAY
314 //Store objects and their pointers into hash
315 void dc_t_chashInsertOnceArray(void * key, unsigned int intkey, void *val) {
316   dchashlistnode_t *ptr;
317
318   if (key==NULL)
319     return;
320
321   if(dc_c_numelements > (dc_c_threshold)) {
322     //Resize
323     unsigned int newsize = dc_c_size << 1;
324     dc_t_chashResize(newsize);
325   }
326
327   ptr = &dc_c_table[(((unsigned INTPTR)key^intkey)&dc_c_mask)>>4];
328
329   if(ptr->key==0) {
330     ptr->key=key;
331     ptr->intkey=intkey;
332     ptr->val=val;
333     ptr->lnext=dc_c_list;
334     dc_c_list=ptr;
335     dc_c_numelements++;
336   } else { // Insert in the beginning of linked list
337     dchashlistnode_t * node;
338     dchashlistnode_t *search=ptr;
339     
340     //make sure it isn't here
341     do {
342       if(search->key == key&&search->intkey==intkey) {
343         return;
344       }
345       search=search->next;
346     } while(search != NULL);
347
348     dc_c_numelements++;
349     if (dc_c_structs->num<NUMCLIST) {
350       node=&dc_c_structs->array[dc_c_structs->num];
351       dc_c_structs->num++;
352     } else {
353       //get new list
354       dcliststruct_t *tcl=calloc(1,sizeof(dcliststruct_t));
355       tcl->next=dc_c_structs;
356       dc_c_structs=tcl;
357       node=&tcl->array[0];
358       tcl->num=1;
359     }
360     node->key = key;
361     node->intkey = intkey;
362     node->val = val;
363     node->next = ptr->next;
364     ptr->next=node;
365     node->lnext=dc_c_list;
366     dc_c_list=node;
367   }
368 }
369 #endif
370
371 #ifdef STMARRAY
372 //Store objects and their pointers into hash
373 void dc_t_chashInsertOnce(void * key, unsigned int indexkey, void *val) {
374   chashlistnode_t *ptr;
375
376   if (key==NULL)
377     return;
378
379   if(dc_c_numelements > (dc_c_threshold)) {
380     //Resize
381     unsigned int newsize = dc_c_size << 1;
382     dc_t_chashResize(newsize);
383   }
384
385   ptr = &dc_c_table[(((unsigned INTPTR)key)&dc_c_mask)>>4];
386
387   if(ptr->key==0) {
388     ptr->key=key;
389     ptr->val=val;
390     ptr->lnext=dc_c_list;
391     dc_c_list=ptr;
392     dc_c_numelements++;
393   } else { // Insert in the beginning of linked list
394     chashlistnode_t * node;
395     chashlistnode_t *search=ptr;
396     
397     //make sure it isn't here
398     do {
399       if(search->key == key) {
400         return;
401       }
402       search=search->next;
403     } while(search != NULL);
404
405     dc_c_numelements++;    
406     if (dc_c_structs->num<NUMCLIST) {
407       node=&dc_c_structs->array[dc_c_structs->num];
408       dc_c_structs->num++;
409     } else {
410       //get new list
411       cliststruct_t *tcl=calloc(1,sizeof(cliststruct_t));
412       tcl->next=dc_c_structs;
413       dc_c_structs=tcl;
414       node=&tcl->array[0];
415       tcl->num=1;
416     }
417     node->key = key;
418     node->val = val;
419     node->next = ptr->next;
420     ptr->next=node;
421     node->lnext=dc_c_list;
422     dc_c_list=node;
423   }
424 }
425 #endif
426
427 unsigned int dc_t_chashResize(unsigned int newsize) {
428   dchashlistnode_t *node, *ptr, *curr;    // curr and next keep track of the current and the next chashlistnodes in a linked list
429   unsigned int oldsize;
430   int isfirst;    // Keeps track of the first element in the chashlistnode_t for each bin in hashtable
431   unsigned int i,index;
432   unsigned int mask;
433
434   ptr = dc_c_table;
435   oldsize = dc_c_size;
436   dc_c_list=NULL;
437
438   if((node = calloc(newsize, sizeof(dchashlistnode_t))) == NULL) {
439     printf("Calloc error %s %d\n", __FILE__, __LINE__);
440     return 1;
441   }
442
443   dc_c_table = node;          //Update the global hashtable upon resize()
444   dc_c_size = newsize;
445   dc_c_threshold = newsize * dc_c_loadfactor;
446   mask=dc_c_mask = (newsize << 4)-1;
447
448   for(i = 0; i < oldsize; i++) {                        //Outer loop for each bin in hash table
449     curr = &ptr[i];
450     isfirst = 1;
451     do {                      //Inner loop to go through linked lists
452       void * key;
453 #ifdef STMARRAY
454       unsigned int intkey;
455 #endif
456       dchashlistnode_t *tmp,*next;
457
458       if ((key=curr->key) == 0) {             //Exit inner loop if there the first element is 0
459         break;                  //key = val =0 for element if not present within the hash table
460       }
461 #ifdef STMARRAY
462       intkey=curr->intkey;
463       index = (((unsigned INTPTR)key^intkey) & mask) >>4;
464 #else
465       index = (((unsigned INTPTR)key) & mask) >>4;
466 #endif
467       tmp=&node[index];
468       next = curr->next;
469       // Insert into the new table
470       if(tmp->key == 0) {
471         tmp->key = key;
472 #ifdef STMARRAY
473         tmp->intkey = intkey;
474 #endif
475         tmp->val = curr->val;
476         tmp->lnext=dc_c_list;
477         dc_c_list=tmp;
478       } /*
479           NOTE:  Add this case if you change this...
480           This case currently never happens because of the way things rehash....
481           else if (isfirst) {
482           chashlistnode_t *newnode= calloc(1, sizeof(chashlistnode_t));
483           newnode->key = curr->key;
484           newnode->val = curr->val;
485           newnode->next = tmp->next;
486           tmp->next=newnode;
487           } */
488       else {
489         curr->next=tmp->next;
490         tmp->next=curr;
491         curr->lnext=dc_c_list;
492         dc_c_list=curr;
493       }
494
495       isfirst = 0;
496       curr = next;
497     } while(curr!=NULL);
498   }
499
500   free(ptr);            //Free the memory of the old hash table
501   return 0;
502 }
503
504 //Delete the entire hash table
505 void dc_t_chashDelete() {
506   int i;
507   dcliststruct_t *ptr=dc_c_structs;
508   while(ptr!=NULL) {
509     dcliststruct_t *next=ptr->next;
510     free(ptr);
511     ptr=next;
512   }
513   free(dc_c_table);
514   dc_c_table=NULL;
515   dc_c_structs=NULL;
516   dc_c_list=NULL;
517 }
518
519 // Search for an address for a given oid
520 INLINE void * dc_t_chashSearch(void * key) {
521   //REMOVE HASH FUNCTION CALL TO MAKE SURE IT IS INLINED HERE
522   dchashlistnode_t *node = &dc_c_table[(((unsigned INTPTR)key) & dc_c_mask)>>4];
523   
524   do {
525     if(node->key == key) {
526       return node->val;
527     }
528     node = node->next;
529   } while(node != NULL);
530
531   return NULL;
532 }
533
534 #ifdef STMARRAY
535 // Search for an address for a given oid
536 INLINE void * dc_t_chashSearchArray(void * key, unsigned int intkey) {
537   //REMOVE HASH FUNCTION CALL TO MAKE SURE IT IS INLINED HERE
538   dchashlistnode_t *node = &dc_c_table[(((unsigned INTPTR)key^intkey) & dc_c_mask)>>4];
539   
540   do {
541     if(node->key == key && node->intkey==intkey) {
542       return node->val;
543     }
544     node = node->next;
545   } while(node != NULL);
546
547   return NULL;
548 }
549 #endif
550
551 #endif
552
553 void t_chashCreate(unsigned int size, double loadfactor) {
554   chashtable_t *ctable;
555   chashlistnode_t *nodes;
556   int i;
557
558   // Allocate space for the hash table
559
560
561   c_table = calloc(size, sizeof(chashlistnode_t));
562   c_loadfactor = loadfactor;
563   c_size = size;
564   c_threshold=size*loadfactor;
565   c_mask = (size << 4)-1;
566   c_structs=calloc(1, sizeof(cliststruct_t));
567   c_numelements = 0; // Initial number of elements in the hash
568   c_list=NULL;
569 }
570
571 void t_chashreset() {
572   chashlistnode_t *ptr = c_table;
573   int i;
574
575   if (c_numelements<(c_size>>4)) {
576     chashlistnode_t *top=&ptr[c_size];
577     chashlistnode_t *tmpptr=c_list;
578     while(tmpptr!=NULL) {
579       chashlistnode_t *next=tmpptr->lnext;
580       if (tmpptr>=ptr&&tmpptr<top) {
581         //zero in list
582         tmpptr->key=NULL;
583         tmpptr->next=NULL;
584       }
585       tmpptr=next;
586     }
587   } else {
588     bzero(c_table, sizeof(chashlistnode_t)*c_size);
589   }
590   while(c_structs->next!=NULL) {
591     cliststruct_t *next=c_structs->next;
592     free(c_structs);
593     c_structs=next;
594   }
595   c_structs->num = 0;
596   c_numelements = 0;
597   c_list=NULL;
598 }
599
600 //Store objects and their pointers into hash
601 void t_chashInsert(void * key, void *val) {
602   chashlistnode_t *ptr;
603
604
605   if(c_numelements > (c_threshold)) {
606     //Resize
607     unsigned int newsize = c_size << 1;
608     t_chashResize(newsize);
609   }
610
611   ptr = &c_table[(((unsigned INTPTR)key)&c_mask)>>4];
612   c_numelements++;
613
614   if(ptr->key==0) {
615     ptr->key=key;
616     ptr->val=val;
617     ptr->lnext=c_list;
618     c_list=ptr;
619   } else { // Insert in the beginning of linked list
620     chashlistnode_t * node;
621     if (c_structs->num<NUMCLIST) {
622       node=&c_structs->array[c_structs->num];
623       c_structs->num++;
624     } else {
625       //get new list
626       cliststruct_t *tcl=calloc(1,sizeof(cliststruct_t));
627       tcl->next=c_structs;
628       c_structs=tcl;
629       node=&tcl->array[0];
630       tcl->num=1;
631     }
632     node->key = key;
633     node->val = val;
634     node->next = ptr->next;
635     ptr->next=node;
636     node->lnext=c_list;
637     c_list=node;
638   }
639 }
640
641 // Search for an address for a given oid
642 INLINE void * t_chashSearch(void * key) {
643   //REMOVE HASH FUNCTION CALL TO MAKE SURE IT IS INLINED HERE
644   chashlistnode_t *node = &c_table[(((unsigned INTPTR)key) & c_mask)>>4];
645
646   do {
647     if(node->key == key) {
648       return node->val;
649     }
650     node = node->next;
651   } while(node != NULL);
652
653   return NULL;
654 }
655
656 unsigned int t_chashResize(unsigned int newsize) {
657   chashlistnode_t *node, *ptr, *curr;    // curr and next keep track of the current and the next chashlistnodes in a linked list
658   unsigned int oldsize;
659   int isfirst;    // Keeps track of the first element in the chashlistnode_t for each bin in hashtable
660   unsigned int i,index;
661   unsigned int mask;
662
663   ptr = c_table;
664   oldsize = c_size;
665   c_list=NULL;
666
667   if((node = calloc(newsize, sizeof(chashlistnode_t))) == NULL) {
668     printf("Calloc error %s %d\n", __FILE__, __LINE__);
669     return 1;
670   }
671
672   c_table = node;          //Update the global hashtable upon resize()
673   c_size = newsize;
674   c_threshold = newsize * c_loadfactor;
675   mask=c_mask = (newsize << 4)-1;
676
677   for(i = 0; i < oldsize; i++) {                        //Outer loop for each bin in hash table
678     curr = &ptr[i];
679     isfirst = 1;
680     do {                      //Inner loop to go through linked lists
681       void * key;
682       chashlistnode_t *tmp,*next;
683
684       if ((key=curr->key) == 0) {             //Exit inner loop if there the first element is 0
685         break;                  //key = val =0 for element if not present within the hash table
686       }
687       index = (((unsigned INTPTR)key) & mask) >>4;
688       tmp=&node[index];
689       next = curr->next;
690       // Insert into the new table
691       if(tmp->key == 0) {
692         tmp->key = key;
693         tmp->val = curr->val;
694         tmp->lnext=c_list;
695         c_list=tmp;
696       } /*
697           NOTE:  Add this case if you change this...
698           This case currently never happens because of the way things rehash....
699           else if (isfirst) {
700           chashlistnode_t *newnode= calloc(1, sizeof(chashlistnode_t));
701           newnode->key = curr->key;
702           newnode->val = curr->val;
703           newnode->next = tmp->next;
704           tmp->next=newnode;
705           } */
706       else {
707         curr->next=tmp->next;
708         tmp->next=curr;
709         curr->lnext=c_list;
710         c_list=curr;
711       }
712
713       isfirst = 0;
714       curr = next;
715     } while(curr!=NULL);
716   }
717
718   free(ptr);            //Free the memory of the old hash table
719   return 0;
720 }
721
722 //Delete the entire hash table
723 void t_chashDelete() {
724   int i;
725   cliststruct_t *ptr=c_structs;
726   while(ptr!=NULL) {
727     cliststruct_t *next=ptr->next;
728     free(ptr);
729     ptr=next;
730   }
731   free(c_table);
732   c_table=NULL;
733   c_structs=NULL;
734   c_list=NULL;
735 }