static int primes[] = {50,100,150,200,250,300,350,400,500,1000,2000,3000,4000,5000,10000,50000,70000}; int str_hash (signed char *v) { /* 31 bit hash function */ const signed char *p = v; int h = *p; if (h) for (p += 1; *p != '\0'; p++) h = (h << 5) - h + *p; return h; } typedef struct _HashNode { int hash; void *content; struct _HashNode * next; } HashNode; typedef struct _HashTable{ int free; int size_index; HashNode **nodes; } HashTable; HashTable* init_hash_table(){ HashTable *table = (HashTable*) calloc(1,sizeof(HashTable)); table->size_index = 0; size = primes[table->size_index]; table->free = size; table->nodes = (HashNode**) calloc(1, sizeof(HashNode*) * size); return table; } int hash_table_increase_size(HashTable *table){ int i, new_position, newsize, oldsize; newsize = primes[table->size_index + 1]; oldsize = primes[table->size_index]; HashNode **new_nodes = (HashNode**) calloc(1, sizeof(HashNode*) * newsize); if (new_nodes == NULL) return -1; for (i=0; i < oldsize; i++) { if (table->nodes[i] != NULL) { new_position = table->nodes[i]->hash % newsize; new_nodes[new_position] = table->nodes[i]; } } table->nodes = new_nodes; table->size_index++; table->free = table->free + (newsize - oldsize); return 1; } void insert_node(HashNode *node, HashTable *table) { int position; HashNode *scan; if (table->free < 2) hash_table_increase_size(table); position = node->hash % primes[table->size_index]; if (table->nodes[position] == NULL){ table->nodes[position] = node; table->free--; } else { scan = table->nodes[position]; while (scan->next != NULL){ scan = scan->next; } scan->next = node; } } HashNode* get_node(int hash, HashTable *table){ int position; HashNode *node; position = hash % primes[table->size_index]; node = table->nodes[position]; while (node != NULL){ if (node->hash == hash) { return node; } node = node->next; } return NULL; };