7 #define stricmp strcasecmp
11 // hash init assumes we get clean memory
12 void Hash_InitTable(hashtable_t *table, unsigned int numbucks, void *mem)
14 table->numbuckets = numbucks;
15 table->bucket = (bucket_t **)mem;
18 unsigned int Hash_Key(const char *name, unsigned int modulus)
21 for (key=0;*name; name++)
22 key += ((key<<3) + (key>>28) + *name);
26 unsigned int Hash_KeyInsensative(const char *name, unsigned int modulus)
29 for (key=0;*name; name++)
31 if (*name >= 'A' && *name <= 'Z')
32 key += ((key<<3) + (key>>28) + (*name-'A'+'a'));
34 key += ((key<<3) + (key>>28) + *name);
40 void *Hash_Get(hashtable_t *table, const char *name)
42 unsigned int bucknum = Hash_Key(name, table->numbuckets);
45 buck = table->bucket[bucknum];
49 if (!STRCMP(name, buck->key.string))
56 void *Hash_GetInsensative(hashtable_t *table, const char *name)
58 unsigned int bucknum = Hash_KeyInsensative(name, table->numbuckets);
61 buck = table->bucket[bucknum];
65 if (!stricmp(name, buck->key.string))
72 void *Hash_GetKey(hashtable_t *table, unsigned int key)
74 unsigned int bucknum = key%table->numbuckets;
77 buck = table->bucket[bucknum];
81 if (buck->key.value == key)
88 /*Does _NOT_ support items that are added with two names*/
89 void *Hash_GetNextKey(hashtable_t *table, unsigned int key, void *old)
91 unsigned int bucknum = key%table->numbuckets;
94 buck = table->bucket[bucknum];
98 if (buck->data == old) //found the old one
105 buck = buck->next;//don't return old
108 if (buck->key.value == key)
115 /*Does _NOT_ support items that are added with two names*/
116 void *Hash_GetNext(hashtable_t *table, const char *name, void *old)
118 unsigned int bucknum = Hash_Key(name, table->numbuckets);
121 buck = table->bucket[bucknum];
125 if (buck->data == old) //found the old one
126 // if (!STRCMP(name, buck->key.string))
133 buck = buck->next;//don't return old
136 if (!STRCMP(name, buck->key.string))
143 /*Does _NOT_ support items that are added with two names*/
144 void *Hash_GetNextInsensative(hashtable_t *table, const char *name, void *old)
146 unsigned int bucknum = Hash_KeyInsensative(name, table->numbuckets);
149 buck = table->bucket[bucknum];
153 if (buck->data == old) //found the old one
155 // if (!stricmp(name, buck->key.string))
164 buck = buck->next;//don't return old
167 if (!stricmp(name, buck->key.string))
176 void *Hash_Add(hashtable_t *table, const char *name, void *data, bucket_t *buck)
178 unsigned int bucknum = Hash_Key(name, table->numbuckets);
181 buck->key.string = name;
182 buck->next = table->bucket[bucknum];
183 table->bucket[bucknum] = buck;
187 void *Hash_AddInsensative(hashtable_t *table, const char *name, void *data, bucket_t *buck)
189 unsigned int bucknum = Hash_KeyInsensative(name, table->numbuckets);
192 buck->key.string = name;
193 buck->next = table->bucket[bucknum];
194 table->bucket[bucknum] = buck;
198 void *Hash_AddKey(hashtable_t *table, unsigned int key, void *data, bucket_t *buck)
200 unsigned int bucknum = key%table->numbuckets;
203 buck->key.value = key;
204 buck->next = table->bucket[bucknum];
205 table->bucket[bucknum] = buck;
210 void Hash_Remove(hashtable_t *table, const char *name)
212 unsigned int bucknum = Hash_Key(name, table->numbuckets);
215 buck = table->bucket[bucknum];
217 if (!STRCMP(name, buck->key.string))
219 table->bucket[bucknum] = buck->next;
226 if (!STRCMP(name, buck->next->key.string))
228 buck->next = buck->next->next;
237 void Hash_RemoveData(hashtable_t *table, const char *name, void *data)
239 unsigned int bucknum = Hash_Key(name, table->numbuckets);
242 buck = table->bucket[bucknum];
244 if (buck->data == data)
245 if (!STRCMP(name, buck->key.string))
247 table->bucket[bucknum] = buck->next;
254 if (buck->next->data == data)
255 if (!STRCMP(name, buck->next->key.string))
257 buck->next = buck->next->next;
267 void Hash_RemoveKey(hashtable_t *table, unsigned int key)
269 unsigned int bucknum = key%table->numbuckets;
272 buck = table->bucket[bucknum];
274 if (buck->key.value == key)
276 table->bucket[bucknum] = buck->next;
283 if (buck->next->key.value == key)
285 buck->next = buck->next->next;