1 /* Martin Asser Hansen (mail@maasha.dk) Copyright (C) 2008 - All right reserved */
9 hash *hash_new( size_t size )
11 /* Martin A. Hansen, June 2008 */
13 /* Initialize a new generic hash structure. */
15 hash *new_hash = NULL;
16 size_t table_size = 0;
18 new_hash = mem_get( sizeof( new_hash ) );
20 table_size = 1 << size; /* table_size = ( 2 ** size ) */
22 new_hash->table_size = table_size;
23 new_hash->mask = table_size - 1;
24 new_hash->table = mem_get( sizeof( hash_elem * ) * table_size );
31 hash_elem *hash_elem_new()
33 /* Martin A. Hansen, November 2008. */
35 /* Initializes a new hash_elem structure. */
37 hash_elem *new_elem = NULL;
39 new_elem = mem_get( sizeof( hash_elem ) );
41 new_elem->next = NULL;
49 void hash_add( hash *hash_pt, char *key, void *val )
51 /* Martin A. Hansen, June 2008 */
53 /* Add a new hash element consisting of a key/value pair to an existing hash. */
55 hash_elem *old_elem = NULL;
56 hash_elem *new_elem = NULL;
57 size_t hash_index = 0;
59 if ( ( old_elem = hash_elem_get( hash_pt, key ) ) != NULL )
65 new_elem = hash_elem_new();
67 hash_index = ( hash_key( key ) & hash_pt->mask );
69 new_elem->key = mem_clone( key, strlen( key ) );
71 new_elem->next = hash_pt->table[ hash_index ];
73 hash_pt->table[ hash_index ] = new_elem;
79 void *hash_get( hash *hash_pt, char *key )
81 /* Martin A. Hansen, June 2008 */
83 /* Lookup a key in a given hash and return the value - or NULL if not found. */
87 bucket = hash_pt->table[ ( hash_key( key ) & hash_pt->mask ) ];
89 while ( bucket != NULL )
91 if ( strcmp( bucket->key, key ) == 0 ) {
95 bucket = bucket->next;
102 hash_elem *hash_elem_get( hash *hash_pt, char *key )
104 /* Martin A. Hansen, June 2008 */
106 /* Lookup a key in a given hash and return the hash element - or NULL if not found. */
110 bucket = hash_pt->table[ ( hash_key( key ) & hash_pt->mask ) ];
112 while ( bucket != NULL )
114 if ( strcmp( bucket->key, key ) == 0 ) {
118 bucket = bucket->next;
125 void hash_destroy( hash *hash_pt )
127 /* Martin A. Hansen, June 2008 */
129 /* Deallocate memory for hash and all hash elements. */
134 for ( i = 0; i < hash_pt->table_size; i++ )
136 for ( bucket = hash_pt->table[ i ]; bucket != NULL; bucket = bucket->next )
138 // mem_free( bucket->key );
139 // mem_free( bucket->val );
144 mem_free( hash_pt->table );
149 uint hash_key( char *string )
151 /* Martin A. Hansen, June 2008 */
153 /* Hash function that generates a hash key, */
154 /* based on the Jim Kent's stuff. */
160 while ( ( c = *key++ ) != '\0' ) {
161 result += ( result << 3 ) + c;
168 void hash_print( hash *hash_pt )
170 /* Martin A. Hansen, November 2008. */
172 /* Debug function that prints hash meta data and
173 * all hash elements. */
175 hash_elem *bucket = NULL;
178 printf( "table_size: %zu mask: %zu elem_count: %zu\n", hash_pt->table_size, hash_pt->mask, hash_pt->nmemb );
180 for ( i = 0; i < hash_pt->table_size; i++ )
182 bucket = hash_pt->table[ i ];
184 while ( bucket != NULL )
186 printf( "i: %zu key: %s val: %s\n", i, bucket->key, ( char * ) bucket->val );
188 bucket = bucket->next;
194 void hash_collision_stats( hash *hash_pt )
196 /* Martin A. Hansen, June 2008 */
198 /* Output some collision stats for a given hash. */
200 /* Use with Biopieces: ... | plot_histogram -k Col -x */
204 hash_elem *bucket = NULL;
206 for ( i = 0; i < hash_pt->table_size; i++ )
210 for ( bucket = hash_pt->table[ i ]; bucket != NULL; bucket = bucket->next ) {
214 printf( "Col: %zu\n---\n", col );