-#include "hashRCR.h"
+#include "HashRCR.h"
#include "strings.h"
#include "tm.h"
-//Smallest Object Size with 1 ptr is 32-bits on x64 and 24-bits on x86
-//#ifdef BIT64
-//#define _truncate_ >>5
-//#else
-//#define _truncate_ /24
-//#endif
-
-//TODO add __thread infront of all
- chashlistnode_t *c_table;
- chashlistnode_t *c_list;
- unsigned int c_size;
- unsigned INTPTR c_mask;
- unsigned int c_numelements;
- unsigned int c_threshold;
- double c_loadfactor;
- cliststruct_t *c_structs;
-
-void hashRCRCreate(unsigned int size, double loadfactor) {
-// chashtable_t *ctable;
-// chashlistnode_t *nodes;
-// int i;
-
- // Allocate space for the hash table
- c_table = calloc(size, sizeof(chashlistnode_t));
- c_loadfactor = loadfactor;
- c_size = size;
- c_threshold=size*loadfactor;
+//Smallest Object Size with 1 ptr is 32bytes on on 64-bit machine and 24bytes on 32-bit machine
#ifdef BIT64
- c_mask = ((size << 4)-1)&~(15UL);
+#define _truncate_ >>5
#else
- c_mask = ((size << 4)-1)&~15;
+#define _truncate_ /24
#endif
- c_structs=calloc(1, sizeof(cliststruct_t));
- c_numelements = 0; // Initial number of elements in the hash
- c_list=NULL;
+
+
+__thread dchashlistnode_t *dc_c_table;
+__thread dchashlistnode_t *dc_c_list;
+__thread dcliststruct_t *dc_c_structs;
+__thread unsigned int dc_c_size;
+__thread unsigned INTPTR dc_c_mask;
+__thread unsigned int dc_c_numelements;
+__thread unsigned int dc_c_threshold;
+__thread double dc_c_loadfactor;
+
+void hashRCRCreate(unsigned int size, double loadfactor) {
+ // Allocate space for the hash table
+
+ dc_c_table = calloc(size, sizeof(dchashlistnode_t));
+ dc_c_loadfactor = loadfactor;
+ dc_c_size = size;
+ dc_c_threshold=size*loadfactor;
+ dc_c_mask = (size << 4)-1;
+ dc_c_structs=calloc(1, sizeof(dcliststruct_t));
+ dc_c_numelements = 0; // Initial number of elements in the hash
+ dc_c_list=NULL;
}
void hashRCRreset() {
- chashlistnode_t *ptr = c_table;
-// int i;
+ dchashlistnode_t *ptr = dc_c_table;
- if (c_numelements<(c_size>>4)) {
- chashlistnode_t *top=&ptr[c_size];
- chashlistnode_t *tmpptr=c_list;
+ if (dc_c_numelements<(dc_c_size>>4)) {
+ dchashlistnode_t *top=&ptr[dc_c_size];
+ dchashlistnode_t *tmpptr=dc_c_list;
while(tmpptr!=NULL) {
- chashlistnode_t *next=tmpptr->lnext;
+ dchashlistnode_t *next=tmpptr->lnext;
if (tmpptr>=ptr&&tmpptr<top) {
//zero in list
- tmpptr->keyAndVal=NULL;
+ tmpptr->key=NULL;
tmpptr->next=NULL;
}
tmpptr=next;
}
} else {
- bzero(c_table, sizeof(chashlistnode_t)*c_size);
+ bzero(dc_c_table, sizeof(dchashlistnode_t)*dc_c_size);
}
- while(c_structs->next!=NULL) {
- cliststruct_t *next=c_structs->next;
- free(c_structs);
- c_structs=next;
+ while(dc_c_structs->next!=NULL) {
+ dcliststruct_t *next=dc_c_structs->next;
+ free(dc_c_structs);
+ dc_c_structs=next;
}
- c_structs->num = 0;
- c_numelements = 0;
- c_list=NULL;
+ dc_c_structs->num = 0;
+ dc_c_numelements = 0;
+ dc_c_list=NULL;
}
//Store objects and their pointers into hash
+//1 = add success
+//0 = object already exists / Add failed
+int hashRCRInsert(void * key) {
+ dchashlistnode_t *ptr;
-void hashRCRInsert(void * addrIn) {
- chashlistnode_t *ptr;
-
+ if (unlikely(key==NULL)) {
+ return 0;
+ }
- if(c_numelements > (c_threshold)) {
+ if(unlikely(dc_c_numelements > dc_c_threshold)) {
//Resize
- unsigned int newsize = c_size << 1;
+ unsigned int newsize = dc_c_size << 1;
hashRCRResize(newsize);
}
-
- ptr = &c_table[(((unsigned INTPTR)addrIn)&c_mask)>>4];
- c_numelements++;
-
- if(ptr->keyAndVal==0) {
- ptr->keyAndVal=addrIn;
- ptr->lnext=c_list;
- c_list=ptr;
+ ptr = &dc_c_table[(((unsigned INTPTR)key _truncate_ )&dc_c_mask)>>4];
+ if(likely(ptr->key==0)) {
+ ptr->key=key;
+ ptr->lnext=dc_c_list;
+ dc_c_list=ptr;
+ dc_c_numelements++;
} else { // Insert in the beginning of linked list
- chashlistnode_t * node;
- if (c_structs->num<NUMCLIST) {
- node=&c_structs->array[c_structs->num];
- c_structs->num++;
+ dchashlistnode_t * node;
+ dchashlistnode_t *search=ptr;
+
+ //make sure it isn't here
+ do {
+ if(search->key == key) {
+ return 0;
+ }
+ search=search->next;
+ } while(search != NULL);
+
+ dc_c_numelements++;
+ if (dc_c_structs->num<NUMDCLIST) {
+ node=&dc_c_structs->array[dc_c_structs->num];
+ dc_c_structs->num++;
} else {
//get new list
- cliststruct_t *tcl=calloc(1,sizeof(cliststruct_t));
- tcl->next=c_structs;
- c_structs=tcl;
+ dcliststruct_t *tcl=calloc(1,sizeof(dcliststruct_t));
+ tcl->next=dc_c_structs;
+ dc_c_structs=tcl;
node=&tcl->array[0];
tcl->num=1;
}
- node->keyAndVal = addrIn;
+ node->key = key;
node->next = ptr->next;
ptr->next=node;
- node->lnext=c_list;
- c_list=node;
+ node->lnext=dc_c_list;
+ dc_c_list=node;
}
-}
-
-// Search for an address for a given oid
-INLINE void * hashRCRSearch(void * key) {
- //REMOVE HASH FUNCTION CALL TO MAKE SURE IT IS INLINED HERE
- chashlistnode_t *node = &c_table[(((unsigned INTPTR)key) & c_mask)>>4];
- do {
- if(node->key == key) {
- return node->val;
- }
- node = node->next;
- } while(node != NULL);
-
- return NULL;
+ return 1;
}
+
unsigned int hashRCRResize(unsigned int newsize) {
- chashlistnode_t *node, *ptr, *curr; // curr and next keep track of the current and the next chashlistnodes in a linked list
+ dchashlistnode_t *node, *ptr, *curr; // curr and next keep track of the current and the next chashlistnodes in a linked list
unsigned int oldsize;
int isfirst; // Keeps track of the first element in the chashlistnode_t for each bin in hashtable
unsigned int i,index;
unsigned int mask;
- ptr = c_table;
- oldsize = c_size;
- c_list=NULL;
+ ptr = dc_c_table;
+ oldsize = dc_c_size;
+ dc_c_list=NULL;
- if((node = calloc(newsize, sizeof(chashlistnode_t))) == NULL) {
+ if((node = calloc(newsize, sizeof(dchashlistnode_t))) == NULL) {
printf("Calloc error %s %d\n", __FILE__, __LINE__);
return 1;
}
- c_table = node; //Update the global hashtable upon resize()
- c_size = newsize;
- c_threshold = newsize * c_loadfactor;
- mask=c_mask = (newsize << 4)-1;
+ dc_c_table = node; //Update the global hashtable upon resize()
+ dc_c_size = newsize;
+ dc_c_threshold = newsize * dc_c_loadfactor;
+ mask=dc_c_mask = (newsize << 4)-1;
for(i = 0; i < oldsize; i++) { //Outer loop for each bin in hash table
curr = &ptr[i];
isfirst = 1;
do { //Inner loop to go through linked lists
void * key;
- chashlistnode_t *tmp,*next;
+ dchashlistnode_t *tmp,*next;
- if ((key=curr->keyAndVal) == 0) { //Exit inner loop if there the first element is 0
+ if ((key=curr->key) == 0) { //Exit inner loop if there the first element is 0
break; //key = val =0 for element if not present within the hash table
}
- index = (((unsigned INTPTR)key) & mask) >>4;
+
+ index = (((unsigned INTPTR)key _truncate_ ) & mask) >>4;
tmp=&node[index];
next = curr->next;
// Insert into the new table
- if(tmp->keyAndVal == 0) {
- tmp->keyAndVal = key;
-// tmp->val = curr->val;
- tmp->lnext=c_list;
- c_list=tmp;
+ if(tmp->key == 0) {
+ tmp->key = key;
+ tmp->lnext=dc_c_list;
+ dc_c_list=tmp;
} /*
NOTE: Add this case if you change this...
This case currently never happens because of the way things rehash....
else {
curr->next=tmp->next;
tmp->next=curr;
- curr->lnext=c_list;
- c_list=curr;
+ curr->lnext=dc_c_list;
+ dc_c_list=curr;
}
isfirst = 0;
//Delete the entire hash table
void hashRCRDelete() {
-// int i;
- cliststruct_t *ptr=c_structs;
+ dcliststruct_t *ptr=dc_c_structs;
while(ptr!=NULL) {
- cliststruct_t *next=ptr->next;
+ dcliststruct_t *next=ptr->next;
free(ptr);
ptr=next;
}
- free(c_table);
- c_table=NULL;
- c_structs=NULL;
- c_list=NULL;
+ free(dc_c_table);
+ dc_c_table=NULL;
+ dc_c_structs=NULL;
+ dc_c_list=NULL;
+}
+
+// Search for an address for a given Address
+INLINE int hashRCRSearch(void * key) {
+ //REMOVE HASH FUNCTION CALL TO MAKE SURE IT IS INLINED HERE
+ dchashlistnode_t *node = &dc_c_table[(((unsigned INTPTR)key _truncate_) & dc_c_mask)>>4];
+
+ do {
+ if(node->key == key) {
+ return 1;
+ }
+ node = node->next;
+ } while(node != NULL);
+
+ return 0;
}
#define INLINE inline __attribute__((always_inline))
-typedef struct chashlistnode {
- void * keyAndVal; //this can be cast to another type or used to point to a larger structure
- struct chashlistnode *next;
- struct chashlistnode *lnext;
-} chashlistnode_t;
-
-typedef struct chashtable {
- chashlistnode_t *table; // points to beginning of hash table
- unsigned int size;
- unsigned int mask;
- unsigned int numelements;
- unsigned int threshold;
- double loadfactor;
-} chashtable_t;
-
-#define NUMCLIST 250
-typedef struct clist {
- struct chashlistnode array[NUMCLIST];
+//TODO consider changing names to avoid conflicts
+extern __thread unsigned int dc_c_size;
+extern __thread unsigned INTPTR dc_c_mask;
+extern __thread unsigned int dc_c_numelements;
+extern __thread unsigned int dc_c_threshold;
+extern __thread double dc_c_loadfactor;
+
+typedef struct dchashlistnode {
+ void * key;
+ struct dchashlistnode *next;
+ struct dchashlistnode *lnext;
+} dchashlistnode_t;
+
+#define NUMDCLIST 250
+typedef struct dclist {
+ struct dchashlistnode array[NUMDCLIST];
int num;
- struct clist *next;
-} cliststruct_t;
+ struct dclist *next;
+} dcliststruct_t;
void hashRCRCreate(unsigned int size, double loadfactor);
-void hashRCRInsert(void * addrIn);
-void * hashRCRSearch(void * key);
+int hashRCRInsert(void * key);
+int hashRCRSearch(void * key);
unsigned int hashRCRResize(unsigned int newsize);
void hashRCRDelete();
void hashRCRreset();
-
-//TODO add __thread after extern for all of these
-//TODO consider changing names to avoid conflicts
-extern chashlistnode_t *c_table;
-extern chashlistnode_t *c_list;
-extern unsigned int c_size;
-extern unsigned INTPTR c_mask;
-extern unsigned int c_numelements;
-extern unsigned int c_threshold;
-extern double c_loadfactor;
-extern cliststruct_t *c_structs;
-
#endif