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