Go to the source code of this file.
Data Structures | |
struct | cso_hash_iter |
Functions | |
struct cso_hash * | cso_hash_create (void) |
void | cso_hash_delete (struct cso_hash *hash) |
int | cso_hash_size (struct cso_hash *hash) |
struct cso_hash_iter | cso_hash_insert (struct cso_hash *hash, unsigned key, void *data) |
Adds a data with the given key to the hash. | |
struct cso_hash_iter | cso_hash_erase (struct cso_hash *hash, struct cso_hash_iter iter) |
Removes the item pointed to by the current iterator from the hash. | |
void * | cso_hash_take (struct cso_hash *hash, unsigned key) |
struct cso_hash_iter | cso_hash_first_node (struct cso_hash *hash) |
struct cso_hash_iter | cso_hash_find (struct cso_hash *hash, unsigned key) |
Return an iterator pointing to the first entry in the collision list. | |
int | cso_hash_iter_is_null (struct cso_hash_iter iter) |
unsigned | cso_hash_iter_key (struct cso_hash_iter iter) |
void * | cso_hash_iter_data (struct cso_hash_iter iter) |
struct cso_hash_iter | cso_hash_iter_next (struct cso_hash_iter iter) |
struct cso_hash_iter | cso_hash_iter_prev (struct cso_hash_iter iter) |
void * | cso_hash_find_data_from_template (struct cso_hash *hash, unsigned hash_key, void *templ, int size) |
Convenience routine to iterate over the collision list while doing a memory comparison to see which entry in the list is a direct copy of our template and returns that entry. |
This file provides a hash implementation that is capable of dealing with collisions. It stores colliding entries in linked list. All functions operating on the hash return an iterator. The iterator itself points to the collision list. If there wasn't any collision the list will have just one entry, otherwise client code should iterate over the entries to find the exact entry among ones that had the same key (e.g. memcmp could be used on the data to check that)
Definition in file cso_hash.h.
struct cso_hash* cso_hash_create | ( | void | ) | [read] |
Definition at line 238 of file cso_hash.c.
References cso_hash_data::buckets, cso_hash::d, cso_hash::data, cso_hash_data::fakeNext, FREE, MALLOC_STRUCT, MinNumBits, cso_hash_data::nodeSize, cso_hash_data::numBits, cso_hash_data::numBuckets, cso_hash_data::size, and cso_hash_data::userNumBits.
00239 { 00240 struct cso_hash *hash = MALLOC_STRUCT(cso_hash); 00241 if (!hash) 00242 return NULL; 00243 00244 hash->data.d = MALLOC_STRUCT(cso_hash_data); 00245 if (!hash->data.d) { 00246 FREE(hash); 00247 return NULL; 00248 } 00249 00250 hash->data.d->fakeNext = 0; 00251 hash->data.d->buckets = 0; 00252 hash->data.d->size = 0; 00253 hash->data.d->nodeSize = sizeof(struct cso_node); 00254 hash->data.d->userNumBits = (short)MinNumBits; 00255 hash->data.d->numBits = 0; 00256 hash->data.d->numBuckets = 0; 00257 00258 return hash; 00259 }
void cso_hash_delete | ( | struct cso_hash * | hash | ) |
Definition at line 261 of file cso_hash.c.
References cso_hash_data::buckets, cso_free_node(), cso_hash::d, cso_hash::data, FREE, cso_node::next, and cso_hash_data::numBuckets.
00262 { 00263 struct cso_node *e_for_x = (struct cso_node *)(hash->data.d); 00264 struct cso_node **bucket = (struct cso_node **)(hash->data.d->buckets); 00265 int n = hash->data.d->numBuckets; 00266 while (n--) { 00267 struct cso_node *cur = *bucket++; 00268 while (cur != e_for_x) { 00269 struct cso_node *next = cur->next; 00270 cso_free_node(cur); 00271 cur = next; 00272 } 00273 } 00274 FREE(hash->data.d->buckets); 00275 FREE(hash->data.d); 00276 FREE(hash); 00277 }
struct cso_hash_iter cso_hash_erase | ( | struct cso_hash * | hash, | |
struct cso_hash_iter | iter | |||
) | [read] |
Removes the item pointed to by the current iterator from the hash.
Note that the data itself is not erased and if it was a malloc'ed pointer it will have to be freed after calling this function by the callee. Function returns iterator pointing to the item after the removed one in the hash.
Definition at line 416 of file cso_hash.c.
References cso_free_node(), cso_hash_iter_next(), cso_node::key, cso_node::next, and cso_hash_iter::node.
00417 { 00418 struct cso_hash_iter ret = iter; 00419 struct cso_node *node = iter.node; 00420 struct cso_node **node_ptr; 00421 00422 if (node == hash->data.e) 00423 return iter; 00424 00425 ret = cso_hash_iter_next(ret); 00426 node_ptr = (struct cso_node**)(&hash->data.d->buckets[node->key % hash->data.d->numBuckets]); 00427 while (*node_ptr != node) 00428 node_ptr = &(*node_ptr)->next; 00429 *node_ptr = node->next; 00430 cso_free_node(node); 00431 --hash->data.d->size; 00432 return ret; 00433 }
struct cso_hash_iter cso_hash_find | ( | struct cso_hash * | hash, | |
unsigned | key | |||
) | [read] |
Return an iterator pointing to the first entry in the collision list.
Definition at line 279 of file cso_hash.c.
References cso_hash_find_node(), and cso_node::key.
00281 { 00282 struct cso_node **nextNode = cso_hash_find_node(hash, key); 00283 struct cso_hash_iter iter = {hash, *nextNode}; 00284 return iter; 00285 }
void* cso_hash_find_data_from_template | ( | struct cso_hash * | hash, | |
unsigned | hash_key, | |||
void * | templ, | |||
int | size | |||
) |
Convenience routine to iterate over the collision list while doing a memory comparison to see which entry in the list is a direct copy of our template and returns that entry.
Definition at line 263 of file cso_cache.c.
References cso_hash_find(), cso_hash_iter_data(), cso_hash_iter_is_null(), and cso_hash_iter_next().
00268 { 00269 struct cso_hash_iter iter = cso_hash_find(hash, hash_key); 00270 while (!cso_hash_iter_is_null(iter)) { 00271 void *iter_data = cso_hash_iter_data(iter); 00272 if (!memcmp(iter_data, templ, size)) { 00273 /* We found a match 00274 */ 00275 return iter_data; 00276 } 00277 iter = cso_hash_iter_next(iter); 00278 } 00279 return NULL;
struct cso_hash_iter cso_hash_first_node | ( | struct cso_hash * | hash | ) | [read] |
Definition at line 405 of file cso_hash.c.
References cso_data_first_node().
00406 { 00407 struct cso_hash_iter iter = {hash, cso_data_first_node(hash->data.d)}; 00408 return iter; 00409 }
struct cso_hash_iter cso_hash_insert | ( | struct cso_hash * | hash, | |
unsigned | key, | |||
void * | data | |||
) | [read] |
Adds a data with the given key to the hash.
If entry with the given key is already in the hash, this current entry is instered before it in the collision list. Function returns iterator pointing to the inserted item in the hash.
Definition at line 218 of file cso_hash.c.
References cso_data_might_grow(), cso_hash_create_node(), cso_hash_find_node(), and cso_node::key.
00220 { 00221 cso_data_might_grow(hash->data.d); 00222 00223 { 00224 struct cso_node **nextNode = cso_hash_find_node(hash, key); 00225 struct cso_node *node = cso_hash_create_node(hash, key, data, nextNode); 00226 if (!node) { 00227 struct cso_hash_iter null_iter = {hash, 0}; 00228 return null_iter; 00229 } 00230 00231 { 00232 struct cso_hash_iter iter = {hash, node}; 00233 return iter; 00234 } 00235 } 00236 }
void* cso_hash_iter_data | ( | struct cso_hash_iter | iter | ) |
Definition at line 294 of file cso_hash.c.
References cso_hash::data, cso_hash::e, cso_hash_iter::hash, cso_hash_iter::node, and cso_node::value.
00295 { 00296 if (!iter.node || iter.hash->data.e == iter.node) 00297 return 0; 00298 return iter.node->value; 00299 }
int cso_hash_iter_is_null | ( | struct cso_hash_iter | iter | ) |
Definition at line 375 of file cso_hash.c.
References cso_hash::data, cso_hash::e, cso_hash_iter::hash, and cso_hash_iter::node.
00376 { 00377 if (!iter.node || iter.node == iter.hash->data.e) 00378 return 1; 00379 return 0; 00380 }
unsigned cso_hash_iter_key | ( | struct cso_hash_iter | iter | ) |
Definition at line 287 of file cso_hash.c.
References cso_hash::data, cso_hash::e, cso_hash_iter::hash, cso_node::key, and cso_hash_iter::node.
00288 { 00289 if (!iter.node || iter.hash->data.e == iter.node) 00290 return 0; 00291 return iter.node->key; 00292 }
struct cso_hash_iter cso_hash_iter_next | ( | struct cso_hash_iter | iter | ) | [read] |
Definition at line 369 of file cso_hash.c.
References cso_hash_data_next(), and cso_hash_iter::hash.
00370 { 00371 struct cso_hash_iter next = {iter.hash, cso_hash_data_next(iter.node)}; 00372 return next; 00373 }
struct cso_hash_iter cso_hash_iter_prev | ( | struct cso_hash_iter | iter | ) | [read] |
Definition at line 398 of file cso_hash.c.
References cso_hash_data_prev(), and cso_hash_iter::hash.
00399 { 00400 struct cso_hash_iter prev = {iter.hash, 00401 cso_hash_data_prev(iter.node)}; 00402 return prev; 00403 }
int cso_hash_size | ( | struct cso_hash * | hash | ) |
Definition at line 411 of file cso_hash.c.
References cso_hash::d, cso_hash::data, and cso_hash_data::size.
void* cso_hash_take | ( | struct cso_hash * | hash, | |
unsigned | key | |||
) |
Definition at line 382 of file cso_hash.c.
References cso_data_has_shrunk(), cso_free_node(), cso_hash_find_node(), cso_hash::d, cso_hash::data, cso_hash::e, cso_node::next, and cso_hash_data::size.
00384 { 00385 struct cso_node **node = cso_hash_find_node(hash, akey); 00386 if (*node != hash->data.e) { 00387 void *t = (*node)->value; 00388 struct cso_node *next = (*node)->next; 00389 cso_free_node(*node); 00390 *node = next; 00391 --hash->data.d->size; 00392 cso_data_has_shrunk(hash->data.d); 00393 return t; 00394 } 00395 return 0; 00396 }