cso_hash.h File Reference

Hash table implementation. More...

This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Data Structures

struct  cso_hash_iter

Functions

struct cso_hashcso_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.


Detailed Description

Hash table implementation.

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)

Author:
Zack Rusin <zack@tungstengraphics.com>

Definition in file cso_hash.h.


Function Documentation

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.

00412 {
00413    return hash->data.d->size;
00414 }

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 }


Generated on Tue Sep 29 06:25:19 2009 for Gallium3D by  doxygen 1.5.4