From 5fcd07cd7e5bb44bf5a14f6a6c3350ade2d5ec02 Mon Sep 17 00:00:00 2001 From: Harou Date: Sat, 17 Apr 2021 01:12:48 +0200 Subject: [PATCH 1/6] 42 normed with keeping cmake --- lib/pair | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/pair b/lib/pair index 6295fb3..a06c672 160000 --- a/lib/pair +++ b/lib/pair @@ -1 +1 @@ -Subproject commit 6295fb334af42b1581e0cd7d15d739c56856d33b +Subproject commit a06c672d9922ad711f7649f68b8ef2858ee41066 From 6ad6f23536f0289dd0aa9cc17513a31d5c37f28a Mon Sep 17 00:00:00 2001 From: Harou Date: Sat, 17 Apr 2021 01:17:09 +0200 Subject: [PATCH 2/6] .c files and .h files normed --- inc/hashmap.h | 23 +- inc/hashmap_internal.h | 48 ++- src/add_node_to_history.c | 30 ++ src/find_node_by_key.c | 26 ++ src/hash.c | 31 ++ src/hash_map.c | 373 ------------------ src/history_destroy.c | 27 ++ src/hm_add_new_key.c | 39 ++ src/hm_destroy.c | 34 ++ src/hm_find_existing_node_and_replace_value.c | 38 ++ src/hm_get.c | 37 ++ src/hm_get_collision_count.c | 20 + src/hm_get_seq.c | 37 ++ src/hm_handle_collision.c | 26 ++ src/hm_insert_node.c | 35 ++ src/hm_new.c | 25 ++ src/hm_remove.c | 35 ++ src/hm_set.c | 51 +++ src/new_node.c | 26 ++ src/node_destroy.c | 20 + src/node_remove_from_list.c | 25 ++ 21 files changed, 604 insertions(+), 402 deletions(-) create mode 100644 src/add_node_to_history.c create mode 100644 src/find_node_by_key.c create mode 100644 src/hash.c delete mode 100644 src/hash_map.c create mode 100644 src/history_destroy.c create mode 100644 src/hm_add_new_key.c create mode 100644 src/hm_destroy.c create mode 100644 src/hm_find_existing_node_and_replace_value.c create mode 100644 src/hm_get.c create mode 100644 src/hm_get_collision_count.c create mode 100644 src/hm_get_seq.c create mode 100644 src/hm_handle_collision.c create mode 100644 src/hm_insert_node.c create mode 100644 src/hm_new.c create mode 100644 src/hm_remove.c create mode 100644 src/hm_set.c create mode 100644 src/new_node.c create mode 100644 src/node_destroy.c create mode 100644 src/node_remove_from_list.c diff --git a/inc/hashmap.h b/inc/hashmap.h index 0bc1f63..74fcd34 100644 --- a/inc/hashmap.h +++ b/inc/hashmap.h @@ -10,19 +10,18 @@ /* */ /* ************************************************************************** */ -#ifndef LIBHASHMAP_H -# define LIBHASHMAP_H +#ifndef HASHMAP_H +# define HASHMAP_H -#include -#include "pair.h" +# include +# include "pair.h" -void *hm_new(size_t _size); -void hm_destroy(void *_hm, void (*f)(void *)); -void *hm_set(void *_hm, const char *_key, void *_value); -size_t hm_size(const void *_hm); -void *hm_get(const void *_hm, const char *_key); -t_pair hm_get_seq(const void *_hm); -size_t hm_get_collision_count(void *_hm); -void hm_remove(void *_hm, const char *_key, void (*_ft_delete)(void*)); +void *hm_new(size_t _size); +void hm_destroy(void *_hm, void (*f)(void *)); +void *hm_set(void *_hm, const char *_key, void *_value); +void *hm_get(const void *_hm, const char *_key); +t_pair hm_get_seq(const void *_hm); +size_t hm_get_collision_count(void *_hm); +void hm_remove(void *_hm, const char *_key, void (*_ft_delete)(void*)); #endif diff --git a/inc/hashmap_internal.h b/inc/hashmap_internal.h index 9862b3d..00814ff 100644 --- a/inc/hashmap_internal.h +++ b/inc/hashmap_internal.h @@ -1,26 +1,40 @@ -#ifndef LIBHASHMAP_INTERNAL_H -# define LIBHASHMAP_INTERNAL_H +#ifndef HASHMAP_INTERNAL_H +# define HASHMAP_INTERNAL_H # include # include # include "libft.h" # include "hashmap.h" -typedef struct s_hm_node { - char *key; - void *value; - struct s_hm_node *next; - struct s_hm_node *prev; -} t_hm_node; +typedef struct s_hm_node { + struct s_hm_node *next; + struct s_hm_node *prev; + char *key; + void *value; +} t_hm_node; -typedef struct s_hash_map { - t_hm_node **nodes; - t_hm_node *first_node; - t_hm_node *last_node; - t_hm_node *history; - size_t collisions; - size_t cap; - size_t size; -} t_hash_map; +typedef struct s_hash_map { + t_hm_node **nodes; + t_hm_node *first_node; + t_hm_node *last_node; + t_hm_node *history; + size_t collisions; + size_t cap; + size_t size; +} t_hash_map; +uint64_t hash(const size_t cap, const char *key); +t_hm_node *new_node(const char *_key, void *_value); +void add_node_to_history(t_hm_node **root, t_hm_node *node); +void history_destroy(t_hm_node *root, void (*f)(void *)); +t_hm_node *find_node_by_key(t_hm_node *_node, const char *_key); +void node_remove_from_list(t_hash_map *_hm, t_hm_node *_node); +void *hm_add_new_key(t_hash_map *hm, t_hm_node **node, + const char *_key, void *_value); +void node_destroy(t_hm_node *_to_destroy, void (*_ft_delete)(void*)); +void *hm_find_existing_node_and_replace_value(t_hash_map *hm, + t_hm_node *node_at_index, const char *_key, void *_value); +void *hm_insert_node(t_hash_map *hm, t_hm_node *node, t_hm_node *new); +void *hm_handle_collision(t_hash_map *hm, + t_hm_node *node, const char *_key, void *_value); #endif diff --git a/src/add_node_to_history.c b/src/add_node_to_history.c new file mode 100644 index 0000000..134674e --- /dev/null +++ b/src/add_node_to_history.c @@ -0,0 +1,30 @@ +/* ************************************************************************** */ +/* */ +/* :::::::: */ +/* main.c :+: :+: */ +/* +:+ */ +/* By: haachtch +#+ */ +/* +#+ */ +/* Created: 2020/07/13 09:34:21 by haachtch #+# #+# */ +/* Updated: 2020/09/03 14:12:42 by haachtch ######## odam.nl */ +/* */ +/* ************************************************************************** */ + +#include "hashmap_internal.h" + +void add_node_to_history(t_hm_node **root, t_hm_node *node) +{ + t_hm_node *lst; + + if (!*root) + { + (*root) = node; + } + else + { + lst = *root; + while (lst->next) + lst = lst->next; + lst->next = node; + } +} diff --git a/src/find_node_by_key.c b/src/find_node_by_key.c new file mode 100644 index 0000000..740a26d --- /dev/null +++ b/src/find_node_by_key.c @@ -0,0 +1,26 @@ +/* ************************************************************************** */ +/* */ +/* :::::::: */ +/* main.c :+: :+: */ +/* +:+ */ +/* By: haachtch +#+ */ +/* +#+ */ +/* Created: 2020/07/13 09:34:21 by haachtch #+# #+# */ +/* Updated: 2020/09/03 14:12:42 by haachtch ######## odam.nl */ +/* */ +/* ************************************************************************** */ + +#include "hashmap_internal.h" + +t_hm_node *find_node_by_key(t_hm_node *_node, const char *_key) +{ + while (_node) + { + if (ft_strcmp(_key, _node->key) == 0) + break ; + _node = _node->next; + } + if (!_node || ft_strcmp(_key, _node->key) != 0) + return (NULL); + return (_node); +} diff --git a/src/hash.c b/src/hash.c new file mode 100644 index 0000000..bf51f9a --- /dev/null +++ b/src/hash.c @@ -0,0 +1,31 @@ +/* ************************************************************************** */ +/* */ +/* :::::::: */ +/* main.c :+: :+: */ +/* +:+ */ +/* By: haachtch +#+ */ +/* +#+ */ +/* Created: 2020/07/13 09:34:21 by haachtch #+# #+# */ +/* Updated: 2020/09/03 14:12:42 by haachtch ######## odam.nl */ +/* */ +/* ************************************************************************** */ + +#include "hashmap_internal.h" + +uint64_t hash(const size_t cap, const char *key) +{ + uint64_t value; + size_t i; + size_t length; + + value = 0; + i = 0; + length = ft_strlen(key); + while (i < length) + { + value = value * 37 + key[i]; + i++; + } + value = value % cap; + return (value); +} diff --git a/src/hash_map.c b/src/hash_map.c deleted file mode 100644 index 9ecec3e..0000000 --- a/src/hash_map.c +++ /dev/null @@ -1,373 +0,0 @@ -/* ************************************************************************** */ -/* */ -/* :::::::: */ -/* main.c :+: :+: */ -/* +:+ */ -/* By: haachtch +#+ */ -/* +#+ */ -/* Created: 2020/07/13 09:34:21 by haachtch #+# #+# */ -/* Updated: 2020/09/03 14:12:42 by haachtch ######## odam.nl */ -/* */ -/* ************************************************************************** */ - -#include - -#include "hashmap_internal.h" - -static uint64_t hash(const size_t cap, const char *key) -{ - uint64_t value; - size_t i; - size_t length; - - value = 0; - i = 0; - length = ft_strlen(key); - while (i < length) - { - value = value * 37 + key[i]; - i++; - } - value = value % cap; - return (value); -} - -static t_hm_node *new_node(const char *_key, void *_value) -{ - t_hm_node *node; - - node = ft_calloc(sizeof(t_hm_node), 1); - if (node) - { - node->key = ft_strdup(_key); - node->value = _value; - } - return (node); -} - -static void add_node_to_history(t_hm_node **root, t_hm_node *node) -{ - t_hm_node *lst; - - if (!*root) - { - (*root) = node; - } - else - { - lst = *root; - while(lst->next) - lst = lst->next; - lst->next = node; - } -} - -static void history_destroy(t_hm_node *root, void (*f)(void *)) -{ - t_hm_node *prev; - - while(root) - { - prev = root; - root = root->next; - f(prev->value); - free(prev->key); - free(prev); - } -} - -void *hm_new(size_t _cap) -{ - t_hash_map *hm; - - if (_cap == 0) - return (NULL); - hm = ft_calloc(sizeof(t_hash_map), 1); - hm->nodes = ft_calloc(sizeof(t_hm_node*), _cap); - hm->cap = _cap; - return ((void *)hm); -} - -void hm_destroy(void *_hm, void (*f)(void *)) -{ - t_hash_map *hm; - t_hm_node *node; - t_hm_node *dnode; - - hm = (t_hash_map *)_hm; - node = hm->first_node; - while(node) - { - dnode = node; - node = node->next; - f(dnode->value); - free(dnode->key); - free(dnode); - } - free(hm->nodes); - history_destroy(hm->history, f); - free(hm); -} - -static t_hm_node *find_node_by_key(t_hm_node *_node, const char *_key) -{ - while(_node) - { - if (ft_strcmp(_key, _node->key) == 0) - break ; - _node = _node->next; - } - if (!_node || ft_strcmp(_key, _node->key) != 0) - return (NULL); - return (_node); -} - -static void node_remove_from_list(t_hash_map *_hm, t_hm_node *_node) -{ - if (_node->prev) - _node->prev->next = _node->next; - else - _hm->first_node = _node->next; - if (_node->next) - _node->next->prev = _node->prev; - else - _hm->last_node = _node->prev; -} - -void node_destroy(t_hm_node *node, void (*ft_free)(void*)) -{ - if (ft_free) - { - free(node->key); - ft_free(node->value); - } - free(node); -} - -void hm_remove(void *_hm, const char *_key, void (*ft_free)(void*)) -{ - size_t checksum; - t_hash_map *hm; - t_hm_node *node; - - hm = (t_hash_map *)_hm; - checksum = hash(hm->cap, _key); - node = hm->nodes[checksum]; - if (node) - { - if (ft_strcmp(node->key, _key) != 0) - { - /* collision */ - if (!node->next) - return; - node = find_node_by_key(node->next, _key); - if (!node) - return; - } - node_remove_from_list(_hm, node); - node_destroy(node, ft_free); - hm->nodes[checksum] = NULL; - } -} - -static void *hm_add_new_key(t_hash_map *hm, - t_hm_node **node, - const char *_key, - void *_value) -{ - *node = new_node(_key, _value); - if (*node) - { - hm->size++; - if (!hm->last_node) - { - assert(!hm->first_node); - hm->first_node = *node; - hm->last_node = *node; - } - else - { - hm->last_node->next = *node; - (*node)->prev = hm->last_node; - hm->last_node = *node; - } - return (_value); - } - else - return (NULL); -} - -static void *hm_find_existing_node_and_replace_value(t_hash_map *hm, - t_hm_node *node_at_index, - const char *_key, - void *_value) -{ - void *old_value; - t_hm_node *prev; - - assert(node_at_index); - assert(_key); - prev = node_at_index; - while (node_at_index->next) - { - node_at_index = node_at_index->next; - if (ft_strcmp(node_at_index->key, _key) == 0) - { - /* we found the same key */ - old_value = node_at_index->value; - - /* dead key, add to history -> IS THIS NECCESSARY?*/ - add_node_to_history(&hm->history, new_node(node_at_index->key, old_value)); - - node_at_index->value = _value; - return (NULL); - } - prev = node_at_index; - } - return (prev); -} - -static void *hm_insert_node(t_hash_map *hm, t_hm_node *node, t_hm_node *new) -{ - assert(node); - assert(new); - if (node->next) { - t_hm_node *node_next = node->next; - node->next = new; - new->prev = node; - new->next = node_next; - node_next->prev = new; - } - else { - node->next = new; - node->next->prev = node; - hm->last_node = new; - } - hm->size++; - return (new->value); -} - -static void *hm_handle_collision(t_hash_map *hm, - t_hm_node *node, - const char *_key, - void *_value) -{ - t_hm_node *last; - - last = hm_find_existing_node_and_replace_value(hm, node, _key, _value); - if (!last) /* NULL indicates a key was found */ - return (_value); - - /* only gets here if this is a different key */ - return (hm_insert_node(hm, node, new_node(_key, _value))); -} - -void *hm_set(void *_hm, - const char *_key, - void *_value) -{ - void *old_value; - t_hash_map *hm; - t_hm_node **node; - - if (_key == NULL) - return (NULL); - hm = (t_hash_map *)_hm; - node = &hm->nodes[hash(hm->cap, _key)]; - if (*node) - { - if (ft_strcmp((*node)->key, _key) != 0) - { - /* a collision happened */ - hm->collisions++; - assert(hm->first_node); - assert(hm->last_node); - assert(((*node)->prev || (*node)->next) || hm->size == 1); - return (hm_handle_collision(hm, *node, _key, _value)); - } - else - { - /* update value for key */ - hm->size++; - old_value = (*node)->value; - (*node)->value = _value; - - /* store ref to old value here */ - add_node_to_history(&hm->history, new_node((*node)->key, old_value)); - return ((*node)->value); - } - } - else - return (hm_add_new_key(hm, node, _key, _value)); -} - -size_t hm_size(const void *_hm) -{ - const t_hash_map *hm = (t_hash_map *)_hm; - - return (hm->size); -} - -t_pair hm_get_seq(const void *_hm) -{ - const t_hash_map *hm = (t_hash_map *)_hm; - static t_hm_node *node; - t_pair pair; - - if (_hm == NULL) - { - node = NULL; - pair.f.key = NULL; - pair.s.value = NULL; - return (pair); - } - - node = (node != NULL) ? node->next : hm->first_node; - if (node) - { - pair.f.key = node->key; - pair.s.value = node->value; - } - else - { - node = hm->first_node; - pair.f.key = NULL; - pair.s.value = NULL; - } - return (pair); -} - -void *hm_get(const void *_hm, const char *_key) -{ - const t_hash_map *hm = (t_hash_map *)_hm; - t_hm_node *node; - - if (_key == NULL) - return (NULL); - node = hm->nodes[hash(hm->cap, _key)]; - - /* verify with strcmp if key is actually key ? */ - - if (node && node->next) - { - /* check for collision */ - while (node) - { - if (ft_strcmp(node->key, _key) == 0) - return (node->value); - node = node->next; - } - return (NULL); - } - else if (node) - return (node->value); - else - return (NULL); -} - -size_t hm_get_collision_count(void *_hm) -{ - const t_hash_map *hm = (t_hash_map *)_hm; - - return (hm->collisions); -} diff --git a/src/history_destroy.c b/src/history_destroy.c new file mode 100644 index 0000000..2307d8f --- /dev/null +++ b/src/history_destroy.c @@ -0,0 +1,27 @@ +/* ************************************************************************** */ +/* */ +/* :::::::: */ +/* main.c :+: :+: */ +/* +:+ */ +/* By: haachtch +#+ */ +/* +#+ */ +/* Created: 2020/07/13 09:34:21 by haachtch #+# #+# */ +/* Updated: 2020/09/03 14:12:42 by haachtch ######## odam.nl */ +/* */ +/* ************************************************************************** */ + +#include "hashmap_internal.h" + +void history_destroy(t_hm_node *root, void (*f)(void *)) +{ + t_hm_node *prev; + + while (root) + { + prev = root; + root = root->next; + f(prev->value); + free(prev->key); + free(prev); + } +} diff --git a/src/hm_add_new_key.c b/src/hm_add_new_key.c new file mode 100644 index 0000000..797d596 --- /dev/null +++ b/src/hm_add_new_key.c @@ -0,0 +1,39 @@ +/* ************************************************************************** */ +/* */ +/* :::::::: */ +/* main.c :+: :+: */ +/* +:+ */ +/* By: haachtch +#+ */ +/* +#+ */ +/* Created: 2020/07/13 09:34:21 by haachtch #+# #+# */ +/* Updated: 2020/09/03 14:12:42 by haachtch ######## odam.nl */ +/* */ +/* ************************************************************************** */ + +#include "hashmap_internal.h" + +void *hm_add_new_key(t_hash_map *hm, + t_hm_node **node, + const char *_key, + void *_value) +{ + *node = new_node(_key, _value); + if (*node) + { + hm->size++; + if (!hm->last_node) + { + hm->first_node = *node; + hm->last_node = *node; + } + else + { + hm->last_node->next = *node; + (*node)->prev = hm->last_node; + hm->last_node = *node; + } + return (_value); + } + else + return (NULL); +} diff --git a/src/hm_destroy.c b/src/hm_destroy.c new file mode 100644 index 0000000..84f4319 --- /dev/null +++ b/src/hm_destroy.c @@ -0,0 +1,34 @@ +/* ************************************************************************** */ +/* */ +/* :::::::: */ +/* main.c :+: :+: */ +/* +:+ */ +/* By: haachtch +#+ */ +/* +#+ */ +/* Created: 2020/07/13 09:34:21 by haachtch #+# #+# */ +/* Updated: 2020/09/03 14:12:42 by haachtch ######## odam.nl */ +/* */ +/* ************************************************************************** */ + +#include "hashmap_internal.h" + +void hm_destroy(void *_hm, void (*f)(void *)) +{ + t_hash_map *hm; + t_hm_node *node; + t_hm_node *dnode; + + hm = (t_hash_map *)_hm; + node = hm->first_node; + while (node) + { + dnode = node; + node = node->next; + f(dnode->value); + free(dnode->key); + free(dnode); + } + free(hm->nodes); + history_destroy(hm->history, f); + free(hm); +} diff --git a/src/hm_find_existing_node_and_replace_value.c b/src/hm_find_existing_node_and_replace_value.c new file mode 100644 index 0000000..430890a --- /dev/null +++ b/src/hm_find_existing_node_and_replace_value.c @@ -0,0 +1,38 @@ +/* ************************************************************************** */ +/* */ +/* :::::::: */ +/* main.c :+: :+: */ +/* +:+ */ +/* By: haachtch +#+ */ +/* +#+ */ +/* Created: 2020/07/13 09:34:21 by haachtch #+# #+# */ +/* Updated: 2020/09/03 14:12:42 by haachtch ######## odam.nl */ +/* */ +/* ************************************************************************** */ + +#include "hashmap_internal.h" + +void *hm_find_existing_node_and_replace_value(t_hash_map *hm, + t_hm_node *node_at_index, + const char *_key, + void *_value) +{ + void *old_value; + t_hm_node *prev; + + prev = node_at_index; + while (node_at_index->next) + { + node_at_index = node_at_index->next; + if (ft_strcmp(node_at_index->key, _key) == 0) + { + old_value = node_at_index->value; + add_node_to_history(&hm->history, + new_node(node_at_index->key, old_value)); + node_at_index->value = _value; + return (NULL); + } + prev = node_at_index; + } + return (prev); +} diff --git a/src/hm_get.c b/src/hm_get.c new file mode 100644 index 0000000..f20811a --- /dev/null +++ b/src/hm_get.c @@ -0,0 +1,37 @@ +/* ************************************************************************** */ +/* */ +/* :::::::: */ +/* main.c :+: :+: */ +/* +:+ */ +/* By: haachtch +#+ */ +/* +#+ */ +/* Created: 2020/07/13 09:34:21 by haachtch #+# #+# */ +/* Updated: 2020/09/03 14:12:42 by haachtch ######## odam.nl */ +/* */ +/* ************************************************************************** */ + +#include "hashmap_internal.h" + +void *hm_get(const void *_hm, const char *_key) +{ + const t_hash_map *hm = (t_hash_map *)_hm; + t_hm_node *node; + + if (_key == NULL) + return (NULL); + node = hm->nodes[hash(hm->cap, _key)]; + if (node && node->next) + { + while (node) + { + if (ft_strcmp(node->key, _key) == 0) + return (node->value); + node = node->next; + } + return (NULL); + } + else if (node) + return (node->value); + else + return (NULL); +} diff --git a/src/hm_get_collision_count.c b/src/hm_get_collision_count.c new file mode 100644 index 0000000..954bd96 --- /dev/null +++ b/src/hm_get_collision_count.c @@ -0,0 +1,20 @@ +/* ************************************************************************** */ +/* */ +/* :::::::: */ +/* main.c :+: :+: */ +/* +:+ */ +/* By: haachtch +#+ */ +/* +#+ */ +/* Created: 2020/07/13 09:34:21 by haachtch #+# #+# */ +/* Updated: 2020/09/03 14:12:42 by haachtch ######## odam.nl */ +/* */ +/* ************************************************************************** */ + +#include "hashmap_internal.h" + +size_t hm_get_collision_count(void *_hm) +{ + const t_hash_map *hm = (t_hash_map *)_hm; + + return (hm->collisions); +} diff --git a/src/hm_get_seq.c b/src/hm_get_seq.c new file mode 100644 index 0000000..7359ac0 --- /dev/null +++ b/src/hm_get_seq.c @@ -0,0 +1,37 @@ +/* ************************************************************************** */ +/* */ +/* :::::::: */ +/* main.c :+: :+: */ +/* +:+ */ +/* By: haachtch +#+ */ +/* +#+ */ +/* Created: 2020/07/13 09:34:21 by haachtch #+# #+# */ +/* Updated: 2020/09/03 14:12:42 by haachtch ######## odam.nl */ +/* */ +/* ************************************************************************** */ + +#include "hashmap_internal.h" + +t_pair hm_get_seq(const void *_hm) +{ + const t_hash_map *hm = (t_hash_map *)_hm; + static t_hm_node *node; + t_pair pair; + + if (node) + node = node->next; + else + node = hm->first_node; + if (node) + { + pair.u_f.key = node->key; + pair.u_s.value = node->value; + } + else + { + node = hm->first_node; + pair.u_f.key = NULL; + pair.u_s.value = NULL; + } + return (pair); +} diff --git a/src/hm_handle_collision.c b/src/hm_handle_collision.c new file mode 100644 index 0000000..46d595f --- /dev/null +++ b/src/hm_handle_collision.c @@ -0,0 +1,26 @@ +/* ************************************************************************** */ +/* */ +/* :::::::: */ +/* main.c :+: :+: */ +/* +:+ */ +/* By: haachtch +#+ */ +/* +#+ */ +/* Created: 2020/07/13 09:34:21 by haachtch #+# #+# */ +/* Updated: 2020/09/03 14:12:42 by haachtch ######## odam.nl */ +/* */ +/* ************************************************************************** */ + +#include "hashmap_internal.h" + +void *hm_handle_collision(t_hash_map *hm, + t_hm_node *node, + const char *_key, + void *_value) +{ + t_hm_node *last; + + last = hm_find_existing_node_and_replace_value(hm, node, _key, _value); + if (!last) + return (_value); + return (hm_insert_node(hm, node, new_node(_key, _value))); +} diff --git a/src/hm_insert_node.c b/src/hm_insert_node.c new file mode 100644 index 0000000..f0fe0e4 --- /dev/null +++ b/src/hm_insert_node.c @@ -0,0 +1,35 @@ +/* ************************************************************************** */ +/* */ +/* :::::::: */ +/* main.c :+: :+: */ +/* +:+ */ +/* By: haachtch +#+ */ +/* +#+ */ +/* Created: 2020/07/13 09:34:21 by haachtch #+# #+# */ +/* Updated: 2020/09/03 14:12:42 by haachtch ######## odam.nl */ +/* */ +/* ************************************************************************** */ + +#include "hashmap_internal.h" + +void *hm_insert_node(t_hash_map *hm, t_hm_node *node, t_hm_node *new) +{ + t_hm_node *node_next; + + if (node->next) + { + node_next = node->next; + node->next = new; + new->prev = node; + new->next = node_next; + node_next->prev = new; + } + else + { + node->next = new; + node->next->prev = node; + hm->last_node = new; + } + hm->size++; + return (new->value); +} diff --git a/src/hm_new.c b/src/hm_new.c new file mode 100644 index 0000000..17ec650 --- /dev/null +++ b/src/hm_new.c @@ -0,0 +1,25 @@ +/* ************************************************************************** */ +/* */ +/* :::::::: */ +/* main.c :+: :+: */ +/* +:+ */ +/* By: haachtch +#+ */ +/* +#+ */ +/* Created: 2020/07/13 09:34:21 by haachtch #+# #+# */ +/* Updated: 2020/09/03 14:12:42 by haachtch ######## odam.nl */ +/* */ +/* ************************************************************************** */ + +#include "hashmap_internal.h" + +void *hm_new(size_t _cap) +{ + t_hash_map *hm; + + if (_cap == 0) + return (NULL); + hm = ft_calloc(sizeof(t_hash_map), 1); + hm->nodes = ft_calloc(sizeof(t_hm_node *), _cap); + hm->cap = _cap; + return ((void *)hm); +} diff --git a/src/hm_remove.c b/src/hm_remove.c new file mode 100644 index 0000000..e924119 --- /dev/null +++ b/src/hm_remove.c @@ -0,0 +1,35 @@ +/* ************************************************************************** */ +/* */ +/* :::::::: */ +/* main.c :+: :+: */ +/* +:+ */ +/* By: haachtch +#+ */ +/* +#+ */ +/* Created: 2020/07/13 09:34:21 by haachtch #+# #+# */ +/* Updated: 2020/09/03 14:12:42 by haachtch ######## odam.nl */ +/* */ +/* ************************************************************************** */ + +#include "hashmap_internal.h" + +void hm_remove(void *_hm, const char *_key, void (*_ft_delete)(void*)) +{ + t_hash_map *hm; + t_hm_node **to_remove; + + hm = (t_hash_map *)_hm; + to_remove = &hm->nodes[hash(hm->cap, _key)]; + if (*to_remove) + { + if (ft_strcmp((*to_remove)->key, _key) != 0) + { + if (!(*to_remove)->next) + return ; + *to_remove = find_node_by_key((*to_remove)->next, _key); + if (!*to_remove) + return ; + } + node_remove_from_list(_hm, *to_remove); + node_destroy(*to_remove, _ft_delete); + } +} diff --git a/src/hm_set.c b/src/hm_set.c new file mode 100644 index 0000000..adb39e0 --- /dev/null +++ b/src/hm_set.c @@ -0,0 +1,51 @@ +/* ************************************************************************** */ +/* */ +/* :::::::: */ +/* main.c :+: :+: */ +/* +:+ */ +/* By: haachtch +#+ */ +/* +#+ */ +/* Created: 2020/07/13 09:34:21 by haachtch #+# #+# */ +/* Updated: 2020/09/03 14:12:42 by haachtch ######## odam.nl */ +/* */ +/* ************************************************************************** */ + +#include "hashmap_internal.h" + +static void *__set(t_hash_map *hm, t_hm_node **node, + const char *_key, void *_value) +{ + void *old_value; + + if (ft_strcmp((*node)->key, _key) != 0) + { + hm->collisions++; + return (hm_handle_collision(hm, *node, _key, _value)); + } + else + { + hm->size++; + old_value = (*node)->value; + (*node)->value = _value; + add_node_to_history(&hm->history, new_node((*node)->key, + old_value)); + return ((*node)->value); + } +} + +void *hm_set(void *_hm, + const char *_key, + void *_value) +{ + t_hash_map *hm; + t_hm_node **node; + + if (_key == NULL) + return (NULL); + hm = (t_hash_map *)_hm; + node = &hm->nodes[hash(hm->cap, _key)]; + if (*node) + return (__set(hm, node, _key, _value)); + else + return (hm_add_new_key(hm, node, _key, _value)); +} diff --git a/src/new_node.c b/src/new_node.c new file mode 100644 index 0000000..364e3da --- /dev/null +++ b/src/new_node.c @@ -0,0 +1,26 @@ +/* ************************************************************************** */ +/* */ +/* :::::::: */ +/* main.c :+: :+: */ +/* +:+ */ +/* By: haachtch +#+ */ +/* +#+ */ +/* Created: 2020/07/13 09:34:21 by haachtch #+# #+# */ +/* Updated: 2020/09/03 14:12:42 by haachtch ######## odam.nl */ +/* */ +/* ************************************************************************** */ + +#include "hashmap_internal.h" + +t_hm_node *new_node(const char *_key, void *_value) +{ + t_hm_node *node; + + node = ft_calloc(sizeof(t_hm_node), 1); + if (node) + { + node->key = ft_strdup(_key); + node->value = _value; + } + return (node); +} diff --git a/src/node_destroy.c b/src/node_destroy.c new file mode 100644 index 0000000..9505c2a --- /dev/null +++ b/src/node_destroy.c @@ -0,0 +1,20 @@ +/* ************************************************************************** */ +/* */ +/* :::::::: */ +/* main.c :+: :+: */ +/* +:+ */ +/* By: haachtch +#+ */ +/* +#+ */ +/* Created: 2020/07/13 09:34:21 by haachtch #+# #+# */ +/* Updated: 2020/09/03 14:12:42 by haachtch ######## odam.nl */ +/* */ +/* ************************************************************************** */ + +#include "hashmap_internal.h" + +void node_destroy(t_hm_node *_to_destroy, void (*_ft_delete)(void*)) +{ + free(_to_destroy->key); + _ft_delete(_to_destroy->value); + free(_to_destroy); +} diff --git a/src/node_remove_from_list.c b/src/node_remove_from_list.c new file mode 100644 index 0000000..ec1fea9 --- /dev/null +++ b/src/node_remove_from_list.c @@ -0,0 +1,25 @@ +/* ************************************************************************** */ +/* */ +/* :::::::: */ +/* main.c :+: :+: */ +/* +:+ */ +/* By: haachtch +#+ */ +/* +#+ */ +/* Created: 2020/07/13 09:34:21 by haachtch #+# #+# */ +/* Updated: 2020/09/03 14:12:42 by haachtch ######## odam.nl */ +/* */ +/* ************************************************************************** */ + +#include "hashmap_internal.h" + +void node_remove_from_list(t_hash_map *_hm, t_hm_node *_node) +{ + if (_node->prev) + _node->prev->next = _node->next; + else + _hm->first_node = _node->next; + if (_node->next) + _node->next->prev = _node->prev; + else + _hm->last_node = _node->prev; +} From 6619b600f3ab32fc4b8c318441d2153167b75a3e Mon Sep 17 00:00:00 2001 From: Harou Date: Sat, 17 Apr 2021 01:27:36 +0200 Subject: [PATCH 3/6] added hm_size and updated hm_remove to latest version --- inc/hashmap.h | 1 + src/hm_remove.c | 23 +++++++++++++---------- src/hm_size.c | 8 ++++++++ 3 files changed, 22 insertions(+), 10 deletions(-) create mode 100644 src/hm_size.c diff --git a/inc/hashmap.h b/inc/hashmap.h index 74fcd34..b5b615b 100644 --- a/inc/hashmap.h +++ b/inc/hashmap.h @@ -19,6 +19,7 @@ void *hm_new(size_t _size); void hm_destroy(void *_hm, void (*f)(void *)); void *hm_set(void *_hm, const char *_key, void *_value); +size_t hm_size(const void *_hm); void *hm_get(const void *_hm, const char *_key); t_pair hm_get_seq(const void *_hm); size_t hm_get_collision_count(void *_hm); diff --git a/src/hm_remove.c b/src/hm_remove.c index e924119..28d8ed7 100644 --- a/src/hm_remove.c +++ b/src/hm_remove.c @@ -12,24 +12,27 @@ #include "hashmap_internal.h" -void hm_remove(void *_hm, const char *_key, void (*_ft_delete)(void*)) +void hm_remove(void *_hm, const char *_key, void (*ft_free)(void*)) { + size_t checksum; t_hash_map *hm; - t_hm_node **to_remove; + t_hm_node *node; hm = (t_hash_map *)_hm; - to_remove = &hm->nodes[hash(hm->cap, _key)]; - if (*to_remove) + checksum = hash(hm->cap, _key); + node = hm->nodes[checksum]; + if (node) { - if (ft_strcmp((*to_remove)->key, _key) != 0) + if (ft_strcmp(node->key, _key) != 0) { - if (!(*to_remove)->next) + if (!node->next) return ; - *to_remove = find_node_by_key((*to_remove)->next, _key); - if (!*to_remove) + node = find_node_by_key(node->next, _key); + if (!node) return ; } - node_remove_from_list(_hm, *to_remove); - node_destroy(*to_remove, _ft_delete); + node_remove_from_list(_hm, node); + node_destroy(node, ft_free); + hm->nodes[checksum] = NULL; } } diff --git a/src/hm_size.c b/src/hm_size.c new file mode 100644 index 0000000..80720b0 --- /dev/null +++ b/src/hm_size.c @@ -0,0 +1,8 @@ +#include "hashmap_internal.h" + +size_t hm_size(const void *_hm) +{ + const t_hash_map *hm = (t_hash_map *)_hm; + + return (hm->size); +} From 3f845a7013da40226eb8d017ee204730ee7f0c3c Mon Sep 17 00:00:00 2001 From: Harou Date: Sat, 17 Apr 2021 02:03:56 +0200 Subject: [PATCH 4/6] hm_get_seq updated to the last version --- src/hm_get_seq.c | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/src/hm_get_seq.c b/src/hm_get_seq.c index 7359ac0..28bd983 100644 --- a/src/hm_get_seq.c +++ b/src/hm_get_seq.c @@ -12,13 +12,25 @@ #include "hashmap_internal.h" +static void set_pair_to_null(t_pair *pair) +{ + pair->u_f.key = NULL; + pair->u_s.value = NULL; +} + t_pair hm_get_seq(const void *_hm) { const t_hash_map *hm = (t_hash_map *)_hm; static t_hm_node *node; t_pair pair; - if (node) + if (_hm == NULL) + { + node = NULL; + set_pair_to_null(&pair); + return (pair); + } + if (node != NULL) node = node->next; else node = hm->first_node; @@ -30,8 +42,7 @@ t_pair hm_get_seq(const void *_hm) else { node = hm->first_node; - pair.u_f.key = NULL; - pair.u_s.value = NULL; + set_pair_to_null(&pair); } return (pair); } From 0bb060d1d32f6083326f7807f5276382a16d5915 Mon Sep 17 00:00:00 2001 From: Harou Date: Wed, 21 Apr 2021 11:02:03 +0200 Subject: [PATCH 5/6] libpair update --- lib/pair | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/pair b/lib/pair index a06c672..99e1469 160000 --- a/lib/pair +++ b/lib/pair @@ -1 +1 @@ -Subproject commit a06c672d9922ad711f7649f68b8ef2858ee41066 +Subproject commit 99e14692d6b65e5af0f1b75c7c1efd7bf041c9ad From a3bfed047d8be0ec0e99502be126a53eabde2793 Mon Sep 17 00:00:00 2001 From: Harou Date: Wed, 21 Apr 2021 11:07:07 +0200 Subject: [PATCH 6/6] updated src/cmakelists to c11 version and updated src/hm_get_seq.c accordly to last libpair update --- src/CMakeLists.txt | 2 +- src/hm_get_seq.c | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index f16d460..f5f301d 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -10,7 +10,7 @@ file(GLOB SRC_SUBROOT_LIST CONFIGURE_DEPENDS "${hashmap_SOURCE_DIR}/src/*/*.c") add_library(hashmap ${SRC_LIST} ${SRC_SUBROOT_LIST} ${HEADER_LIST}) # Set the compilation standards -set_property(TARGET hashmap PROPERTY C_STANDARD 99) +set_property(TARGET hashmap PROPERTY C_STANDARD 11) # We need this directory, and users of our library will need it too target_include_directories(hashmap PUBLIC ../inc) diff --git a/src/hm_get_seq.c b/src/hm_get_seq.c index 28bd983..b80343d 100644 --- a/src/hm_get_seq.c +++ b/src/hm_get_seq.c @@ -14,8 +14,8 @@ static void set_pair_to_null(t_pair *pair) { - pair->u_f.key = NULL; - pair->u_s.value = NULL; + pair->key = NULL; + pair->value = NULL; } t_pair hm_get_seq(const void *_hm) @@ -36,8 +36,8 @@ t_pair hm_get_seq(const void *_hm) node = hm->first_node; if (node) { - pair.u_f.key = node->key; - pair.u_s.value = node->value; + pair.key = node->key; + pair.value = node->value; } else {