switch to spaces only..
[IRC.git] / Robust / src / Runtime / chash.c
1 #include "chash.h"
2
3 void crehash(ctable_t *table) {
4   cResize(table, table->size);
5 }
6
7 ctable_t *cCreate(unsigned int size, float loadfactor) {
8   ctable_t *ctable;
9   cnode_t *nodes;
10   int i;
11
12   if((ctable = calloc(1, sizeof(ctable_t))) == NULL) {
13     printf("Calloc error %s %d\n", __FILE__, __LINE__);
14     return NULL;
15   }
16
17   // Allocate space for the hash table
18   if((nodes = calloc(size, sizeof(cnode_t))) == NULL) {
19     printf("Calloc error %s %d\n", __FILE__, __LINE__);
20     free(ctable);
21     return NULL;
22   }
23
24   ctable->table = nodes;
25   ctable->size = size;
26   ctable->mask = (size << 2)-1;
27   ctable->numelements = 0; // Initial number of elements in the hash
28   ctable->loadfactor = loadfactor;
29   ctable->resize=loadfactor*size;
30   ctable->listhead=NULL;
31
32   return ctable;
33 }
34
35 //Store objects and their pointers into hash
36 INLINE void cInsert(ctable_t *table, void * key, void *val) {
37   unsigned int newsize;
38   int index;
39   cnode_t *ptr, *node;
40
41   ptr = &table->table[(((unsigned int)key) & table->mask)>>2];
42   if (ptr->key==0) {
43     ptr->key=key;
44     ptr->val=val;
45     ptr->lnext=table->listhead;
46     table->listhead=ptr;
47     return;
48   }
49
50   cnode_t *tmp=malloc(sizeof(cnode_t));
51   tmp->next=ptr->next;
52   ptr->next=tmp;
53   tmp->key=key;
54   tmp->val=val;
55   tmp->lnext=table->listhead;
56   table->listhead=tmp;
57
58   table->numelements++;
59   if(table->numelements > table->resize) {
60     newsize = table->size << 1;
61     cResize(table,newsize);
62   }
63 }
64
65 // Search for an address for a given oid
66 INLINE void * cSearch(ctable_t *table, void * key) {
67   //REMOVE HASH FUNCTION CALL TO MAKE SURE IT IS INLINED HERE
68   cnode_t *node = &table->table[(((unsigned int)key) & table->mask)>>2];
69
70   while(node != NULL) {
71     if(node->key == key) {
72       return node->val;
73     }
74     node = node->next;
75   }
76   return NULL;
77 }
78
79 unsigned int cRemove(ctable_t *table, void * key) {
80   int index;
81   cnode_t *curr, *prev;
82   cnode_t *ptr, *node;
83
84   ptr = table->table;
85   index =(((unsigned int)key) & table->mask)>>2;
86   curr = &ptr[index];
87
88   for (; curr != NULL; curr = curr->next) {
89     if (curr->key == key) {         // Find a match in the hash table
90       table->numelements--;  // Decrement the number of elements in the global hashtable
91       if ((curr == &ptr[index]) && (curr->next == NULL)) {  // Delete the first item inside the hashtable with no linked list of cnode_t
92         curr->key = 0;
93         curr->val = NULL;
94       } else if ((curr == &ptr[index]) && (curr->next != NULL)) { //Delete the first item with a linked list of cnode_t  connected
95         curr->key = curr->next->key;
96         curr->val = curr->next->val;
97         node = curr->next;
98         curr->next = curr->next->next;
99         free(node);
100       } else {                                          // Regular delete from linked listed
101         prev->next = curr->next;
102         free(curr);
103       }
104       return 0;
105     }
106     prev = curr;
107   }
108   return 1;
109 }
110
111 unsigned int cResize(ctable_t *table, unsigned int newsize) {
112   int i;
113   cnode_t *last=NULL;
114   int mask=(newsize<<2)-1;
115   int oldsize = table->size;
116   cnode_t *ptr = table->table;
117   cnode_t * ntable=calloc(newsize, sizeof(cnode_t));
118
119   table->table = ntable;
120   table->size = newsize;
121   table->mask = mask;
122   table->resize=newsize*table->loadfactor;
123
124   for(i = 0; i < oldsize; i++) {
125     int isfirst=1;
126     cnode_t * curr=&ptr[i];
127     if (curr->key==0)
128       continue;
129     while(curr!=NULL) {
130       cnode_t * next = curr->next;
131       int index =(((unsigned int)curr->key) & mask)>>2;
132       cnode_t * newnode=&ntable[index];
133
134       if(newnode->key==0) {
135         newnode->key=curr->key;
136         newnode->val=curr->val;
137         newnode->lnext=last;
138         last=newnode;
139       } else {
140         cnode_t *tmp=malloc(sizeof(cnode_t));
141         tmp->next=newnode->next;
142         newnode->next=tmp;
143         tmp->key=curr->key;
144         tmp->val=curr->val;
145         tmp->lnext=last;
146         last=tmp;
147       }
148       if (isfirst) {
149         isfirst=0;
150       } else {
151         free(curr);
152       }
153       curr = next;
154     }
155   }
156   table->listhead=last;
157   free(ptr);            //Free the memory of the old hash table
158   return 0;
159 }
160
161 //Delete the entire hash table
162 void cDelete(ctable_t *ctable) {
163   int i, isFirst;
164   cnode_t *ptr, *curr, *next;
165   ptr = ctable->table;
166
167   for(i=0; i<ctable->size; i++) {
168     curr = &ptr[i];
169     isFirst = 1;
170     while(curr  != NULL) {
171       next = curr->next;
172       if(isFirst != 1) {
173         free(curr);
174       }
175       isFirst = 0;
176       curr = next;
177     }
178   }
179
180   free(ptr);
181   ptr = NULL;
182   free(ctable);
183   ctable = NULL;
184 }