5 struct chashlistnode array[NUMCLIST];
10 __thread chashlistnode_t *c_table;
11 __thread unsigned int c_size;
12 __thread unsigned int c_mask;
13 __thread unsigned int c_numelements;
14 __thread unsigned int c_threshold;
15 __thread double c_loadfactor;
16 __thread cliststruct_t *c_structs;
18 void t_chashCreate(unsigned int size, double loadfactor) {
20 chashlistnode_t *nodes;
23 // Allocate space for the hash table
26 c_table = calloc(size, sizeof(chashlistnode_t));
27 c_loadfactor = loadfactor;
29 c_threshold=size*loadfactor;
30 c_mask = (size << 1)-1;
31 c_structs=calloc(1,sizeof(cliststruct_t));
32 c_numelements = 0; // Initial number of elements in the hash
35 chashtable_t *chashCreate(unsigned int size, double loadfactor) {
37 chashlistnode_t *nodes;
40 if((ctable = calloc(1, sizeof(chashtable_t))) == NULL) {
41 printf("Calloc error %s %d\n", __FILE__, __LINE__);
45 // Allocate space for the hash table
46 if((nodes = calloc(size, sizeof(chashlistnode_t))) == NULL) {
47 printf("Calloc error %s %d\n", __FILE__, __LINE__);
52 ctable->table = nodes;
53 ctable->loadfactor = loadfactor;
55 ctable->threshold=size*loadfactor;
56 ctable->mask = (size << 1)-1;
57 ctable->numelements = 0; // Initial number of elements in the hash
63 //Finds the right bin in the hash table
64 static INLINE unsigned int chashFunction(chashtable_t *table, unsigned int key) {
65 return ( key & (table->mask))>>1; //throw away low order bit
68 //Store objects and their pointers into hash
69 void chashInsert(chashtable_t *table, unsigned int key, void *val) {
73 if(table->numelements > (table->threshold)) {
75 unsigned int newsize = table->size << 1;
76 chashResize(table,newsize);
79 ptr = &table->table[(key&table->mask)>>1];
85 } else { // Insert in the beginning of linked list
86 chashlistnode_t * node = calloc(1, sizeof(chashlistnode_t));
89 node->next = ptr->next;
94 // Search for an address for a given oid
95 INLINE void * chashSearch(chashtable_t *table, unsigned int key) {
96 //REMOVE HASH FUNCTION CALL TO MAKE SURE IT IS INLINED HERE
97 chashlistnode_t *node = &table->table[(key & table->mask)>>1];
100 if(node->key == key) {
104 } while(node != NULL);
109 //Store objects and their pointers into hash
110 void t_chashInsert(unsigned int key, void *val) {
111 chashlistnode_t *ptr;
113 if(c_numelements > (c_threshold)) {
115 unsigned int newsize = c_size << 1;
116 t_chashResize(newsize);
119 ptr = &c_table[(key&c_mask)>>1];
125 } else { // Insert in the beginning of linked list
126 chashlistnode_t * node;
127 if (c_structs->num<NUMCLIST) {
128 node=&c_structs->array[c_structs->num];
132 cliststruct_t *tcl=calloc(1,sizeof(cliststruct_t));
140 node->next = ptr->next;
145 // Search for an address for a given oid
146 INLINE void * t_chashSearch(unsigned int key) {
147 //REMOVE HASH FUNCTION CALL TO MAKE SURE IT IS INLINED HERE
148 chashlistnode_t *node = &c_table[(key & c_mask)>>1];
151 if(node->key == key) {
155 } while(node != NULL);
160 unsigned int chashRemove(chashtable_t *table, unsigned int key) {
161 return chashRemove2(table, key)==NULL;
165 void * chashRemove2(chashtable_t *table, unsigned int key) {
167 chashlistnode_t *curr, *prev;
168 chashlistnode_t *ptr, *node;
172 index = chashFunction(table,key);
175 for (; curr != NULL; curr = curr->next) {
176 if (curr->key == key) { // Find a match in the hash table
177 table->numelements--; // Decrement the number of elements in the global hashtable
178 if ((curr == &ptr[index]) && (curr->next == NULL)) { // Delete the first item inside the hashtable with no linked list of chashlistnode_t
182 } else if ((curr == &ptr[index]) && (curr->next != NULL)) { //Delete the first item with a linked list of chashlistnode_t connected
183 curr->key = curr->next->key;
185 curr->val = curr->next->val;
187 curr->next = curr->next->next;
189 } else { // Regular delete from linked listed
190 prev->next = curr->next;
201 unsigned int chashResize(chashtable_t *table, unsigned int newsize) {
202 chashlistnode_t *node, *ptr, *curr; // curr and next keep track of the current and the next chashlistnodes in a linked list
203 unsigned int oldsize;
204 int isfirst; // Keeps track of the first element in the chashlistnode_t for each bin in hashtable
205 unsigned int i,index;
209 oldsize = table->size;
211 if((node = calloc(newsize, sizeof(chashlistnode_t))) == NULL) {
212 printf("Calloc error %s %d\n", __FILE__, __LINE__);
216 table->table = node; //Update the global hashtable upon resize()
217 table->size = newsize;
218 table->threshold = newsize * table->loadfactor;
219 mask=table->mask = (newsize << 1)-1;
221 for(i = 0; i < oldsize; i++) { //Outer loop for each bin in hash table
224 do { //Inner loop to go through linked lists
226 chashlistnode_t *tmp,*next;
228 if ((key=curr->key) == 0) { //Exit inner loop if there the first element is 0
229 break; //key = val =0 for element if not present within the hash table
232 index = (key & mask) >>1;
234 // Insert into the new table
236 tmp->key = curr->key;
237 tmp->val = curr->val;
242 NOTE: Add this case if you change this...
243 This case currently never happens because of the way things rehash....
245 chashlistnode_t *newnode= calloc(1, sizeof(chashlistnode_t));
246 newnode->key = curr->key;
247 newnode->val = curr->val;
248 newnode->next = tmp->next;
252 curr->next=tmp->next;
261 free(ptr); //Free the memory of the old hash table
265 unsigned int t_chashResize(unsigned int newsize) {
266 chashlistnode_t *node, *ptr, *curr; // curr and next keep track of the current and the next chashlistnodes in a linked list
267 unsigned int oldsize;
268 int isfirst; // Keeps track of the first element in the chashlistnode_t for each bin in hashtable
269 unsigned int i,index;
275 if((node = calloc(newsize, sizeof(chashlistnode_t))) == NULL) {
276 printf("Calloc error %s %d\n", __FILE__, __LINE__);
280 c_table = node; //Update the global hashtable upon resize()
282 c_threshold = newsize * c_loadfactor;
283 mask=c_mask = (newsize << 1)-1;
285 for(i = 0; i < oldsize; i++) { //Outer loop for each bin in hash table
288 do { //Inner loop to go through linked lists
290 chashlistnode_t *tmp,*next;
292 if ((key=curr->key) == 0) { //Exit inner loop if there the first element is 0
293 break; //key = val =0 for element if not present within the hash table
295 index = (key & mask) >>1;
298 // Insert into the new table
301 tmp->val = curr->val;
303 NOTE: Add this case if you change this...
304 This case currently never happens because of the way things rehash....
306 chashlistnode_t *newnode= calloc(1, sizeof(chashlistnode_t));
307 newnode->key = curr->key;
308 newnode->val = curr->val;
309 newnode->next = tmp->next;
313 curr->next=tmp->next;
322 free(ptr); //Free the memory of the old hash table
326 //Delete the entire hash table
327 void chashDelete(chashtable_t *ctable) {
329 chashlistnode_t *ptr = ctable->table;
331 for(i=0; i<ctable->size; i++) {
332 chashlistnode_t * curr = ptr[i].next;
334 chashlistnode_t * next = curr->next;
343 //Delete the entire hash table
344 void t_chashDelete() {
345 cliststruct_t *ptr=c_structs;
347 cliststruct_t *next=ptr->next;