remove some codes for scheduling
[IRC.git] / Robust / src / Runtime / DSTM / interface / llookup.c
1 /************************************************************************************************
2   IMP NOTE:
3    All llookup hash function prototypes returns 0 on sucess and 1 otherwise
4    llookup hash is an array of lhashlistnode_t
5    oid = mid = 0 in a given lhashlistnode_t for each bin in the hash table ONLY if the entry is empty =>
6    the OID's can be any unsigned int except 0
7
8    Uses pthreads. compile using -lpthread option
9 ***************************************************************************************************/
10 #include "llookup.h"
11
12 #ifdef SIMPLE_LLOOKUP
13
14 extern unsigned int *hostIpAddrs;
15 extern unsigned int oidsPerBlock;
16
17 unsigned int lhashCreate(unsigned int size, float loadfactor)
18 {
19         return 0;
20 }
21
22 unsigned int lhashInsert(unsigned int oid, unsigned int mid)
23 {
24         return 0;
25 }
26
27 unsigned int lhashSearch(unsigned int oid)
28 {
29         if (oidsPerBlock == 0)
30                 return hostIpAddrs[0];
31         else
32                 return hostIpAddrs[oid / oidsPerBlock];
33 }
34
35 unsigned int lhashRemove(unsigned int oid)
36 {
37         return 0;
38 }
39
40 #else
41
42 lhashtable_t llookup;           //Global Hash table
43
44 // Creates a hash table with size and an array of lhashlistnode_t 
45 unsigned int lhashCreate(unsigned int size, float loadfactor) {
46         lhashlistnode_t *nodes;
47         int i;
48
49         // Allocate space for the hash table 
50         if((nodes = calloc(size, sizeof(lhashlistnode_t))) == NULL) {
51                 printf("Calloc error %s %d\n", __FILE__, __LINE__);
52                 return 1;
53         }
54         
55         llookup.table = nodes;
56         llookup.size = size;
57         llookup.numelements = 0; // Initial number of elements in the hash
58         llookup.loadfactor = loadfactor;
59         //Initialize the pthread_mutex variable         
60         pthread_mutex_init(&llookup.locktable, NULL);
61         return 0;
62 }
63
64 // Assign to oids to bins inside hash table
65 unsigned int lhashFunction(unsigned int oid) {
66         return( oid % (llookup.size));
67 }
68
69 // Insert oid and mid mapping into the hash table
70 unsigned int lhashInsert(unsigned int oid, unsigned int mid) {
71         unsigned int newsize;
72         int index;
73         lhashlistnode_t *ptr, *node;
74         
75         if (llookup.numelements > (llookup.loadfactor * llookup.size)) {
76                 //Resize Table
77                 newsize = 2 * llookup.size + 1;         
78                 pthread_mutex_lock(&llookup.locktable);
79                 lhashResize(newsize);
80                 pthread_mutex_unlock(&llookup.locktable);
81         }
82         
83         ptr = llookup.table;
84         llookup.numelements++;
85         
86         index = lhashFunction(oid);
87 #ifdef DEBUG
88         printf("DEBUG(insert) oid = %d, mid =%d, index =%d\n",oid,mid, index);
89 #endif
90         pthread_mutex_lock(&llookup.locktable);
91         if(ptr[index].next == NULL && ptr[index].oid == 0) {    // Insert at the first position in the hashtable
92                 ptr[index].oid = oid;
93                 ptr[index].mid = mid;
94         } else {                        // Insert in the linked list
95                 if ((node = calloc(1, sizeof(lhashlistnode_t))) == NULL) {
96                         printf("Calloc error %s, %d\n", __FILE__, __LINE__);
97                         pthread_mutex_unlock(&llookup.locktable);
98                         return 1;
99                 }
100                 node->oid = oid;
101                 node->mid = mid;
102                 node->next = ptr[index].next;
103                 ptr[index].next = node;
104         }
105         
106         pthread_mutex_unlock(&llookup.locktable);
107         return 0;
108 }
109
110 // Return mid for a given oid in the hash table
111 unsigned int lhashSearch(unsigned int oid) {
112         int index;
113         lhashlistnode_t *ptr, *node;
114
115         ptr = llookup.table;    // Address of the beginning of hash table       
116         index = lhashFunction(oid);
117         node = &ptr[index];
118         pthread_mutex_lock(&llookup.locktable);
119         while(node != NULL) {
120                 if(node->oid == oid) {
121                         pthread_mutex_unlock(&llookup.locktable);
122                         return node->mid;
123                 }
124                 node = node->next;
125         }
126         pthread_mutex_unlock(&llookup.locktable);
127         return 0;
128 }
129
130 // Remove an entry from the hash table
131 unsigned int lhashRemove(unsigned int oid) {
132         int index;
133         lhashlistnode_t *curr, *prev;
134         lhashlistnode_t *ptr, *node;
135         
136         ptr = llookup.table;
137         index = lhashFunction(oid);
138         curr = &ptr[index];
139         
140         pthread_mutex_lock(&llookup.locktable);
141         for (; curr != NULL; curr = curr->next) {
142                 if (curr->oid == oid) {         // Find a match in the hash table
143                         llookup.numelements--;  // Decrement the number of elements in the global hashtable
144                         if ((curr == &ptr[index]) && (curr->next == NULL))  { // Delete the first item inside the hashtable with no linked list of lhashlistnode_t 
145                                 curr->oid = 0;
146                                 curr->mid = 0;
147                         } else if ((curr == &ptr[index]) && (curr->next != NULL)) { //Delete the first item with a linked list of lhashlistnode_t  connected 
148                                 curr->oid = curr->next->oid;
149                                 curr->mid = curr->next->mid;
150                                 node = curr->next;
151                                 curr->next = curr->next->next;
152                                 free(node);
153                         } else {                                                // Regular delete from linked listed    
154                                 prev->next = curr->next;
155                                 free(curr);
156                         }
157                         pthread_mutex_unlock(&llookup.locktable);
158                         return 0;
159                 }       
160                 prev = curr; 
161         }
162         pthread_mutex_unlock(&llookup.locktable);
163         return 1;
164 }
165
166 // Resize table
167 unsigned int lhashResize(unsigned int newsize) {
168         lhashlistnode_t *node, *ptr, *curr, *next;      // curr and next keep track of the current and the next lhashlistnodes in a linked list
169         unsigned int oldsize;
170         int isfirst;    // Keeps track of the first element in the lhashlistnode_t for each bin in hashtable
171         int i,index;    
172         lhashlistnode_t *newnode;               
173         
174         ptr = llookup.table;
175         oldsize = llookup.size;
176         
177         if((node = calloc(newsize, sizeof(lhashlistnode_t))) == NULL) {
178                 printf("Calloc error %s %d\n", __FILE__, __LINE__);
179                 return 1;
180         }
181
182         llookup.table = node;           //Update the global hashtable upon resize()
183         llookup.size = newsize;
184         llookup.numelements = 0;
185
186         for(i = 0; i < oldsize; i++) {                  //Outer loop for each bin in hash table
187                 curr = &ptr[i];
188                 isfirst = 1;                    
189                 while (curr != NULL) {                  //Inner loop to go through linked lists
190                         if (curr->oid == 0) {           //Exit inner loop if there the first element for a given bin/index is NULL
191                                 break;                  //oid = mid =0 for element if not present within the hash table
192                         }
193                         next = curr->next;
194                         index = lhashFunction(curr->oid);
195                         // Insert into the new table
196                         if(llookup.table[index].next == NULL && llookup.table[index].oid == 0) {
197                                 llookup.table[index].oid = curr->oid;
198                                 llookup.table[index].mid = curr->mid;
199                                 llookup.numelements++;
200                         }else {
201                                 if((newnode = calloc(1, sizeof(lhashlistnode_t))) == NULL) {
202                                         printf("Calloc error %s, %d\n", __FILE__, __LINE__);
203                                         return 1;
204                                 }
205                                 newnode->oid = curr->oid;
206                                 newnode->mid = curr->mid;
207                                 newnode->next = llookup.table[index].next;
208                                 llookup.table[index].next = newnode;    
209                                 llookup.numelements++;
210                         }
211                         
212                         //free the linked list of lhashlistnode_t if not the first element in the hash table
213                         if (isfirst != 1) {
214                                 free(curr);
215                         } 
216                         
217                         isfirst = 0;
218                         curr = next;
219
220                 }
221         }
222
223         free(ptr);              //Free the memory of the old hash table 
224         return 0;
225 }
226
227 #endif
228