3 __thread chashlistnode_t *c_table;
4 __thread unsigned int c_size;
5 __thread unsigned int c_mask;
6 __thread unsigned int c_numelements;
7 __thread unsigned int c_threshold;
8 __thread double c_loadfactor;
10 void t_chashCreate(unsigned int size, double loadfactor) {
12 chashlistnode_t *nodes;
15 // Allocate space for the hash table
18 c_table = calloc(size, sizeof(chashlistnode_t));
19 c_loadfactor = loadfactor;
21 c_threshold=size*loadfactor;
22 c_mask = (size << 3)-1;
23 c_numelements = 0; // Initial number of elements in the hash
26 chashtable_t *chashCreate(unsigned int size, double loadfactor) {
28 chashlistnode_t *nodes;
31 if((ctable = calloc(1, sizeof(chashtable_t))) == NULL) {
32 printf("Calloc error %s %d\n", __FILE__, __LINE__);
36 // Allocate space for the hash table
37 if((nodes = calloc(size, sizeof(chashlistnode_t))) == NULL) {
38 printf("Calloc error %s %d\n", __FILE__, __LINE__);
43 ctable->table = nodes;
44 ctable->loadfactor = loadfactor;
46 ctable->threshold=size*loadfactor;
47 ctable->mask = (size << 3)-1;
48 ctable->numelements = 0; // Initial number of elements in the hash
54 //Finds the right bin in the hash table
55 static INLINE unsigned int chashFunction(chashtable_t *table, unsigned int key) {
56 return ( key & (table->mask))>>3; //throw away low order bit
59 //Store objects and their pointers into hash
60 void chashInsert(chashtable_t *table, unsigned int key, void *val) {
63 if(table->numelements > (table->threshold)) {
65 unsigned int newsize = table->size << 1;
66 chashResize(table,newsize);
69 ptr = &table->table[(key&table->mask)>>3];
75 } else { // Insert in the beginning of linked list
76 chashlistnode_t * node = calloc(1, sizeof(chashlistnode_t));
79 node->next = ptr->next;
84 // Search for an address for a given oid
85 INLINE void * chashSearch(chashtable_t *table, unsigned int key) {
86 //REMOVE HASH FUNCTION CALL TO MAKE SURE IT IS INLINED HERE
87 chashlistnode_t *node = &table->table[(key & table->mask)>>3];
90 if(node->key == key) {
94 } while(node != NULL);
99 //Store objects and their pointers into hash
100 void t_chashInsert(unsigned int key, void *val) {
101 chashlistnode_t *ptr;
104 if(c_numelements > (c_threshold)) {
106 unsigned int newsize = c_size << 1;
107 t_chashResize(newsize);
110 ptr = &c_table[(key&c_mask)>>3];
116 } else { // Insert in the beginning of linked list
117 chashlistnode_t * node = calloc(1, sizeof(chashlistnode_t));
120 node->next = ptr->next;
125 // Search for an address for a given oid
126 INLINE void * t_chashSearch(unsigned int key) {
127 //REMOVE HASH FUNCTION CALL TO MAKE SURE IT IS INLINED HERE
128 chashlistnode_t *node = &c_table[(key & c_mask)>>3];
131 if(node->key == key) {
135 } while(node != NULL);
140 unsigned int chashRemove(chashtable_t *table, unsigned int key) {
141 return chashRemove2(table, key)==NULL;
145 void * chashRemove2(chashtable_t *table, unsigned int key) {
147 chashlistnode_t *curr, *prev;
148 chashlistnode_t *ptr, *node;
152 index = chashFunction(table,key);
155 for (; curr != NULL; curr = curr->next) {
156 if (curr->key == key) { // Find a match in the hash table
157 table->numelements--; // Decrement the number of elements in the global hashtable
158 if ((curr == &ptr[index]) && (curr->next == NULL)) { // Delete the first item inside the hashtable with no linked list of chashlistnode_t
162 } else if ((curr == &ptr[index]) && (curr->next != NULL)) { //Delete the first item with a linked list of chashlistnode_t connected
163 curr->key = curr->next->key;
165 curr->val = curr->next->val;
167 curr->next = curr->next->next;
169 } else { // Regular delete from linked listed
170 prev->next = curr->next;
181 unsigned int chashResize(chashtable_t *table, unsigned int newsize) {
182 chashlistnode_t *node, *ptr, *curr; // curr and next keep track of the current and the next chashlistnodes in a linked list
183 unsigned int oldsize;
184 int isfirst; // Keeps track of the first element in the chashlistnode_t for each bin in hashtable
185 unsigned int i,index;
189 oldsize = table->size;
191 if((node = calloc(newsize, sizeof(chashlistnode_t))) == NULL) {
192 printf("Calloc error %s %d\n", __FILE__, __LINE__);
196 table->table = node; //Update the global hashtable upon resize()
197 table->size = newsize;
198 table->threshold = newsize * table->loadfactor;
199 mask=table->mask = (newsize << 3)-1;
201 for(i = 0; i < oldsize; i++) { //Outer loop for each bin in hash table
204 do { //Inner loop to go through linked lists
206 chashlistnode_t *tmp,*next;
208 if ((key=curr->key) == 0) { //Exit inner loop if there the first element is 0
209 break; //key = val =0 for element if not present within the hash table
212 index = (key & mask) >>3;
214 // Insert into the new table
216 tmp->key = curr->key;
217 tmp->val = curr->val;
222 NOTE: Add this case if you change this...
223 This case currently never happens because of the way things rehash....
225 chashlistnode_t *newnode= calloc(1, sizeof(chashlistnode_t));
226 newnode->key = curr->key;
227 newnode->val = curr->val;
228 newnode->next = tmp->next;
232 curr->next=tmp->next;
241 free(ptr); //Free the memory of the old hash table
245 unsigned int t_chashResize(unsigned int newsize) {
246 chashlistnode_t *node, *ptr, *curr; // curr and next keep track of the current and the next chashlistnodes in a linked list
247 unsigned int oldsize;
248 int isfirst; // Keeps track of the first element in the chashlistnode_t for each bin in hashtable
249 unsigned int i,index;
255 if((node = calloc(newsize, sizeof(chashlistnode_t))) == NULL) {
256 printf("Calloc error %s %d\n", __FILE__, __LINE__);
260 c_table = node; //Update the global hashtable upon resize()
262 c_threshold = newsize * c_loadfactor;
263 mask=c_mask = (newsize << 3)-1;
265 for(i = 0; i < oldsize; i++) { //Outer loop for each bin in hash table
268 do { //Inner loop to go through linked lists
270 chashlistnode_t *tmp,*next;
272 if ((key=curr->key) == 0) { //Exit inner loop if there the first element is 0
273 break; //key = val =0 for element if not present within the hash table
276 index = (key & mask) >>3;
278 // Insert into the new table
280 tmp->key = curr->key;
281 tmp->val = curr->val;
286 NOTE: Add this case if you change this...
287 This case currently never happens because of the way things rehash....
289 chashlistnode_t *newnode= calloc(1, sizeof(chashlistnode_t));
290 newnode->key = curr->key;
291 newnode->val = curr->val;
292 newnode->next = tmp->next;
296 curr->next=tmp->next;
305 free(ptr); //Free the memory of the old hash table
309 //Delete the entire hash table
310 void chashDelete(chashtable_t *ctable) {
312 chashlistnode_t *ptr = ctable->table;
314 for(i=0 ; i<ctable->size ; i++) {
315 chashlistnode_t * curr = ptr[i].next;
317 chashlistnode_t * next = curr->next;
326 //Delete the entire hash table
327 void t_chashDelete() {
329 chashlistnode_t *ptr = c_table;
331 for(i=0 ; i<c_size ; i++) {
332 chashlistnode_t * curr = ptr[i].next;
334 chashlistnode_t * next = curr->next;