Added hash functions with support for multiple hash tables
[IRC.git] / Robust / src / Runtime / DSTM / interface / dstm.c
1 #include "dstm.h"
2
3 obj_store_t *obj_begin;                 // points to the first location of the object store linked list
4 //unsigned int hash_size;                       // number of entries in hash table
5
6 extern int classsize[];
7
8 /* BEGIN - object store */
9 // Initializes the pointers...currently invoked inside main()
10 void dstm_init(void) {
11         obj_begin = NULL;
12         return;
13 }
14 // Create a new object store of a given "size"  as a linked list
15 void create_objstr(unsigned int size) {
16         obj_store_t *tmp, *ptr;
17         static int id = 0; // keeps track of which object store is it when there are more than one object store 
18
19         if ((tmp = (obj_store_t *) malloc(sizeof(obj_store_t))) < 0) {
20                 printf("DSTM: Malloc error %s %d\n", __FILE__, __LINE__);
21                 exit(-1);
22         }
23         if ((tmp->base = (char *) malloc(sizeof(char)*size)) < 0) {
24                 printf("DSTM: Malloc error %s %d\n", __FILE__, __LINE__);
25                 exit(-1);
26         }
27         tmp->size = size;
28         printf("The object store size is : %d\n", tmp->size);
29         tmp->top = tmp->base;
30         tmp->id = id++;
31         printf("The object store id is : %d\n", tmp->id);
32         tmp->next = obj_begin;          //adds new object store to the linked list and updates obj_begin pointer to new object store node
33         obj_begin = tmp;
34         return;
35 }
36
37 // Delete the object store numbered "id"
38 void delete_objstr(int id) {
39         //TODO Implement this along with garbage collector
40         return;
41 }
42
43 obj_store_t *get_objstr_begin(void) {
44         return obj_begin;
45 }
46
47 /* END object store */
48
49 /* BEGIN object header */
50 // Get a new object id
51 int get_newID(void) {
52         static int id = 0;
53         
54         return ++id;
55 }
56 // Insert the object header and object into the object store
57 int insertObject(obj_header_t h) {
58         extern obj_addr_table_t mlut;           //declared in the main mlut=>machine look up table
59         unsigned int left, req;                 // Keeps track of the space available in the current object store
60         obj_header_t *header;
61         
62         left = obj_begin->size - (obj_begin->top - obj_begin->base);
63         req = getObjSize(h) + sizeof(obj_header_t);
64         if (req < left) {
65                 memcpy(obj_begin->top, &h, sizeof(obj_header_t));
66                 header = (obj_header_t *) obj_begin->top;
67                 printf("The header points to : %d\n", header);
68                 obj_begin->top = obj_begin->top + sizeof(obj_header_t) + getObjSize(h); //increment object store top when new object is inserted
69                 printf("Top now points to :%d\n", obj_begin->top);
70         } else {
71                 return -1;
72         }
73         printf("header: %d\n", header);
74         printf("The oid is : %d\n", h.oid);
75         addKey(h.oid, header, &mlut);                   //Update obj_addr_table
76         printf("Object id = %d\n",h.oid);
77         return 0;
78 }
79 // Get the size of the object for a given type
80 int getObjSize(obj_header_t h) {
81         return classsize[h.type];
82 }
83 // Initial object when it is created at first
84 void createObject(unsigned short type) {
85         obj_header_t h;
86
87         h.oid = get_newID();
88         h.type = type;
89         h.version = 0;
90         h.rcount = 1;
91         h.status = CLEAN;
92         insertObject(h);
93 }
94 /* END object header */
95
96 /* BEGIN hash*/
97 //obj_addr_table is a generic hash table structure
98 //hash is an array of pointers that point to the beginning of a obj_listnode_t DS
99 // "size" in hash table is the no of indices in the hash table  and each index points to a pointer for an object_header  
100 void createHash(obj_addr_table_t *table, int size, float loadfactor)  {
101         int i;
102
103         if ((table->hash = (obj_listnode_t **) malloc(sizeof(obj_listnode_t *)*size)) == NULL) {
104                 printf("Malloc error %s %d\n", __FILE__, __LINE__);
105                 exit(-1);
106         }
107         for (i = 0; i < size; i++) {            // initialize the hash elements
108                 table->hash[i] = NULL;
109         }
110
111         table->size = size;
112         table->numelements = 0;
113         table->loadfactor = loadfactor;
114         
115         return;
116 }
117
118 // Hash Resize
119 void resize(obj_addr_table_t * table){
120         int newCapacity = 2*(table->size) + 1;
121         obj_listnode_t **old;
122         //if ((table->hash = (obj_listnode_t **) malloc(sizeof(obj_listnode_t *)*size)) == NULL) {
123 }
124
125 // Hashing for the Key
126 int hashKey(unsigned int oid, obj_addr_table_t *table) {
127         // hash32shiftmult
128         int c2=0x27d4eb2d; // a prime or an odd constant
129         oid = (oid ^ 61) ^ (oid >> 16);
130         oid = oid + (oid << 3);
131         oid = oid ^ (oid >> 4);
132         oid = oid * c2;
133         oid = oid ^ (oid >> 15);
134         printf("The bucket number is %d\n", oid % (table->size));
135         return (oid % (table->size));
136 }
137
138 //Add oid and its address to the new ob_listnode_t 
139 void addKey(unsigned int oid, obj_header_t *ptr, obj_addr_table_t *table) {
140         int index;
141         obj_listnode_t *node;
142         
143         table->numelements++;
144         if(table->numelements > (table->loadfactor * table->size)){
145         //TODO : check if table is nearly full and then resize
146         }
147
148         index = hashKey(oid,table);
149         if ((node = (obj_listnode_t *) malloc(sizeof(obj_listnode_t))) == NULL) {
150                 printf("Malloc error %s %d\n", __FILE__, __LINE__);
151                 exit(-1);
152         }
153         node->oid = oid;
154         node->object = ptr; 
155         node->next = table->hash[index];
156         table->hash[index] = node;
157         return;
158 }
159 // Get the address of the object header for a given oid
160 obj_header_t *findKey(unsigned int oid, obj_addr_table_t *table) {
161         int index;
162         obj_listnode_t *ptr;
163
164         index = hashKey(oid,table);
165         ptr = table->hash[index];
166         while(ptr != NULL) {
167                 if (ptr->oid == oid) {
168                         return ptr->object;
169                 }
170                 ptr = ptr->next;
171         }
172         return NULL;
173 }
174 // Remove the pointer to the object header from a linked list of obj_listnode_t given an oid
175 int removeKey(unsigned int oid, obj_addr_table_t *table) {
176         int index;
177         obj_listnode_t *curr, *prev;            // prev points to previous node and curr points to the node to be deleted
178
179         index = hashKey(oid,table);
180         prev = curr = table->hash[index];
181         for (; curr != NULL; curr = curr->next) {
182                 if (curr->oid == oid) {         // Find a match in the hash table
183                         table->numelements--;
184                         prev->next = curr->next;
185                         if (table->hash[index] == curr) { // Special case when there is one element pointed by  the hash table
186                                 table->hash[index] = NULL;
187                         }
188                         free(curr);
189                         return 0;
190                 } 
191                 prev = curr;
192         }
193         return -1;
194 }