3 #include "runtime_arch.h"
21 #define GC_SHIFT_BITS 4
23 /* mgchash ********************************************************/
24 mgchashtable_t * mgchashCreate(unsigned int size, double loadfactor) {
25 mgchashtable_t *ctable;
26 mgchashlistnode_t *nodes;
33 printf("Negative Hashtable size Exception\n");
38 // Allocate space for the hash table
39 ctable = (mgchashtable_t *)RUNMALLOC(sizeof(mgchashtable_t));
41 // Run out of local memory
44 ctable->table = (mgchashlistnode_t*)RUNMALLOC(size*sizeof(mgchashlistnode_t));
45 if(ctable->table == NULL) {
46 // Run out of local memory
49 ctable->loadfactor = loadfactor;
51 ctable->threshold=size*loadfactor;
53 ctable->mask = (size << (GC_SHIFT_BITS))-1;
54 //ctable->list = NULL;
55 ctable->structs = (mgcliststruct_t*)RUNMALLOC(1*sizeof(mgcliststruct_t));
56 ctable->numelements = 0; // Initial number of elements in the hash
61 void mgchashreset(mgchashtable_t * tbl) {
62 mgchashlistnode_t *ptr = tbl->table;
65 /*if (tbl->numelements<(tbl->size>>6)) {
66 mgchashlistnode_t *top=&ptr[tbl->size];
67 mgchashlistnode_t * list = tbl->list;
69 mgchashlistnode_t * next = list->lnext;
70 if ((list >= ptr) && (list < top)) {
78 BAMBOO_MEMSET_WH(tbl->table, '\0', sizeof(mgchashlistnode_t)*tbl->size);
80 // TODO now never release any allocated memory, may need to be changed
81 //mgcliststruct_t * next = tbl->structs;
82 while(tbl->structs->next!=NULL) {
83 mgcliststruct_t * next = tbl->structs->next;
84 RUNFREE(tbl->structs);
89 tbl->structs->num = 0;
93 //Store objects and their pointers into hash
94 void mgchashInsert(mgchashtable_t * tbl, void * key, void *val) {
95 mgchashlistnode_t *ptr;
97 if(tbl->numelements > (tbl->threshold)) {
99 unsigned int newsize = tbl->size << 1 + 1;
100 mgchashResize(tbl, newsize);
103 ptr=&tbl->table[(((unsigned INTPTR)key)&tbl->mask)>>(GC_SHIFT_BITS)];
107 // the first time insert a value for the key
110 /*ptr->lnext = tbl->list;
112 } else { // Insert in the beginning of linked list
113 mgchashlistnode_t * node;
114 if (tbl->structs->num<NUMMGCLIST) {
115 node=&tbl->structs->array[tbl->structs->num];
119 mgcliststruct_t *tcl=RUNMALLOC(1*sizeof(mgcliststruct_t));
120 tcl->next=tbl->structs;
127 node->next = ptr->next;
129 /*node->lnext = tbl->list;
135 mgchashtable_t * mgchashCreate_I(unsigned int size, double loadfactor) {
136 mgchashtable_t *ctable;
137 mgchashlistnode_t *nodes;
144 printf("Negative Hashtable size Exception\n");
149 // Allocate space for the hash table
150 ctable = (mgchashtable_t*)RUNMALLOC_I(sizeof(mgchashtable_t));
152 // Run out of local memory
155 ctable->table=(mgchashlistnode_t*)RUNMALLOC_I(size*sizeof(mgchashlistnode_t));
156 if(ctable->table == NULL) {
157 // Run out of local memory
160 ctable->loadfactor = loadfactor;
162 ctable->threshold=size*loadfactor;
164 ctable->mask = (size << (GC_SHIFT_BITS))-1;
165 //ctable->list = NULL;
166 ctable->structs = (mgcliststruct_t*)RUNMALLOC_I(1*sizeof(mgcliststruct_t));
167 ctable->numelements = 0; // Initial number of elements in the hash
172 void mgchashInsert_I(mgchashtable_t * tbl, void * key, void *val) {
173 mgchashlistnode_t *ptr;
175 if(tbl->numelements > (tbl->threshold)) {
177 unsigned int newsize = tbl->size << 1 + 1;
178 mgchashResize_I(tbl, newsize);
181 ptr = &tbl->table[(((unsigned INTPTR)key)&tbl->mask)>>(GC_SHIFT_BITS)];
187 /*ptr->lnext = tbl->list;
190 } else { // Insert in the beginning of linked list
191 mgchashlistnode_t * node;
192 if (tbl->structs->num<NUMMGCLIST) {
193 node=&tbl->structs->array[tbl->structs->num];
197 mgcliststruct_t *tcl=RUNMALLOC_I(1*sizeof(mgcliststruct_t));
198 tcl->next=tbl->structs;
205 node->next = ptr->next;
207 /*node->lnext = tbl->list;
213 // Search for an address for a given oid
214 INLINE void * mgchashSearch(mgchashtable_t * tbl, void * key) {
215 //REMOVE HASH FUNCTION CALL TO MAKE SURE IT IS INLINED HERE]
216 mgchashlistnode_t *node =
217 &tbl->table[(((unsigned INTPTR)key)&tbl->mask)>>(GC_SHIFT_BITS)];
220 if(node->key == key) {
224 } while(node != NULL);
229 unsigned int mgchashResize(mgchashtable_t * tbl, unsigned int newsize) {
230 mgchashlistnode_t *node, *ptr, *curr; // curr and next keep track of the
231 // current and the next
232 // mgchashlistnodes in a linked list
233 unsigned int oldsize;
234 int isfirst; // Keeps track of the first element in the
235 // chashlistnode_t for each bin in hashtable
236 unsigned int i,index;
242 if((node = RUNMALLOC(newsize*sizeof(mgchashlistnode_t))) == NULL) {
243 printf("Calloc error %s %d\n", __FILE__, __LINE__);
247 tbl->table = node; //Update the global hashtable upon resize()
249 tbl->threshold = newsize * tbl->loadfactor;
250 mask = tbl->mask = (newsize << (GC_SHIFT_BITS)) - 1;
253 for(i = 0; i < oldsize; i++) { //Outer loop for each bin in hash table
256 do { //Inner loop to go through linked lists
258 mgchashlistnode_t *tmp,*next;
260 if ((key=curr->key) == 0) {
261 //Exit inner loop if there the first element is 0
263 //key = val =0 for element if not present within the hash table
265 index = (((unsigned INTPTR)key) & mask) >> (GC_SHIFT_BITS);
268 // Insert into the new table
271 tmp->val = curr->val;
272 /*tmp->lnext = tbl->list;
275 NOTE: Add this case if you change this...
276 This case currently never happens because of the way things rehash....*/
278 mgchashlistnode_t *newnode= RUNMALLOC(1*sizeof(mgchashlistnode_t));
279 newnode->key = curr->key;
280 newnode->val = curr->val;
281 newnode->next = tmp->next;
283 /*newnode->lnext = tbl->list;
284 tbl->list = newnode;*/
287 curr->next=tmp->next;
289 /*curr->lnext = tbl->list;
298 RUNFREE(ptr); //Free the memory of the old hash table
303 unsigned int mgchashResize_I(mgchashtable_t * tbl, unsigned int newsize) {
304 mgchashlistnode_t *node, *ptr, *curr; // curr and next keep track of the
305 // current and the next
306 // mgchashlistnodes in a linked list
307 unsigned int oldsize;
308 int isfirst; // Keeps track of the first element in the chashlistnode_t
309 // for each bin in hashtable
310 unsigned int i,index;
316 if((node = RUNMALLOC_I(newsize*sizeof(mgchashlistnode_t))) == NULL) {
318 printf("Calloc error %s %d\n", __FILE__, __LINE__);
322 tbl->table = node; //Update the global hashtable upon resize()
324 tbl->threshold = newsize * tbl->loadfactor;
325 mask = tbl->mask = (newsize << (GC_SHIFT_BITS))-1;
328 for(i = 0; i < oldsize; i++) { //Outer loop for each bin in hash table
331 do { //Inner loop to go through linked lists
333 mgchashlistnode_t *tmp,*next;
335 if ((key=curr->key) == 0) {
336 //Exit inner loop if there the first element is 0
338 //key = val =0 for element if not present within the hash table
340 index = (((unsigned INTPTR)key) & mask) >> (GC_SHIFT_BITS);
343 // Insert into the new table
346 tmp->val = curr->val;
347 /*tmp->lnext = tbl->list;
350 NOTE: Add this case if you change this...
351 This case currently never happens because of the way things rehash....*/
353 mgchashlistnode_t *newnode=RUNMALLOC_I(1*sizeof(mgchashlistnode_t));
354 newnode->key = curr->key;
355 newnode->val = curr->val;
356 newnode->next = tmp->next;
358 /*newnode->lnext = tbl->list;
359 tbl->list = newnode;*/
361 curr->next=tmp->next;
363 /*curr->lnext = tbl->list;
371 RUNFREE(ptr); //Free the memory of the old hash table
376 //Delete the entire hash table
377 void mgchashDelete(mgchashtable_t * tbl) {
379 mgcliststruct_t *ptr=tbl->structs;
381 mgcliststruct_t *next=ptr->next;
390 /* MGCHASH ********************************************************/
392 struct MGCHash * allocateMGCHash(int size,
394 struct MGCHash *thisvar;
399 printf("Negative Hashtable size Exception\n");
403 thisvar=(struct MGCHash *)RUNMALLOC(sizeof(struct MGCHash));
404 thisvar->size = size;
406 (struct MGCNode *) RUNMALLOC(sizeof(struct MGCNode)*size);
408 thisvar->num4conflicts = conflicts;
412 void freeMGCHash(struct MGCHash *thisvar) {
414 for(i=thisvar->size-1; i>=0; i--) {
416 for(ptr=thisvar->bucket[i].next; ptr!=NULL; ) {
417 struct MGCNode * nextptr=ptr->next;
422 RUNFREE(thisvar->bucket);
426 int MGCHashadd(struct MGCHash * thisvar, int data) {
428 unsigned int hashkey;
431 int mask = (thisvar->size << (GC_SHIFT_BITS))-1;
432 hashkey = (((unsigned INTPTR)data)&mask)>>(GC_SHIFT_BITS);
433 //hashkey = (unsigned int)data % thisvar->size;
434 ptr = &thisvar->bucket[hashkey];
436 struct MGCNode * prev = NULL;
437 if(ptr->data < thisvar->num4conflicts) {
438 struct MGCNode *node=RUNMALLOC(sizeof(struct MGCNode));
440 node->next=(ptr->next);
444 while (ptr->next!=NULL) {
449 ptr->next = thisvar->bucket[hashkey].next;
450 thisvar->bucket[hashkey].next = ptr;
458 struct MGCHash * allocateMGCHash_I(int size,
460 struct MGCHash *thisvar;
465 printf("Negative Hashtable size Exception\n");
469 thisvar=(struct MGCHash *)RUNMALLOC_I(sizeof(struct MGCHash));
470 thisvar->size = size;
472 (struct MGCNode *) RUNMALLOC_I(sizeof(struct MGCNode)*size);
474 thisvar->num4conflicts = conflicts;
478 int MGCHashadd_I(struct MGCHash * thisvar, int data) {
480 unsigned int hashkey;
483 int mask = (thisvar->size << (GC_SHIFT_BITS))-1;
484 hashkey = (((unsigned INTPTR)data)&mask)>>(GC_SHIFT_BITS);
485 //hashkey = (unsigned int)data % thisvar->size;
486 ptr = &thisvar->bucket[hashkey];
488 struct MGCNode * prev = NULL;
489 if(ptr->data < thisvar->num4conflicts) {
490 struct MGCNode *node=RUNMALLOC_I(sizeof(struct MGCNode));
492 node->next=(ptr->next);
496 while (ptr->next!=NULL) {
501 ptr->next = thisvar->bucket[hashkey].next;
502 thisvar->bucket[hashkey].next = ptr;
510 int MGCHashcontains(struct MGCHash *thisvar, int data) {
511 int mask = (thisvar->size << (GC_SHIFT_BITS))-1;
512 unsigned int hashkey = (((unsigned INTPTR)data)&mask)>>(GC_SHIFT_BITS);
513 //unsigned int hashkey = (unsigned int)data % thisvar->size;
515 struct MGCNode *ptr = thisvar->bucket[hashkey].next;
516 struct MGCNode *prev = NULL;
518 if (ptr->data == data) {
521 ptr->next = thisvar->bucket[hashkey].next;
522 thisvar->bucket[hashkey].next = ptr;