Added pthread support for llookup and mlookup hash
[IRC.git] / Robust / src / Runtime / DSTM / interface / clookup.c
1  #include "clookup.h"
2
3 chashtable_t *chashCreate(unsigned int size, float loadfactor) {
4         chashtable_t *ctable;
5         chashlistnode_t *nodes; 
6         int i; 
7         
8         if((ctable = calloc(1, sizeof(chashtable_t))) == NULL) {
9                 printf("Calloc error %s %d\n", __FILE__, __LINE__);
10                 return NULL;
11         }       
12
13         // Allocate space for the hash table 
14         if((nodes = calloc(size, sizeof(chashlistnode_t))) == NULL) { 
15                 printf("Calloc error %s %d\n", __FILE__, __LINE__);
16                 return NULL;
17         }       
18
19         ctable->table = nodes;
20         ctable->size = size; 
21         ctable->numelements = 0; // Initial number of elements in the hash
22         ctable->loadfactor = loadfactor;
23         
24         return ctable;
25 }
26
27 //Finds the right bin in the hash table
28 unsigned int chashFunction(chashtable_t *table, unsigned int key) {
29         return ( key % (table->size));
30 }
31
32 //Store objects and their pointers into hash
33 unsigned int chashInsert(chashtable_t *table, unsigned int key, void *val) {
34         unsigned int newsize;
35         int index;
36         chashlistnode_t *ptr, *node;
37
38         if(table->numelements > (table->loadfactor * table->size)) {
39                 //Resize
40                 newsize = 2 * table->size + 1;
41                 chashResize(table,newsize);
42         }
43
44         ptr = table->table;
45         table->numelements++;
46         index = chashFunction(table, key);
47 #ifdef DEBUG
48         printf("DEBUG -> index = %d, key = %d, val = %x\n", index, key, val);
49 #endif
50         if(ptr[index].next == NULL && ptr[index].key == 0) {    // Insert at the first position in the hashtable
51                 ptr[index].key = key;
52                 ptr[index].val = val;
53         } else {                        // Insert in the beginning of linked list
54                 if ((node = calloc(1, sizeof(chashlistnode_t))) == NULL) {
55                         printf("Calloc error %s, %d\n", __FILE__, __LINE__);
56                         return 1;
57                 }
58                 node->key = key;
59                 node->val = val ;
60                 node->next = ptr[index].next;
61                 ptr[index].next = node;
62         }
63         return 0;
64 }
65
66 // Search for an address for a given oid
67 void *chashSearch(chashtable_t *table, unsigned int key) {
68         int index;
69         chashlistnode_t *ptr, *node;
70
71         ptr = table->table;
72         index = chashFunction(table, key);
73         node = &ptr[index];
74         while(node != NULL) {
75                 if(node->key == key) {
76                         return node->val;
77                 }
78                 node = node->next;
79         }
80         return NULL;
81 }
82
83 unsigned int chashRemove(chashtable_t *table, unsigned int key) {
84         int index;
85         chashlistnode_t *curr, *prev;
86         chashlistnode_t *ptr, *node;
87         
88         ptr = table->table;
89         index = chashFunction(table,key);
90         curr = &ptr[index];
91
92         for (; curr != NULL; curr = curr->next) {
93                 if (curr->key == key) {         // Find a match in the hash table
94                         table->numelements--;  // Decrement the number of elements in the global hashtable
95                         if ((curr == &ptr[index]) && (curr->next == NULL))  { // Delete the first item inside the hashtable with no linked list of chashlistnode_t 
96                                 curr->key = 0;
97                                 curr->val = NULL;
98                         } else if ((curr == &ptr[index]) && (curr->next != NULL)) { //Delete the first item with a linked list of chashlistnode_t  connected 
99                                 curr->key = curr->next->key;
100                                 curr->val = curr->next->val;
101                                 node = curr->next;
102                                 curr->next = curr->next->next;
103                                 free(node);
104                         } else {                                                // Regular delete from linked listed    
105                                 prev->next = curr->next;
106                                 free(curr);
107                         }
108                         return 0;
109                 }       
110                 prev = curr; 
111         }
112         return 1;
113 }
114
115 unsigned int chashResize(chashtable_t *table, unsigned int newsize) {
116         chashlistnode_t *node, *ptr, *curr, *next;      // curr and next keep track of the current and the next chashlistnodes in a linked list
117         unsigned int oldsize;
118         int isfirst;    // Keeps track of the first element in the chashlistnode_t for each bin in hashtable
119         int i,index;    
120         chashlistnode_t *newnode;               
121         
122         ptr = table->table;
123         oldsize = table->size;
124         
125         if((node = calloc(newsize, sizeof(chashlistnode_t))) == NULL) {
126                 printf("Calloc error %s %d\n", __FILE__, __LINE__);
127                 return 1;
128         }
129
130         table->table = node;            //Update the global hashtable upon resize()
131         table->size = newsize;
132         table->numelements = 0;
133
134         for(i = 0; i < oldsize; i++) {                  //Outer loop for each bin in hash table
135                 curr = &ptr[i];
136                 isfirst = 1;                    
137                 while (curr != NULL) {                  //Inner loop to go through linked lists
138                         if (curr->key == 0) {           //Exit inner loop if there the first element for a given bin/index is NULL
139                                 break;                  //key = val =0 for element if not present within the hash table
140                         }
141                         next = curr->next;
142
143                         index = chashFunction(table, curr->key);
144 #ifdef DEBUG
145                         printf("DEBUG(resize) -> index = %d, key = %d, val = %x\n", index, curr->key, curr->val);
146 #endif
147                         // Insert into the new table
148                         if(table->table[index].next == NULL && table->table[index].key == 0) { 
149                                 table->table[index].key = curr->key;
150                                 table->table[index].val = curr->val;
151                                 table->numelements++;
152                         }else { 
153                                 if((newnode = calloc(1, sizeof(chashlistnode_t))) == NULL) { 
154                                         printf("Calloc error %s, %d\n", __FILE__, __LINE__);
155                                         return 1;
156                                 }       
157                                 newnode->key = curr->key;
158                                 newnode->val = curr->val;
159                                 newnode->next = table->table[index].next;
160                                 table->table[index].next = newnode;    
161                                 table->numelements++;
162                         }       
163
164                         //free the linked list of chashlistnode_t if not the first element in the hash table
165                         if (isfirst != 1) {
166                                 free(curr);
167                         } 
168                         
169                         isfirst = 0;
170                         curr = next;
171                 }
172         }
173
174         free(ptr);              //Free the memory of the old hash table 
175         return 0;
176 }
177
178 //Delete the entire hash table
179 void chashDelete(chashtable_t *table) {
180         int i, isFirst;
181         chashlistnode_t *ptr, *curr, *next;
182         ptr = table->table;
183
184         for(i=0 ; i<table->size ; i++) {
185                 curr = &ptr[i];
186                 isFirst = 1 ;
187                 while(curr  != NULL) {
188                         next = curr->next;
189                         if(isFirst != 1) {
190                                 free(curr);
191                         }
192                         isFirst = 0;
193                         curr = next;
194                 }
195         }
196
197         free(ptr);
198         free(table);
199         table = NULL;
200 }