3 #include "runtime_arch.h"
22 /* mgchash ********************************************************/
23 mgchashtable_t * mgchashCreate(unsigned int size, double loadfactor) {
24 mgchashtable_t *ctable;
25 mgchashlistnode_t *nodes;
32 printf("Negative Hashtable size Exception\n");
37 // Allocate space for the hash table
38 ctable = (mgchashtable_t *)RUNMALLOC(sizeof(mgchashtable_t));
40 // Run out of local memory
43 ctable->table = (mgchashlistnode_t*)RUNMALLOC(size*sizeof(mgchashlistnode_t));
44 if(ctable->table == NULL) {
45 // Run out of local memory
48 ctable->loadfactor = loadfactor;
50 ctable->threshold=size*loadfactor;
52 ctable->mask = (size << 6)-1;
53 //ctable->list = NULL;
54 ctable->structs = (mgcliststruct_t*)RUNMALLOC(1*sizeof(mgcliststruct_t));
55 ctable->numelements = 0; // Initial number of elements in the hash
60 void mgchashreset(mgchashtable_t * tbl) {
61 mgchashlistnode_t *ptr = tbl->table;
64 /*if (tbl->numelements<(tbl->size>>6)) {
65 mgchashlistnode_t *top=&ptr[tbl->size];
66 mgchashlistnode_t * list = tbl->list;
68 mgchashlistnode_t * next = list->lnext;
69 if ((list >= ptr) && (list < top)) {
77 BAMBOO_MEMSET_WH(tbl->table, '\0', sizeof(mgchashlistnode_t)*tbl->size);
79 // TODO now never release any allocated memory, may need to be changed
80 mgcliststruct_t * next = tbl->structs;
81 while(/*tbl->structs->*/next!=NULL) {
82 /*mgcliststruct_t * next = tbl->structs->next;
83 RUNFREE(tbl->structs);
88 //tbl->structs->num = 0;
92 //Store objects and their pointers into hash
93 void mgchashInsert(mgchashtable_t * tbl, void * key, void *val) {
94 mgchashlistnode_t *ptr;
96 if(tbl->numelements > (tbl->threshold)) {
98 unsigned int newsize = tbl->size << 1 + 1;
99 mgchashResize(tbl, newsize);
102 ptr=&tbl->table[(((unsigned INTPTR)key)&tbl->mask)>>6];
106 // the first time insert a value for the key
109 /*ptr->lnext = tbl->list;
111 } else { // Insert in the beginning of linked list
112 mgchashlistnode_t * node;
113 if (tbl->structs->num<NUMMGCLIST) {
114 node=&tbl->structs->array[tbl->structs->num];
118 mgcliststruct_t *tcl=RUNMALLOC(1*sizeof(mgcliststruct_t));
119 tcl->next=tbl->structs;
126 node->next = ptr->next;
128 /*node->lnext = tbl->list;
134 mgchashtable_t * mgchashCreate_I(unsigned int size, double loadfactor) {
135 mgchashtable_t *ctable;
136 mgchashlistnode_t *nodes;
143 printf("Negative Hashtable size Exception\n");
148 // Allocate space for the hash table
149 ctable = (mgchashtable_t*)RUNMALLOC_I(sizeof(mgchashtable_t));
151 // Run out of local memory
154 ctable->table=(mgchashlistnode_t*)RUNMALLOC_I(size*sizeof(mgchashlistnode_t));
155 if(ctable->table == NULL) {
156 // Run out of local memory
159 ctable->loadfactor = loadfactor;
161 ctable->threshold=size*loadfactor;
163 ctable->mask = (size << 6)-1;
164 //ctable->list = NULL;
165 ctable->structs = (mgcliststruct_t*)RUNMALLOC_I(1*sizeof(mgcliststruct_t));
166 ctable->numelements = 0; // Initial number of elements in the hash
171 void mgchashInsert_I(mgchashtable_t * tbl, void * key, void *val) {
172 mgchashlistnode_t *ptr;
174 if(tbl->numelements > (tbl->threshold)) {
176 unsigned int newsize = tbl->size << 1 + 1;
177 mgchashResize_I(tbl, newsize);
180 ptr = &tbl->table[(((unsigned INTPTR)key)&tbl->mask)>>6];
186 /*ptr->lnext = tbl->list;
189 } else { // Insert in the beginning of linked list
190 mgchashlistnode_t * node;
191 if (tbl->structs->num<NUMMGCLIST) {
192 node=&tbl->structs->array[tbl->structs->num];
196 mgcliststruct_t *tcl=RUNMALLOC_I(1*sizeof(mgcliststruct_t));
197 tcl->next=tbl->structs;
204 node->next = ptr->next;
206 /*node->lnext = tbl->list;
212 // Search for an address for a given oid
213 INLINE void * mgchashSearch(mgchashtable_t * tbl, void * key) {
214 //REMOVE HASH FUNCTION CALL TO MAKE SURE IT IS INLINED HERE]
215 mgchashlistnode_t *node = &tbl->table[(((unsigned INTPTR)key)&tbl->mask)>>6];
218 if(node->key == key) {
222 } while(node != NULL);
227 unsigned int mgchashResize(mgchashtable_t * tbl, unsigned int newsize) {
228 mgchashlistnode_t *node, *ptr, *curr; // curr and next keep track of the
229 // current and the next
230 // mgchashlistnodes in a linked list
231 unsigned int oldsize;
232 int isfirst; // Keeps track of the first element in the
233 // chashlistnode_t for each bin in hashtable
234 unsigned int i,index;
240 if((node = RUNMALLOC(newsize*sizeof(mgchashlistnode_t))) == NULL) {
241 printf("Calloc error %s %d\n", __FILE__, __LINE__);
245 tbl->table = node; //Update the global hashtable upon resize()
247 tbl->threshold = newsize * tbl->loadfactor;
248 mask = tbl->mask = (newsize << 6) - 1;
251 for(i = 0; i < oldsize; i++) { //Outer loop for each bin in hash table
254 do { //Inner loop to go through linked lists
256 mgchashlistnode_t *tmp,*next;
258 if ((key=curr->key) == 0) {
259 //Exit inner loop if there the first element is 0
261 //key = val =0 for element if not present within the hash table
263 index = (((unsigned INTPTR)key) & mask) >> 6;
266 // Insert into the new table
269 tmp->val = curr->val;
270 /*tmp->lnext = tbl->list;
273 NOTE: Add this case if you change this...
274 This case currently never happens because of the way things rehash....*/
276 mgchashlistnode_t *newnode= RUNMALLOC(1*sizeof(mgchashlistnode_t));
277 newnode->key = curr->key;
278 newnode->val = curr->val;
279 newnode->next = tmp->next;
281 /*newnode->lnext = tbl->list;
282 tbl->list = newnode;*/
285 curr->next=tmp->next;
287 /*curr->lnext = tbl->list;
296 RUNFREE(ptr); //Free the memory of the old hash table
301 unsigned int mgchashResize_I(mgchashtable_t * tbl, unsigned int newsize) {
302 mgchashlistnode_t *node, *ptr, *curr; // curr and next keep track of the
303 // current and the next
304 // mgchashlistnodes in a linked list
305 unsigned int oldsize;
306 int isfirst; // Keeps track of the first element in the chashlistnode_t
307 // for each bin in hashtable
308 unsigned int i,index;
314 if((node = RUNMALLOC_I(newsize*sizeof(mgchashlistnode_t))) == NULL) {
316 printf("Calloc error %s %d\n", __FILE__, __LINE__);
320 tbl->table = node; //Update the global hashtable upon resize()
322 tbl->threshold = newsize * tbl->loadfactor;
323 mask = tbl->mask = (newsize << 6)-1;
326 for(i = 0; i < oldsize; i++) { //Outer loop for each bin in hash table
329 do { //Inner loop to go through linked lists
331 mgchashlistnode_t *tmp,*next;
333 if ((key=curr->key) == 0) {
334 //Exit inner loop if there the first element is 0
336 //key = val =0 for element if not present within the hash table
338 index = (((unsigned INTPTR)key) & mask) >>6;
341 // Insert into the new table
344 tmp->val = curr->val;
345 /*tmp->lnext = tbl->list;
348 NOTE: Add this case if you change this...
349 This case currently never happens because of the way things rehash....*/
351 mgchashlistnode_t *newnode=RUNMALLOC_I(1*sizeof(mgchashlistnode_t));
352 newnode->key = curr->key;
353 newnode->val = curr->val;
354 newnode->next = tmp->next;
356 /*newnode->lnext = tbl->list;
357 tbl->list = newnode;*/
359 curr->next=tmp->next;
361 /*curr->lnext = tbl->list;
369 RUNFREE(ptr); //Free the memory of the old hash table
374 //Delete the entire hash table
375 void mgchashDelete(mgchashtable_t * tbl) {
377 mgcliststruct_t *ptr=tbl->structs;
379 mgcliststruct_t *next=ptr->next;
388 /* MGCHASH ********************************************************/
390 struct MGCHash * allocateMGCHash(int size,
392 struct MGCHash *thisvar;
397 printf("Negative Hashtable size Exception\n");
401 thisvar=(struct MGCHash *)RUNMALLOC(sizeof(struct MGCHash));
402 thisvar->size = size;
404 (struct MGCNode *) RUNMALLOC(sizeof(struct MGCNode)*size);
406 thisvar->num4conflicts = conflicts;
410 void freeMGCHash(struct MGCHash *thisvar) {
412 for(i=thisvar->size-1; i>=0; i--) {
414 for(ptr=thisvar->bucket[i].next; ptr!=NULL; ) {
415 struct MGCNode * nextptr=ptr->next;
420 RUNFREE(thisvar->bucket);
424 int MGCHashadd(struct MGCHash * thisvar, int data) {
426 unsigned int hashkey;
429 hashkey = (unsigned int)data % thisvar->size;
430 ptr = &thisvar->bucket[hashkey];
432 struct MGCNode * prev = NULL;
433 if(ptr->data < thisvar->num4conflicts) {
434 struct MGCNode *node=RUNMALLOC(sizeof(struct MGCNode));
436 node->next=(ptr->next);
440 while (ptr->next!=NULL) {
445 ptr->next = thisvar->bucket[hashkey].next;
446 thisvar->bucket[hashkey].next = ptr;
454 struct MGCHash * allocateMGCHash_I(int size,
456 struct MGCHash *thisvar;
461 printf("Negative Hashtable size Exception\n");
465 thisvar=(struct MGCHash *)RUNMALLOC_I(sizeof(struct MGCHash));
466 thisvar->size = size;
468 (struct MGCNode *) RUNMALLOC_I(sizeof(struct MGCNode)*size);
470 thisvar->num4conflicts = conflicts;
474 int MGCHashadd_I(struct MGCHash * thisvar, int data) {
476 unsigned int hashkey;
479 hashkey = (unsigned int)data % thisvar->size;
480 ptr = &thisvar->bucket[hashkey];
482 struct MGCNode * prev = NULL;
483 if(ptr->data < thisvar->num4conflicts) {
484 struct MGCNode *node=RUNMALLOC_I(sizeof(struct MGCNode));
486 node->next=(ptr->next);
490 while (ptr->next!=NULL) {
495 ptr->next = thisvar->bucket[hashkey].next;
496 thisvar->bucket[hashkey].next = ptr;
504 int MGCHashcontains(struct MGCHash *thisvar, int data) {
505 unsigned int hashkey = (unsigned int)data % thisvar->size;
507 struct MGCNode *ptr = thisvar->bucket[hashkey].next;
508 struct MGCNode *prev = NULL;
510 if (ptr->data == data) {
513 ptr->next = thisvar->bucket[hashkey].next;
514 thisvar->bucket[hashkey].next = ptr;