remove some codes for scheduling
[IRC.git] / Robust / src / Runtime / DSTM / interface / prelookup.c
1 /* LOCK THE ENTIRE HASH TABLE */
2 #include "prelookup.h"
3
4 prehashtable_t pflookup; //Global prefetch cache table
5
6 unsigned int prehashCreate(unsigned int size, float loadfactor) {
7         prehashlistnode_t *nodes; 
8         int i; 
9
10         // Allocate space for the hash table 
11         if((nodes = calloc(size, sizeof(prehashlistnode_t))) == NULL) { 
12                 printf("Calloc error %s %d\n", __FILE__, __LINE__);
13                 return 1;
14         }       
15
16         pflookup.table = nodes;
17         pflookup.size = size; 
18         pflookup.numelements = 0; // Initial number of elements in the hash
19         pflookup.loadfactor = loadfactor;
20
21         //Intiliaze and set prefetch table mutex attribute
22         pthread_mutexattr_init(&pflookup.prefetchmutexattr);
23         //NOTE:PTHREAD_MUTEX_RECURSIVE is currently inside a #if_def UNIX98 in the pthread.h file
24         //Therefore use PTHREAD_MUTEX_RECURSIVE_NP instead
25         pthread_mutexattr_settype(&pflookup.prefetchmutexattr, PTHREAD_MUTEX_RECURSIVE_NP);
26
27         //Initialize mutex var
28         pthread_mutex_init(&pflookup.lock, &pflookup.prefetchmutexattr);
29         //pthread_mutex_init(&pflookup.lock, NULL);
30         pthread_cond_init(&pflookup.cond, NULL); 
31         return 0;
32 }
33
34 //Assign keys to bins inside hash table
35 unsigned int prehashFunction(unsigned int key) {
36         return ( key % (pflookup.size));
37 }
38
39 //Store oids and their pointers into hash
40 unsigned int prehashInsert(unsigned int key, void *val) {
41         unsigned int newsize;
42         int index;
43         prehashlistnode_t *ptr, *node;
44
45         if(pflookup.numelements > (pflookup.loadfactor * pflookup.size)) {
46                 //Resize
47                 newsize = 2 * pflookup.size + 1;
48                 pthread_mutex_lock(&pflookup.lock);
49                 prehashResize(newsize);
50                 pthread_mutex_unlock(&pflookup.lock);
51         }
52
53         ptr = pflookup.table;
54         pflookup.numelements++;
55         index = prehashFunction(key);
56         
57         pthread_mutex_lock(&pflookup.lock);
58         if(ptr[index].next == NULL && ptr[index].key == 0) {    // Insert at the first position in the hashtable
59                 ptr[index].key = key;
60                 ptr[index].val = val;
61         } else {                        // Insert in the beginning of linked list
62                 if ((node = calloc(1, sizeof(prehashlistnode_t))) == NULL) {
63                         printf("Calloc error %s, %d\n", __FILE__, __LINE__);
64                         pthread_mutex_unlock(&pflookup.lock);
65                         return 1;
66                 }
67                 node->key = key;
68                 node->val = val ;
69                 node->next = ptr[index].next;
70                 ptr[index].next = node;
71         }
72         pthread_mutex_unlock(&pflookup.lock);
73         return 0;
74 }
75
76 // Search for an address for a given oid
77 void *prehashSearch(unsigned int key) {
78         int index;
79         prehashlistnode_t *ptr, *node;
80
81         ptr = pflookup.table;
82         index = prehashFunction(key);
83         node = &ptr[index];
84         pthread_mutex_lock(&pflookup.lock);
85         while(node != NULL) {
86                 if(node->key == key) {
87                         pthread_mutex_unlock(&pflookup.lock);
88                         return node->val;
89                 }
90                 node = node->next;
91         }
92         pthread_mutex_unlock(&pflookup.lock);
93         return NULL;
94 }
95
96 unsigned int prehashRemove(unsigned int key) {
97         int index;
98         prehashlistnode_t *curr, *prev;
99         prehashlistnode_t *ptr, *node;
100         
101         ptr = pflookup.table;
102         index = prehashFunction(key);
103         curr = &ptr[index];
104
105         pthread_mutex_lock(&pflookup.lock);
106         for (; curr != NULL; curr = curr->next) {
107                 if (curr->key == key) {         // Find a match in the hash table
108                         pflookup.numelements--;  // Decrement the number of elements in the global hashtable
109                         if ((curr == &ptr[index]) && (curr->next == NULL))  { // Delete the first item inside the hashtable with no linked list of prehashlistnode_t 
110                                 curr->key = 0;
111                                 curr->val = NULL;
112                         } else if ((curr == &ptr[index]) && (curr->next != NULL)) { //Delete the first item with a linked list of prehashlistnode_t  connected 
113                                 curr->key = curr->next->key;
114                                 curr->val = curr->next->val;
115                                 node = curr->next;
116                                 curr->next = curr->next->next;
117                                 free(node);
118                         } else {                                                // Regular delete from linked listed    
119                                 prev->next = curr->next;
120                                 free(curr);
121                         }
122                         pthread_mutex_unlock(&pflookup.lock);
123                         return 0;
124                 }       
125                 prev = curr; 
126         }
127         pthread_mutex_unlock(&pflookup.lock);
128         return 1;
129 }
130
131 unsigned int prehashResize(unsigned int newsize) {
132         prehashlistnode_t *node, *ptr, *curr, *next;    // curr and next keep track of the current and the next chashlistnodes in a linked list
133         unsigned int oldsize;
134         int isfirst;    // Keeps track of the first element in the prehashlistnode_t for each bin in hashtable
135         int i,index;    
136         prehashlistnode_t *newnode;             
137         
138         ptr = pflookup.table;
139         oldsize = pflookup.size;
140         
141         if((node = calloc(newsize, sizeof(prehashlistnode_t))) == NULL) {
142                 printf("Calloc error %s %d\n", __FILE__, __LINE__);
143                 return 1;
144         }
145
146         pflookup.table = node;          //Update the global hashtable upon resize()
147         pflookup.size = newsize;
148         pflookup.numelements = 0;
149
150         for(i = 0; i < oldsize; i++) {                  //Outer loop for each bin in hash table
151                 curr = &ptr[i];
152                 isfirst = 1;                    
153                 while (curr != NULL) {                  //Inner loop to go through linked lists
154                         if (curr->key == 0) {           //Exit inner loop if there the first element for a given bin/index is NULL
155                                 break;                  //key = val =0 for element if not present within the hash table
156                         }
157                         next = curr->next;
158                         index = prehashFunction(curr->key);
159                         // Insert into the new table
160                         if(pflookup.table[index].next == NULL && pflookup.table[index].key == 0) { 
161                                 pflookup.table[index].key = curr->key;
162                                 pflookup.table[index].val = curr->val;
163                                 pflookup.numelements++;
164                         }else { 
165                                 if((newnode = calloc(1, sizeof(prehashlistnode_t))) == NULL) { 
166                                         printf("Calloc error %s, %d\n", __FILE__, __LINE__);
167                                         return 1;
168                                 }       
169                                 newnode->key = curr->key;
170                                 newnode->val = curr->val;
171                                 newnode->next = pflookup.table[index].next;
172                                 pflookup.table[index].next = newnode;    
173                                 pflookup.numelements++;
174                         }       
175
176                         //free the linked list of prehashlistnode_t if not the first element in the hash table
177                         if (isfirst != 1) {
178                                 free(curr);
179                         } 
180                         
181                         isfirst = 0;
182                         curr = next;
183                 }
184         }
185
186         free(ptr);              //Free the memory of the old hash table 
187         return 0;
188 }
189
190 /* Deletes the prefetch Cache */
191 void prehashDelete() {
192         int i, isFirst;
193         prehashlistnode_t *ptr, *curr, *next;
194         ptr = pflookup.table; 
195
196         for(i=0 ; i<pflookup.size ; i++) {
197                 curr = &ptr[i];
198                 isFirst = 1;
199                 while(curr != NULL) {
200                         next = curr->next;
201                         if(isFirst != 1) {
202                                 free(curr);
203                         }
204                         isFirst = 0;
205                         curr = next;
206                 }
207         }
208
209         free(ptr);
210 }