diff --git a/main.c b/main.c index 2828529..0866c4e 100644 --- a/main.c +++ b/main.c @@ -5,6 +5,7 @@ #include #include #include +#include #define WORD 32 #define TRANSFORM_TABLE_MAX_RAND 4294967296 @@ -24,11 +25,12 @@ typedef struct { char *key; + unsigned int keylen; + void *data; // gets set to 1 if another key, collides with this elemnts location u_int8_t encountered_collision; - // On collision, this field stores, where in the hash table array the second key (with the same hash) is located int next_key_location; @@ -37,12 +39,12 @@ typedef struct // Contains everything the functions for the hashtables need, to work with, including the hash table itself typedef struct { + // stores a transformation table used by the shash_hash function unsigned int *transformation_table; shash_table_element_t *hash_table; unsigned int table_size; } shash_hashtable_t; -// Returns -1 when the hashtable is full int get_empty_hashtable_slot(shash_hashtable_t *hashtable) { assert(hashtable != NULL); @@ -58,7 +60,7 @@ int get_empty_hashtable_slot(shash_hashtable_t *hashtable) int shash_init_hashtable(shash_hashtable_t *hashtable, unsigned int table_size) { - // Initialize the RNG to a non-constant value, to make the output less pseudo random + // Initialize the RNG to a non-constant seed, to make the output less pseudo random srand(time(NULL)); // Create a transformation table @@ -104,6 +106,20 @@ unsigned int shash_hash(char *key, unsigned int len, shash_hashtable_t *hashtabl return hash_word % hashtable->table_size; } +static bool is_key_in_slot(shash_table_element_t slot, char *key, unsigned int len) +{ + if(slot.keylen != len) + { + return 0; + } + unsigned int longer_key_lenght = slot.keylen > len ? slot.keylen : len; + if(strncmp(slot.key, key, longer_key_lenght) == 0) + { + return true; + } + return false; +} + int shash_set(char *key, unsigned int len, void *data, shash_hashtable_t *hashtable) { assert(key != NULL); @@ -111,9 +127,9 @@ int shash_set(char *key, unsigned int len, void *data, shash_hashtable_t *hashta assert(hashtable != NULL); unsigned int slot = shash_hash(key, len, hashtable); - + // Loop to the end of the linked list - while (hashtable->hash_table[slot].encountered_collision != 0 && strcmp(hashtable->hash_table[slot].key, key) != 0) + while (hashtable->hash_table[slot].encountered_collision != 0 && !is_key_in_slot(hashtable->hash_table[slot], key, len)) { slot = hashtable->hash_table[slot].next_key_location; } @@ -121,10 +137,11 @@ int shash_set(char *key, unsigned int len, void *data, shash_hashtable_t *hashta shash_table_element_t table_element = { .key = strndup(key, len), + .keylen = len, .data = data}; // If there is no element already in the slot, we can just use it - if (hashtable->hash_table[slot].key == 0) + if (hashtable->hash_table[slot].key == 0 || is_key_in_slot(hashtable->hash_table[slot], key, len)) { hashtable->hash_table[slot] = table_element; return EXIT_SUCCESS; @@ -153,7 +170,7 @@ void *shash_get(char *key, unsigned int len, shash_hashtable_t *hashtable) unsigned int slot = shash_hash(key, len, hashtable); // Itereate through the link list until we find the right element - while (strcmp(hashtable->hash_table[slot].key, key) != 0) + while (!is_key_in_slot(hashtable->hash_table[slot], key, len)) { if (hashtable->hash_table[slot].encountered_collision == 1) {