3 #include "runtime_arch.h"
11 #define GC_SHIFT_BITS 4
13 /* mgchash ********************************************************/
14 mgchashtable_t * mgchashCreate(unsigned int size, double loadfactor) {
15 mgchashtable_t *ctable;
16 mgchashlistnode_t *nodes;
23 printf("Negative Hashtable size Exception\n");
28 // Allocate space for the hash table
29 ctable = (mgchashtable_t *)RUNMALLOC(sizeof(mgchashtable_t));
31 // Run out of local memory
34 ctable->table = (mgchashlistnode_t*)RUNMALLOC(size*sizeof(mgchashlistnode_t));
35 if(ctable->table == NULL) {
36 // Run out of local memory
39 ctable->loadfactor = loadfactor;
41 ctable->threshold=size*loadfactor;
43 ctable->mask = (size << (GC_SHIFT_BITS))-1;
44 ctable->structs = (mgcliststruct_t*)RUNMALLOC(1*sizeof(mgcliststruct_t));
45 ctable->numelements = 0; // Initial number of elements in the hash
50 void mgchashreset(mgchashtable_t * tbl) {
51 mgchashlistnode_t *ptr = tbl->table;
54 /*if (tbl->numelements<(tbl->size>>6)) {
55 mgchashlistnode_t *top=&ptr[tbl->size];
56 mgchashlistnode_t * list = tbl->list;
58 mgchashlistnode_t * next = list->lnext;
59 if ((list >= ptr) && (list < top)) {
67 BAMBOO_MEMSET_WH(tbl->table, '\0', sizeof(mgchashlistnode_t)*tbl->size);
69 // TODO now never release any allocated memory, may need to be changed
70 while(tbl->structs->next!=NULL) {
71 mgcliststruct_t * next = tbl->structs->next;
72 RUNFREE(tbl->structs);
75 tbl->structs->num = 0;
79 //Store objects and their pointers into hash
80 void mgchashInsert(mgchashtable_t * tbl, void * key, void *val) {
81 mgchashlistnode_t *ptr;
83 if(tbl->numelements > (tbl->threshold)) {
85 unsigned int newsize = tbl->size << 1 + 1;
86 mgchashResize(tbl, newsize);
89 ptr=&tbl->table[(((unsigned INTPTR)key)&tbl->mask)>>(GC_SHIFT_BITS)];
93 // the first time insert a value for the key
96 } else { // Insert in the beginning of linked list
97 mgchashlistnode_t * node;
98 if (tbl->structs->num<NUMMGCLIST) {
99 node=&tbl->structs->array[tbl->structs->num];
103 mgcliststruct_t *tcl=RUNMALLOC(1*sizeof(mgcliststruct_t));
104 tcl->next=tbl->structs;
111 node->next = ptr->next;
117 mgchashtable_t * mgchashCreate_I(unsigned int size, double loadfactor) {
118 mgchashtable_t *ctable;
119 mgchashlistnode_t *nodes;
126 printf("Negative Hashtable size Exception\n");
131 // Allocate space for the hash table
132 ctable = (mgchashtable_t*)RUNMALLOC_I(sizeof(mgchashtable_t));
134 // Run out of local memory
137 ctable->table=(mgchashlistnode_t*)RUNMALLOC_I(size*sizeof(mgchashlistnode_t));
138 if(ctable->table == NULL) {
139 // Run out of local memory
142 ctable->loadfactor = loadfactor;
144 ctable->threshold=size*loadfactor;
146 ctable->mask = (size << (GC_SHIFT_BITS))-1;
147 ctable->structs = (mgcliststruct_t*)RUNMALLOC_I(1*sizeof(mgcliststruct_t));
148 ctable->numelements = 0; // Initial number of elements in the hash
153 void mgchashInsert_I(mgchashtable_t * tbl, void * key, void *val) {
154 mgchashlistnode_t *ptr;
156 if(tbl->numelements > (tbl->threshold)) {
158 unsigned int newsize = tbl->size << 1 + 1;
159 mgchashResize_I(tbl, newsize);
162 ptr = &tbl->table[(((unsigned INTPTR)key)&tbl->mask)>>(GC_SHIFT_BITS)];
169 } else { // Insert in the beginning of linked list
170 mgchashlistnode_t * node;
171 if (tbl->structs->num<NUMMGCLIST) {
172 node=&tbl->structs->array[tbl->structs->num];
176 mgcliststruct_t *tcl=RUNMALLOC_I(1*sizeof(mgcliststruct_t));
177 tcl->next=tbl->structs;
184 node->next = ptr->next;
190 // Search for an address for a given oid
191 INLINE void * mgchashSearch(mgchashtable_t * tbl, void * key) {
192 //REMOVE HASH FUNCTION CALL TO MAKE SURE IT IS INLINED HERE]
193 mgchashlistnode_t *node =
194 &tbl->table[(((unsigned INTPTR)key)&tbl->mask)>>(GC_SHIFT_BITS)];
197 if(node->key == key) {
201 } while(node != NULL);
206 unsigned int mgchashResize(mgchashtable_t * tbl, unsigned int newsize) {
207 mgchashlistnode_t *node, *ptr, *curr; // curr and next keep track of the
208 // current and the next
209 // mgchashlistnodes in a linked list
210 unsigned int oldsize;
211 int isfirst; // Keeps track of the first element in the
212 // chashlistnode_t for each bin in hashtable
213 unsigned int i,index;
219 if((node = RUNMALLOC(newsize*sizeof(mgchashlistnode_t))) == NULL) {
220 printf("Calloc error %s %d\n", __FILE__, __LINE__);
224 tbl->table = node; //Update the global hashtable upon resize()
226 tbl->threshold = newsize * tbl->loadfactor;
227 mask = tbl->mask = (newsize << (GC_SHIFT_BITS)) - 1;
229 for(i = 0; i < oldsize; i++) { //Outer loop for each bin in hash table
232 do { //Inner loop to go through linked lists
234 mgchashlistnode_t *tmp,*next;
236 if ((key=curr->key) == 0) {
237 //Exit inner loop if there the first element is 0
239 //key = val =0 for element if not present within the hash table
241 index = (((unsigned INTPTR)key) & mask) >> (GC_SHIFT_BITS);
244 // Insert into the new table
247 tmp->val = curr->val;
249 NOTE: Add this case if you change this...
250 This case currently never happens because of the way things rehash....*/
252 mgchashlistnode_t *newnode= RUNMALLOC(1*sizeof(mgchashlistnode_t));
253 newnode->key = curr->key;
254 newnode->val = curr->val;
255 newnode->next = tmp->next;
259 curr->next=tmp->next;
268 RUNFREE(ptr); //Free the memory of the old hash table
273 unsigned int mgchashResize_I(mgchashtable_t * tbl, unsigned int newsize) {
274 mgchashlistnode_t *node, *ptr, *curr; // curr and next keep track of the
275 // current and the next
276 // mgchashlistnodes in a linked list
277 unsigned int oldsize;
278 int isfirst; // Keeps track of the first element in the chashlistnode_t
279 // for each bin in hashtable
280 unsigned int i,index;
286 if((node = RUNMALLOC_I(newsize*sizeof(mgchashlistnode_t))) == NULL) {
288 printf("Calloc error %s %d\n", __FILE__, __LINE__);
292 tbl->table = node; //Update the global hashtable upon resize()
294 tbl->threshold = newsize * tbl->loadfactor;
295 mask = tbl->mask = (newsize << (GC_SHIFT_BITS))-1;
297 for(i = 0; i < oldsize; i++) { //Outer loop for each bin in hash table
300 do { //Inner loop to go through linked lists
302 mgchashlistnode_t *tmp,*next;
304 if ((key=curr->key) == 0) {
305 //Exit inner loop if there the first element is 0
307 //key = val =0 for element if not present within the hash table
309 index = (((unsigned INTPTR)key) & mask) >> (GC_SHIFT_BITS);
312 // Insert into the new table
315 tmp->val = curr->val;
317 NOTE: Add this case if you change this...
318 This case currently never happens because of the way things rehash....*/
320 mgchashlistnode_t *newnode=RUNMALLOC_I(1*sizeof(mgchashlistnode_t));
321 newnode->key = curr->key;
322 newnode->val = curr->val;
323 newnode->next = tmp->next;
326 curr->next=tmp->next;
334 RUNFREE_I(ptr); //Free the memory of the old hash table
339 //Delete the entire hash table
340 void mgchashDelete(mgchashtable_t * tbl) {
342 mgcliststruct_t *ptr=tbl->structs;
344 mgcliststruct_t *next=ptr->next;
353 /* MGCHASH ********************************************************/
355 struct MGCHash * allocateMGCHash(int size,
357 struct MGCHash *thisvar;
362 printf("Negative Hashtable size Exception\n");
366 thisvar=(struct MGCHash *)RUNMALLOC(sizeof(struct MGCHash));
367 thisvar->size = size;
369 (struct MGCNode *) RUNMALLOC(sizeof(struct MGCNode)*size);
371 thisvar->num4conflicts = conflicts;
375 void freeMGCHash(struct MGCHash *thisvar) {
377 for(i=thisvar->size-1; i>=0; i--) {
379 for(ptr=thisvar->bucket[i].next; ptr!=NULL; ) {
380 struct MGCNode * nextptr=ptr->next;
385 RUNFREE(thisvar->bucket);
389 int MGCHashadd(struct MGCHash * thisvar, int data) {
391 unsigned int hashkey;
394 int mask = (thisvar->size << (GC_SHIFT_BITS))-1;
395 hashkey = (((unsigned INTPTR)data)&mask)>>(GC_SHIFT_BITS);
396 ptr = &thisvar->bucket[hashkey];
398 struct MGCNode * prev = NULL;
399 if(ptr->data < thisvar->num4conflicts) {
400 struct MGCNode *node=RUNMALLOC(sizeof(struct MGCNode));
402 node->next=(ptr->next);
406 while (ptr->next!=NULL) {
411 ptr->next = thisvar->bucket[hashkey].next;
412 thisvar->bucket[hashkey].next = ptr;
420 struct MGCHash * allocateMGCHash_I(int size,
422 struct MGCHash *thisvar;
427 printf("Negative Hashtable size Exception\n");
431 thisvar=(struct MGCHash *)RUNMALLOC_I(sizeof(struct MGCHash));
432 thisvar->size = size;
434 (struct MGCNode *) RUNMALLOC_I(sizeof(struct MGCNode)*size);
436 thisvar->num4conflicts = conflicts;
440 int MGCHashadd_I(struct MGCHash * thisvar, int data) {
442 unsigned int hashkey;
445 int mask = (thisvar->size << (GC_SHIFT_BITS))-1;
446 hashkey = (((unsigned INTPTR)data)&mask)>>(GC_SHIFT_BITS);
447 ptr = &thisvar->bucket[hashkey];
449 struct MGCNode * prev = NULL;
450 if(ptr->data < thisvar->num4conflicts) {
451 struct MGCNode *node=RUNMALLOC_I(sizeof(struct MGCNode));
453 node->next=(ptr->next);
457 while (ptr->next!=NULL) {
462 ptr->next = thisvar->bucket[hashkey].next;
463 thisvar->bucket[hashkey].next = ptr;
471 int MGCHashcontains(struct MGCHash *thisvar, int data) {
472 int mask = (thisvar->size << (GC_SHIFT_BITS))-1;
473 unsigned int hashkey = (((unsigned INTPTR)data)&mask)>>(GC_SHIFT_BITS);
475 struct MGCNode *ptr = thisvar->bucket[hashkey].next;
476 struct MGCNode *prev = NULL;
478 if (ptr->data == data) {
481 ptr->next = thisvar->bucket[hashkey].next;
482 thisvar->bucket[hashkey].next = ptr;