diff --git a/.github/workflows/CI.yml b/.github/workflows/CI.yml index 4d7dbb5..1e1658c 100644 --- a/.github/workflows/CI.yml +++ b/.github/workflows/CI.yml @@ -84,6 +84,7 @@ jobs: "print.c", "random.c", "tmpfile.c", + "hashtable.c", ] runs-on: ubuntu-latest steps: diff --git a/inc/libft.h b/inc/libft.h index c00e135..a51e65c 100644 --- a/inc/libft.h +++ b/inc/libft.h @@ -6,7 +6,7 @@ /* By: brda-sil item[i]; + while (ptr) + { + tmp = ptr->next; + free(ptr->key); + free(ptr); + ptr = tmp; + } + } + free(table->item); + free(table); +} diff --git a/src/hashtable/ft_ht_get.c b/src/hashtable/ft_ht_get.c new file mode 100644 index 0000000..681ef21 --- /dev/null +++ b/src/hashtable/ft_ht_get.c @@ -0,0 +1,26 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* ft_ht_get.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: brda-sil item[key_hash]; + t_size len_str = ft_strlen(key); + + while (ptr && ft_strncmp(ptr->key, key, len_str)) + ptr = ptr->next; + if (ptr) + return ptr->value; + return (FT_NULL); +} diff --git a/src/hashtable/ft_ht_hash_key.c b/src/hashtable/ft_ht_hash_key.c new file mode 100644 index 0000000..7f628b4 --- /dev/null +++ b/src/hashtable/ft_ht_hash_key.c @@ -0,0 +1,41 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* ft_ht_hash_key.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: brda-sil = k_len) + break ; + + hash = (hash * (*((t_uint32 *)(k + index)))); + index += 4; + } + + if (index != k_len) + { + unsigned char buff[4] = {0}; + + for (int i = 0; i + index < k_len; i++) + buff[i] = k[index + i]; + + hash = (hash * (*((t_uint32 *)(buff)))); + } + + return (hash % HT_SIZE); +} diff --git a/src/hashtable/ft_ht_item.c b/src/hashtable/ft_ht_item.c new file mode 100644 index 0000000..0a05e84 --- /dev/null +++ b/src/hashtable/ft_ht_item.c @@ -0,0 +1,33 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* ft_ht_item.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: brda-sil value = value; + ptr->key = ft_strdup(key); + return (ptr); +} + +ht_item *ft_ht_add_item(ht_item **item, char *key, void *value) +{ + ht_item **ptr = item; + + while (*ptr) + ptr = &((*ptr)->next); + *ptr = ft_ht_new_item(key, value); + return (*item); +} diff --git a/src/hashtable/ft_ht_len.c b/src/hashtable/ft_ht_len.c new file mode 100644 index 0000000..c9b8b6a --- /dev/null +++ b/src/hashtable/ft_ht_len.c @@ -0,0 +1,32 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* ft_ht_len.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: brda-sil value) + len++; + ptr = ptr->next; + } + } + return (len); +} diff --git a/src/hashtable/ft_ht_new.c b/src/hashtable/ft_ht_new.c new file mode 100644 index 0000000..2f2bc11 --- /dev/null +++ b/src/hashtable/ft_ht_new.c @@ -0,0 +1,22 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* ft_ht_new.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: brda-sil item = (ht_item **)ft_calloc(HT_SIZE, sizeof(ht_item *)); + return table; +} diff --git a/src/hashtable/ft_ht_set.c b/src/hashtable/ft_ht_set.c new file mode 100644 index 0000000..78ddf95 --- /dev/null +++ b/src/hashtable/ft_ht_set.c @@ -0,0 +1,24 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* ft_ht_set.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: brda-sil item[key_hash]) + table->item[key_hash] = ft_ht_new_item(key, value); + else + table->item[key_hash] = ft_ht_add_item(&table->item[key_hash], key, value); + return TRUE; +} diff --git a/test/src/hashtable.c b/test/src/hashtable.c new file mode 100644 index 0000000..2ab46c9 --- /dev/null +++ b/test/src/hashtable.c @@ -0,0 +1,131 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* hashtable.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: brda-sil + +#ifndef CI_TEST +# define CI_TEST FALSE +#endif + +t_bool KEY_TABLE[HT_SIZE] = {0}; + +t_bin test_hash_add_key(t_uint32 key) +{ + if (KEY_TABLE[key % HT_SIZE]) + return (TRUE); + KEY_TABLE[key % HT_SIZE] = TRUE; + return (FALSE); +} + +void test_hash(char *str) +{ + printf("k:"); + for (int i = 0; i < ft_strlen(str); i++) + printf("%02x", (unsigned char)str[i]); + + t_uint32 key = ft_ht_hash_key(str); + + printf("|h:%u", key); + + if (test_hash_add_key(key)) + printf(": Collision detected\n"); + else + printf(": GOOD\n"); +} + +int get_len_hash_table(void) +{ + int counter = 0; + + for (unsigned long int i = 0; i < HT_SIZE; i++) + if (KEY_TABLE[i]) + counter++; + return (counter); +} + +void test_collision(void) +{ + t_size size = 2; + char buff[size]; + + buff[size - 1] = 0; + + for (int i = 0; i <= 0xff; i++) + { buff[0] = i; + test_hash(buff); + } + printf("len %d\n", get_len_hash_table()); +} + +void ft_ht_enumerate(ht table) +{ + ht_item *ptr; + + for (unsigned long int i = 0; i < HT_SIZE; i++) + { + ptr = table.item[i]; + + while (ptr) + { + printf("[%03ld] %-9s %p\n", i, ptr->key, ptr->value); + ptr = ptr->next; + } + } +} + +ht *test_table(void) +{ + ht *table = ft_ht_new(); + char buff[10]; + int i; + + for (i = 0; i < 0xfff; i++) + { + ft_bzero(buff, 10); + ft_strcat(buff, "test_"); + char *tmp = ft_itoa(i); + ft_strcat(buff, tmp); + free(tmp); + // printf("%s -> %d\n", buff, ft_ht_hash_key(buff)); + ft_ht_set(table, buff, "value"); + } + printf("len table %ld\n", ft_ht_len(*table)); + return (table); +} + +int ci_test(void) +{ + test_collision(); + + ht *test = test_table(); + + ft_ht_enumerate(*test); + printf("%s\n", ft_ht_get(test, "test_1")); + ft_ht_free(test); + return (0); +} + +int interactive(void) +{ + return (0); +} + +int main(void) +{ + if (CI_TEST) + return (ci_test()); + else + return (interactive()); + return (0); +} +