This commit was manufactured by cvs2svn to create tag 'buildscript'.
[IRC.git] /
1  #include "clookup.h"
2
3 chashtable_t *chashCreate(unsigned int size, float loadfactor) {
4         chashtable_t *ctable;
5         chashlistnode_t *nodes; 
6         int i; 
7         
8         if((ctable = calloc(1, sizeof(chashtable_t))) == NULL) {
9                 printf("Calloc error %s %d\n", __FILE__, __LINE__);
10                 return NULL;
11         }       
12
13         // Allocate space for the hash table 
14         if((nodes = calloc(size, sizeof(chashlistnode_t))) == NULL) { 
15                 printf("Calloc error %s %d\n", __FILE__, __LINE__);
16                 free(ctable);
17                 return NULL;
18         }       
19
20         ctable->table = nodes;
21         ctable->size = size; 
22         ctable->numelements = 0; // Initial number of elements in the hash
23         ctable->loadfactor = loadfactor;
24         
25         return ctable;
26 }
27
28 //Finds the right bin in the hash table
29 unsigned int chashFunction(chashtable_t *table, unsigned int key) {
30         return ( key % (table->size));
31 }
32
33 //Store objects and their pointers into hash
34 unsigned int chashInsert(chashtable_t *table, unsigned int key, void *val) {
35         unsigned int newsize;
36         int index;
37         chashlistnode_t *ptr, *node;
38
39         if(table->numelements > (table->loadfactor * table->size)) {
40                 //Resize
41                 newsize = 2 * table->size + 1;
42                 chashResize(table,newsize);
43         }
44
45         ptr = table->table;
46         table->numelements++;
47         index = chashFunction(table, key);
48 #ifdef DEBUG
49         printf("DEBUG -> index = %d, key = %d, val = %x\n", index, key, val);
50 #endif
51         if(ptr[index].next == NULL && ptr[index].key == 0) {    // Insert at the first position in the hashtable
52                 ptr[index].key = key;
53                 ptr[index].val = val;
54         } else {                        // Insert in the beginning of linked list
55                 if ((node = calloc(1, sizeof(chashlistnode_t))) == NULL) {
56                         printf("Calloc error %s, %d\n", __FILE__, __LINE__);
57                         return 1;
58                 }
59                 node->key = key;
60                 node->val = val;
61                 node->next = ptr[index].next;
62                 ptr[index].next = node;
63         }
64         return 0;
65 }
66
67 // Search for an address for a given oid
68 void *chashSearch(chashtable_t *table, unsigned int key) {
69         int index;
70         chashlistnode_t *ptr, *node;
71
72         ptr = table->table;
73         index = chashFunction(table, key);
74         node = &ptr[index];
75         while(node != NULL) {
76                 if(node->key == key) {
77                         return node->val;
78                 }
79                 node = node->next;
80         }
81         return NULL;
82 }
83
84 unsigned int chashRemove(chashtable_t *table, unsigned int key) {
85         int index;
86         chashlistnode_t *curr, *prev;
87         chashlistnode_t *ptr, *node;
88         
89         ptr = table->table;
90         index = chashFunction(table,key);
91         curr = &ptr[index];
92
93         for (; curr != NULL; curr = curr->next) {
94                 if (curr->key == key) {         // Find a match in the hash table
95                         table->numelements--;  // Decrement the number of elements in the global hashtable
96                         if ((curr == &ptr[index]) && (curr->next == NULL))  { // Delete the first item inside the hashtable with no linked list of chashlistnode_t 
97                                 curr->key = 0;
98                                 curr->val = NULL;
99                         } else if ((curr == &ptr[index]) && (curr->next != NULL)) { //Delete the first item with a linked list of chashlistnode_t  connected 
100                                 curr->key = curr->next->key;
101                                 curr->val = curr->next->val;
102                                 node = curr->next;
103                                 curr->next = curr->next->next;
104                                 free(node);
105                         } else {                                                // Regular delete from linked listed    
106                                 prev->next = curr->next;
107                                 free(curr);
108                         }
109                         return 0;
110                 }       
111                 prev = curr; 
112         }
113         return 1;
114 }
115
116 unsigned int chashResize(chashtable_t *table, unsigned int newsize) {
117         chashlistnode_t *node, *ptr, *curr, *next;      // curr and next keep track of the current and the next chashlistnodes in a linked list
118         unsigned int oldsize;
119         int isfirst;    // Keeps track of the first element in the chashlistnode_t for each bin in hashtable
120         int i,index;    
121         chashlistnode_t *newnode;               
122         
123         ptr = table->table;
124         oldsize = table->size;
125         
126         if((node = calloc(newsize, sizeof(chashlistnode_t))) == NULL) {
127                 printf("Calloc error %s %d\n", __FILE__, __LINE__);
128                 return 1;
129         }
130
131         table->table = node;            //Update the global hashtable upon resize()
132         table->size = newsize;
133         table->numelements = 0;
134
135         for(i = 0; i < oldsize; i++) {                  //Outer loop for each bin in hash table
136                 curr = &ptr[i];
137                 isfirst = 1;                    
138                 while (curr != NULL) {                  //Inner loop to go through linked lists
139                         if (curr->key == 0) {           //Exit inner loop if there the first element for a given bin/index is NULL
140                                 break;                  //key = val =0 for element if not present within the hash table
141                         }
142                         next = curr->next;
143
144                         index = chashFunction(table, curr->key);
145 #ifdef DEBUG
146                         printf("DEBUG(resize) -> index = %d, key = %d, val = %x\n", index, curr->key, curr->val);
147 #endif
148                         // Insert into the new table
149                         if(table->table[index].next == NULL && table->table[index].key == 0) { 
150                                 table->table[index].key = curr->key;
151                                 table->table[index].val = curr->val;
152                                 table->numelements++;
153                         }else { 
154                                 if((newnode = calloc(1, sizeof(chashlistnode_t))) == NULL) { 
155                                         printf("Calloc error %s, %d\n", __FILE__, __LINE__);
156                                         return 1;
157                                 }       
158                                 newnode->key = curr->key;
159                                 newnode->val = curr->val;
160                                 newnode->next = table->table[index].next;
161                                 table->table[index].next = newnode;    
162                                 table->numelements++;
163                         }       
164
165                         //free the linked list of chashlistnode_t if not the first element in the hash table
166                         if (isfirst != 1) {
167                                 free(curr);
168                         } 
169                         
170                         isfirst = 0;
171                         curr = next;
172                 }
173         }
174
175         free(ptr);              //Free the memory of the old hash table 
176         return 0;
177 }
178
179 //Delete the entire hash table
180 void chashDelete(chashtable_t *table) {
181         int i, isFirst;
182         chashlistnode_t *ptr, *curr, *next;
183         ptr = table->table;
184
185         for(i=0 ; i<table->size ; i++) {
186                 curr = &ptr[i];
187                 isFirst = 1 ;
188                 while(curr  != NULL) {
189                         next = curr->next;
190                         if(isFirst != 1) {
191                                 free(curr);
192                         }
193                         isFirst = 0;
194                         curr = next;
195                 }
196         }
197
198         free(ptr);
199         free(table);
200         table = NULL;
201 }