Added Hash functionality and fixed minor bugs
[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 obj_listnode_t **hash;                  // points to beginning of hash table
5 unsigned int hash_size;                 // number of entries in hash table
6
7 extern int classsize[];
8
9 /* BEGIN - object store */
10 // Initializes the pointers...currently invoked inside main()
11 void dstm_init(void) {
12         obj_begin = NULL;
13         hash = NULL;
14         hash_size = 0;
15         return;
16 }
17 // Create a new object store of a given "size"  as a linked list
18 void create_objstr(unsigned int size) {
19         obj_store_t *tmp, *ptr;
20         static int id = 0; // keeps track of which object store is it when there are more than one object store 
21
22         if ((tmp = (obj_store_t *) malloc(sizeof(obj_store_t))) < 0) {
23                 printf("DSTM: Malloc error %s %d\n", __FILE__, __LINE__);
24                 exit(-1);
25         }
26         if ((tmp->base = (char *) malloc(sizeof(char)*size)) < 0) {
27                 printf("DSTM: Malloc error %s %d\n", __FILE__, __LINE__);
28                 exit(-1);
29         }
30         tmp->size = size;
31         tmp->top = tmp->base;
32         tmp->id = id++;
33         tmp->next = obj_begin;
34         obj_begin = tmp;
35         return;
36 }
37
38 // Delete the object store numbered "id"
39 void delete_objstr(int id) {
40         //TODO Implement this along with garbage collector
41         return;
42 }
43
44 obj_store_t *get_objstr_begin(void) {
45         return obj_begin;
46 }
47
48 /* END object store */
49
50 /* BEGIN object header */
51 // Get a new object id
52 int get_newID(void) {
53         static int id = 0;
54         
55         return ++id;
56 }
57 // Insert the object header and object into the object store
58 int insertObject(obj_header_t h) {
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                 obj_begin->top = obj_begin->top + sizeof(obj_header_t) + getObjSize(h);
68         } else {
69                 return -1;
70         }
71         //TODO Update obj_addr_table
72         addKey(h.oid, header);
73
74         return 0;
75 }
76 // Get the size of the object for a given type
77 int getObjSize(obj_header_t h) {
78         return classsize[h.type];
79 }
80 // Initial object when it is created at first
81 void createObject(unsigned short type) {
82         obj_header_t h;
83
84         h.oid = get_newID();
85         h.type = type;
86         h.version = 0;
87         h.rcount = 1;
88         h.status = CLEAN;
89         insertObject(h);
90 }
91 /* END object header */
92
93 /* BEGIN hash*/
94
95 //hash table is an array of pointers that point to the beginning of a obj_listnode_t DS
96 // "size" in hash table is the no of indices in the hash table  and each index points to a pointer for an object_header  
97 void createHash(int size)  {
98         int i;
99
100         if ((hash = (obj_listnode_t **) malloc(sizeof(obj_listnode_t *)*size)) == NULL) {
101                 printf("Malloc error %s %d\n", __FILE__, __LINE__);
102                 exit(-1);
103         }
104         for (i = 0; i < size; i++) {            // initialize the hash elements
105                 hash[i] = NULL;
106         }
107         hash_size = size;
108         return;
109 }
110
111 // Hashing for the Key
112 int hashkey(unsigned int oid) {
113         //TODO: Design a better hash function
114 //      return (hash_size % oid);
115         return (oid % hash_size);
116 }
117
118 //Add oid and its address to the new ob_listnode_t 
119 void addKey(unsigned int oid, obj_header_t *ptr) {
120         int index;
121         obj_listnode_t *node;
122
123         index = hashkey(oid);
124         if ((node = (obj_listnode_t *) malloc(sizeof(obj_listnode_t))) == NULL) {
125                 printf("Malloc error %s %d\n", __FILE__, __LINE__);
126                 exit(-1);
127         }
128         node->oid = oid;
129         node->object = ptr; 
130         node->next = hash[index];
131         hash[index] = node;
132         return;
133 }
134 // Get the address of the object header for a given oid
135 obj_header_t *findKey(unsigned int oid) {
136         int index;
137         obj_listnode_t *ptr;
138
139         index = hashkey(oid);
140         ptr = hash[index];
141         while(ptr != NULL) {
142                 if (ptr->oid == oid) {
143                         return ptr->object;
144                 }
145                 ptr = ptr->next;
146         }
147         return NULL;
148 }
149 // Remove the pointer to the object header from a linked list of obj_listnode_t given an oid
150 int removeKey(unsigned int oid) {
151         int index;
152         obj_listnode_t *curr, *prev;            // prev points to previous node and curr points to the node to be deleted
153
154         index = hashKey(oid);
155         prev = curr = hash[index];
156         for (; curr != NULL; curr = curr->next) {
157                 if (curr->oid == oid) {         // Find a match in the hash table
158                         prev->next = curr->next;
159                         if (hash[index] == curr) { // Special case when there is one element pointed by  the hash table
160                                 hash[index] = NULL;
161                         }
162                         free(curr);
163                         return 0;
164                 } 
165                 prev = curr;
166         }
167         return -1;
168 }