copy on git
This commit is contained in:
commit
42653de246
205 changed files with 7459 additions and 0 deletions
156
libft/ft_hashmap/ft_hashmap.c
Executable file
156
libft/ft_hashmap/ft_hashmap.c
Executable file
|
|
@ -0,0 +1,156 @@
|
|||
/* ************************************************************************** */
|
||||
/* */
|
||||
/* ::: :::::::: */
|
||||
/* ft_hashmap.c :+: :+: :+: */
|
||||
/* +:+ +:+ +:+ */
|
||||
/* By: thrieg <thrieg@student.42mulhouse.fr> +#+ +:+ +#+ */
|
||||
/* +#+#+#+#+#+ +#+ */
|
||||
/* Created: 2024/11/07 12:14:50 by thrieg #+# #+# */
|
||||
/* Updated: 2025/02/16 19:08:34 by thrieg ### ########.fr */
|
||||
/* */
|
||||
/* ************************************************************************** */
|
||||
|
||||
#include "ft_hashmap_private.h"
|
||||
|
||||
//allocates an array of initial_size, and sets nb_elems/hashmap_size to 0
|
||||
//cmp is a function that returns 0 if both keys are the same
|
||||
//returns NULL if any allocation fails
|
||||
t_hashmap *ft_create_hashmap(
|
||||
size_t initial_size,
|
||||
void (*free_key)(void *),
|
||||
void (*free_value)(void *),
|
||||
int (*cmp)(void *key, void *key_to_compare))
|
||||
{
|
||||
t_hashmap *map;
|
||||
|
||||
if (initial_size == 0)
|
||||
return (NULL);
|
||||
map = malloc(sizeof(t_hashmap));
|
||||
if (!map)
|
||||
return (NULL);
|
||||
map->nb_elems = 0;
|
||||
map->hashmap_size = initial_size;
|
||||
map->cmp = cmp;
|
||||
map->free_key = free_key;
|
||||
map->free_value = free_value;
|
||||
map->table = ft_calloc((initial_size), sizeof(t_list *));
|
||||
if (!(map->table))
|
||||
return (free(map), NULL);
|
||||
return (map);
|
||||
}
|
||||
|
||||
// Inserts a key-value pair into the hashmap,
|
||||
//returns 0 for an error, 1 for remplaced value for a key and 2 for new key
|
||||
int ft_hashmap_insert_element(
|
||||
t_hashmap *map,
|
||||
void *key,
|
||||
void *value,
|
||||
size_t hash)
|
||||
{
|
||||
size_t index;
|
||||
t_list *current;
|
||||
t_hash_element *element;
|
||||
|
||||
if (!map || !key)
|
||||
return (0);
|
||||
if ((map->nb_elems * 100) > map->hashmap_size * HASHMAP_FILL_PERCENT_MAX)
|
||||
ft_resize_hashmap(map);
|
||||
index = hash % map->hashmap_size;
|
||||
current = map->table[index];
|
||||
while (current)
|
||||
{
|
||||
if (map->cmp(((t_hash_element *)(current->content))->key, key) == 0)
|
||||
{
|
||||
map->free_value(((t_hash_element *)(current->content))->value);
|
||||
return (((t_hash_element *)(current->content))->value = value, 1);
|
||||
}
|
||||
current = current->next;
|
||||
}
|
||||
element = ft_create_hash_element(key, value, hash);
|
||||
if (!element)
|
||||
return (0);
|
||||
if (!ft_add_hashmap_element(index, map, element))
|
||||
return (ft_free_hash_element(element, map), 0);
|
||||
return (2);
|
||||
}
|
||||
|
||||
//returns 1 if the element has been deleted
|
||||
//returns 0 if the element has not been found
|
||||
int ft_delete_hashmap_element(t_hashmap *map, void *key, size_t hash)
|
||||
{
|
||||
size_t index;
|
||||
t_list *curr;
|
||||
t_list *prev;
|
||||
t_hash_element *elem;
|
||||
|
||||
if (!map || !key || map->hashmap_size == 0)
|
||||
return (0);
|
||||
if (((map->nb_elems * 100) / map->hashmap_size)
|
||||
<= HASHMAP_FILL_PERCENT_BEFORE_SHRINK)
|
||||
ft_shrink_hashmap(map);
|
||||
index = hash % map->hashmap_size;
|
||||
curr = map->table[index];
|
||||
prev = NULL;
|
||||
while (curr)
|
||||
{
|
||||
elem = (t_hash_element *)curr->content;
|
||||
if (map->cmp(elem->key, key) == 0)
|
||||
{
|
||||
return (ft_delete_hashmap_list_node(curr, prev, index, map), 1);
|
||||
}
|
||||
prev = curr;
|
||||
curr = curr->next;
|
||||
}
|
||||
return (0);
|
||||
}
|
||||
|
||||
//returns a pointer to the value of key, or a NULL pointer if not found
|
||||
void *ft_lookup_hashmap_element(t_hashmap *map, void *key, size_t hash)
|
||||
{
|
||||
size_t index;
|
||||
t_list *curr;
|
||||
t_hash_element *elem;
|
||||
|
||||
if (!map || !key || map->hashmap_size == 0)
|
||||
return (NULL);
|
||||
index = hash % map->hashmap_size;
|
||||
curr = map->table[index];
|
||||
while (curr)
|
||||
{
|
||||
elem = (t_hash_element *)curr->content;
|
||||
if (map->cmp(elem->key, key) == 0)
|
||||
return (elem->value);
|
||||
curr = curr->next;
|
||||
}
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
//frees the entire hashmap and then returns NULL once done
|
||||
void *ft_free_hashmap(t_hashmap *map)
|
||||
{
|
||||
size_t index;
|
||||
t_list *curr;
|
||||
t_list *next;
|
||||
t_hash_element *elem;
|
||||
|
||||
if (!map)
|
||||
return (NULL);
|
||||
if (!map->table)
|
||||
return (free(map), NULL);
|
||||
index = 0;
|
||||
while (index < map->hashmap_size)
|
||||
{
|
||||
curr = map->table[index];
|
||||
while (curr)
|
||||
{
|
||||
next = curr->next;
|
||||
elem = (t_hash_element *)curr->content;
|
||||
ft_free_hash_element(elem, map);
|
||||
free(curr);
|
||||
curr = next;
|
||||
}
|
||||
index++;
|
||||
}
|
||||
free(map->table);
|
||||
return (free(map), NULL);
|
||||
}
|
||||
BIN
libft/ft_hashmap/ft_hashmap.o
Normal file
BIN
libft/ft_hashmap/ft_hashmap.o
Normal file
Binary file not shown.
57
libft/ft_hashmap/ft_hashmap_advanced_type_hash.c
Executable file
57
libft/ft_hashmap/ft_hashmap_advanced_type_hash.c
Executable file
|
|
@ -0,0 +1,57 @@
|
|||
/* ************************************************************************** */
|
||||
/* */
|
||||
/* ::: :::::::: */
|
||||
/* ft_hashmap_advanced_type_hash.c :+: :+: :+: */
|
||||
/* +:+ +:+ +:+ */
|
||||
/* By: thrieg <thrieg@student.42mulhouse.fr> +#+ +:+ +#+ */
|
||||
/* +#+#+#+#+#+ +#+ */
|
||||
/* Created: 2024/11/07 12:47:23 by thrieg #+# #+# */
|
||||
/* Updated: 2025/02/16 19:08:26 by thrieg ### ########.fr */
|
||||
/* */
|
||||
/* ************************************************************************** */
|
||||
|
||||
#include "ft_hashmap_private.h"
|
||||
#include <stdint.h>
|
||||
|
||||
//hash function for an address, returns a size_t between 0 and size_t max
|
||||
size_t ft_hash_address(const void *key)
|
||||
{
|
||||
uintptr_t address;
|
||||
|
||||
address = (uintptr_t)key;
|
||||
return ((size_t)address >> 3);
|
||||
}
|
||||
|
||||
// Hash function for a t_list, returns a size_t between 0 and size_t max
|
||||
//takes the function to hash a single element
|
||||
size_t ft_hash_list(const t_list *list)
|
||||
{
|
||||
return (ft_hash_address(list));
|
||||
}
|
||||
|
||||
// Hash function for a t_hashmap, returns a size_t between 0 and size_t max
|
||||
size_t ft_hash_hashmap(const t_hashmap *hashmap)
|
||||
{
|
||||
return (ft_hash_address(hashmap));
|
||||
}
|
||||
|
||||
// Hash function for a t_vector, returns a size_t between 0 and size_t max
|
||||
size_t ft_hash_vector(const t_vector *vec)
|
||||
{
|
||||
size_t i;
|
||||
int c;
|
||||
size_t index;
|
||||
size_t hash;
|
||||
char *str;
|
||||
|
||||
hash = 5381;
|
||||
index = vec->index;
|
||||
str = vec->buffer;
|
||||
i = 0;
|
||||
while (i < index)
|
||||
{
|
||||
c = str[i++];
|
||||
hash = ((hash << 5) + hash) + c;
|
||||
}
|
||||
return (hash);
|
||||
}
|
||||
BIN
libft/ft_hashmap/ft_hashmap_advanced_type_hash.o
Normal file
BIN
libft/ft_hashmap/ft_hashmap_advanced_type_hash.o
Normal file
Binary file not shown.
79
libft/ft_hashmap/ft_hashmap_basic_cmp.c
Executable file
79
libft/ft_hashmap/ft_hashmap_basic_cmp.c
Executable file
|
|
@ -0,0 +1,79 @@
|
|||
/* ************************************************************************** */
|
||||
/* */
|
||||
/* ::: :::::::: */
|
||||
/* ft_hashmap_basic_cmp.c :+: :+: :+: */
|
||||
/* +:+ +:+ +:+ */
|
||||
/* By: thrieg <thrieg@student.42mulhouse.fr> +#+ +:+ +#+ */
|
||||
/* +#+#+#+#+#+ +#+ */
|
||||
/* Created: 2024/11/08 13:18:52 by thrieg #+# #+# */
|
||||
/* Updated: 2025/02/16 19:08:27 by thrieg ### ########.fr */
|
||||
/* */
|
||||
/* ************************************************************************** */
|
||||
|
||||
#include "ft_hashmap_private.h"
|
||||
#include <limits.h>
|
||||
|
||||
// Comparison function for integers
|
||||
int int_cmp(void *key1, void *key2)
|
||||
{
|
||||
int a;
|
||||
int b;
|
||||
|
||||
a = *(int *)key1;
|
||||
b = *(int *)key2;
|
||||
if (a < b)
|
||||
return (-1);
|
||||
else if (a > b)
|
||||
return (1);
|
||||
else
|
||||
return (0);
|
||||
}
|
||||
|
||||
// Comparison function for strings
|
||||
int cmp_str(void *key1, void *key2)
|
||||
{
|
||||
return (ft_strcmp((char *)key1, (char *)key2));
|
||||
}
|
||||
|
||||
// Comparison function for unsigned chars
|
||||
int cmp_uchar(void *key1, void *key2)
|
||||
{
|
||||
unsigned char *c1;
|
||||
unsigned char *c2;
|
||||
|
||||
c1 = (unsigned char *)key1;
|
||||
c2 = (unsigned char *)key2;
|
||||
return (*c1 - *c2);
|
||||
}
|
||||
|
||||
// Comparison function for unsigned integers
|
||||
int uint_cmp(void *key1, void *key2)
|
||||
{
|
||||
unsigned int a;
|
||||
unsigned int b;
|
||||
|
||||
a = *(unsigned int *)key1;
|
||||
b = *(unsigned int *)key2;
|
||||
if (a < b)
|
||||
return (-1);
|
||||
else if (a > b)
|
||||
return (1);
|
||||
else
|
||||
return (0);
|
||||
}
|
||||
|
||||
// Comparison function for size_t
|
||||
int sizet_cmp(void *key1, void *key2)
|
||||
{
|
||||
size_t a;
|
||||
size_t b;
|
||||
|
||||
a = *(size_t *)key1;
|
||||
b = *(size_t *)key2;
|
||||
if (a < b)
|
||||
return (-1);
|
||||
else if (a > b)
|
||||
return (1);
|
||||
else
|
||||
return (0);
|
||||
}
|
||||
BIN
libft/ft_hashmap/ft_hashmap_basic_cmp.o
Normal file
BIN
libft/ft_hashmap/ft_hashmap_basic_cmp.o
Normal file
Binary file not shown.
57
libft/ft_hashmap/ft_hashmap_basic_type_hash.c
Executable file
57
libft/ft_hashmap/ft_hashmap_basic_type_hash.c
Executable file
|
|
@ -0,0 +1,57 @@
|
|||
/* ************************************************************************** */
|
||||
/* */
|
||||
/* ::: :::::::: */
|
||||
/* ft_hashmap_basic_type_hash.c :+: :+: :+: */
|
||||
/* +:+ +:+ +:+ */
|
||||
/* By: thrieg <thrieg@student.42mulhouse.fr> +#+ +:+ +#+ */
|
||||
/* +#+#+#+#+#+ +#+ */
|
||||
/* Created: 2024/11/07 12:34:20 by thrieg #+# #+# */
|
||||
/* Updated: 2025/02/16 19:08:29 by thrieg ### ########.fr */
|
||||
/* */
|
||||
/* ************************************************************************** */
|
||||
|
||||
#include "ft_hashmap_private.h"
|
||||
|
||||
// Integer hash function, returns a size_t between 0 and size_t max
|
||||
size_t ft_hash_int(int value)
|
||||
{
|
||||
return ((size_t)(value * 2654435761u));
|
||||
}
|
||||
|
||||
// Unsigned integer hash function, returns a size_t between 0 and size_t max
|
||||
size_t ft_hash_uint(unsigned int value)
|
||||
{
|
||||
return ((size_t)(value * 2654435761u));
|
||||
}
|
||||
|
||||
// Character hash function, returns a size_t between 0 and size_t max
|
||||
size_t ft_hash_char(char value)
|
||||
{
|
||||
return ((size_t)(value * 31));
|
||||
}
|
||||
|
||||
// String hash function (DJB2), returns a size_t between 0 and size_t max
|
||||
size_t ft_hash_string(const char *str)
|
||||
{
|
||||
int c;
|
||||
size_t hash;
|
||||
|
||||
hash = 5381;
|
||||
while (*str)
|
||||
{
|
||||
c = *str++;
|
||||
hash = ((hash << 5) + hash) + c;
|
||||
}
|
||||
return (hash);
|
||||
}
|
||||
|
||||
// size_t hash function, returns a size_t between 0 and size_t max
|
||||
size_t ft_hash_size_t(size_t value)
|
||||
{
|
||||
value ^= value >> 33;
|
||||
value *= 0xff51afd7ed558ccd;
|
||||
value ^= value >> 33;
|
||||
value *= 0xc4ceb9fe1a85ec53;
|
||||
value ^= value >> 33;
|
||||
return (value);
|
||||
}
|
||||
BIN
libft/ft_hashmap/ft_hashmap_basic_type_hash.o
Normal file
BIN
libft/ft_hashmap/ft_hashmap_basic_type_hash.o
Normal file
Binary file not shown.
46
libft/ft_hashmap/ft_hashmap_private.h
Executable file
46
libft/ft_hashmap/ft_hashmap_private.h
Executable file
|
|
@ -0,0 +1,46 @@
|
|||
/* ************************************************************************** */
|
||||
/* */
|
||||
/* ::: :::::::: */
|
||||
/* ft_hashmap_private.h :+: :+: :+: */
|
||||
/* +:+ +:+ +:+ */
|
||||
/* By: thrieg <thrieg@student.42mulhouse.fr> +#+ +:+ +#+ */
|
||||
/* +#+#+#+#+#+ +#+ */
|
||||
/* Created: 2024/11/07 13:49:11 by thrieg #+# #+# */
|
||||
/* Updated: 2025/02/16 19:08:30 by thrieg ### ########.fr */
|
||||
/* */
|
||||
/* ************************************************************************** */
|
||||
|
||||
#ifndef FT_HASHMAP_PRIVATE_H
|
||||
# define FT_HASHMAP_PRIVATE_H
|
||||
|
||||
# include "../ft_hashmap.h"
|
||||
|
||||
typedef struct s_hash_element
|
||||
{
|
||||
void *key;
|
||||
void *value;
|
||||
size_t hash;
|
||||
} t_hash_element;
|
||||
|
||||
t_hash_element *ft_create_hash_element(void *key, void *value, size_t hash);
|
||||
void ft_free_hash_element(t_hash_element *elem, t_hashmap *map);
|
||||
int ft_add_hashmap_element(
|
||||
size_t index,
|
||||
t_hashmap *map,
|
||||
t_hash_element *elem);
|
||||
int ft_add_hashmap_element(
|
||||
size_t index,
|
||||
t_hashmap *map,
|
||||
t_hash_element *elem);
|
||||
void ft_copy_hashmap_table(
|
||||
t_list **new_table,
|
||||
t_list **old_table,
|
||||
size_t new_size,
|
||||
size_t old_size);
|
||||
void ft_delete_hashmap_list_node(
|
||||
t_list *curr,
|
||||
t_list *prev,
|
||||
size_t index,
|
||||
t_hashmap *map);
|
||||
|
||||
#endif
|
||||
70
libft/ft_hashmap/ft_hashmap_utils.c
Executable file
70
libft/ft_hashmap/ft_hashmap_utils.c
Executable file
|
|
@ -0,0 +1,70 @@
|
|||
/* ************************************************************************** */
|
||||
/* */
|
||||
/* ::: :::::::: */
|
||||
/* ft_hashmap_utils.c :+: :+: :+: */
|
||||
/* +:+ +:+ +:+ */
|
||||
/* By: thrieg <thrieg@student.42mulhouse.fr> +#+ +:+ +#+ */
|
||||
/* +#+#+#+#+#+ +#+ */
|
||||
/* Created: 2024/11/07 13:51:48 by thrieg #+# #+# */
|
||||
/* Updated: 2025/02/16 19:08:32 by thrieg ### ########.fr */
|
||||
/* */
|
||||
/* ************************************************************************** */
|
||||
|
||||
#include "ft_hashmap_private.h"
|
||||
|
||||
void ft_free_hash_element(t_hash_element *elem, t_hashmap *map)
|
||||
{
|
||||
if (map->free_key)
|
||||
map->free_key(elem->key);
|
||||
if (map->free_value)
|
||||
map->free_value(elem->value);
|
||||
free(elem);
|
||||
}
|
||||
|
||||
// Helper function to create a new hash element
|
||||
t_hash_element *ft_create_hash_element(void *key, void *value, size_t hash)
|
||||
{
|
||||
t_hash_element *new_element;
|
||||
|
||||
new_element = malloc(sizeof(t_hash_element));
|
||||
if (!new_element)
|
||||
return (NULL);
|
||||
new_element->key = key;
|
||||
new_element->value = value;
|
||||
new_element->hash = hash;
|
||||
return (new_element);
|
||||
}
|
||||
|
||||
//returns 0 for allocation fail without allocating or freeing anything
|
||||
int ft_add_hashmap_element(size_t index, t_hashmap *map, t_hash_element *elem)
|
||||
{
|
||||
t_list *new_node;
|
||||
|
||||
new_node = malloc(sizeof(t_list));
|
||||
if (!new_node)
|
||||
return (0);
|
||||
new_node->content = elem;
|
||||
new_node->next = map->table[index];
|
||||
map->table[index] = new_node;
|
||||
map->nb_elems++;
|
||||
return (1);
|
||||
}
|
||||
|
||||
//returns 0 without doing anything if the allocation of the new table fails
|
||||
//in that case the old table is still valid!
|
||||
//returns 1 if the resize is a success
|
||||
int ft_resize_hashmap(t_hashmap *map)
|
||||
{
|
||||
size_t new_size;
|
||||
t_list **new_table;
|
||||
|
||||
new_size = map->hashmap_size * HASHMAP_RESIZE_FACTOR;
|
||||
new_table = ft_calloc(new_size, sizeof(t_list *));
|
||||
if (!new_table)
|
||||
return (0);
|
||||
ft_copy_hashmap_table(new_table, map->table, new_size, map->hashmap_size);
|
||||
free(map->table);
|
||||
map->table = new_table;
|
||||
map->hashmap_size = new_size;
|
||||
return (1);
|
||||
}
|
||||
BIN
libft/ft_hashmap/ft_hashmap_utils.o
Normal file
BIN
libft/ft_hashmap/ft_hashmap_utils.o
Normal file
Binary file not shown.
85
libft/ft_hashmap/ft_hashmap_utils_two.c
Executable file
85
libft/ft_hashmap/ft_hashmap_utils_two.c
Executable file
|
|
@ -0,0 +1,85 @@
|
|||
/* ************************************************************************** */
|
||||
/* */
|
||||
/* ::: :::::::: */
|
||||
/* ft_hashmap_utils_two.c :+: :+: :+: */
|
||||
/* +:+ +:+ +:+ */
|
||||
/* By: thrieg <thrieg@student.42mulhouse.fr> +#+ +:+ +#+ */
|
||||
/* +#+#+#+#+#+ +#+ */
|
||||
/* Created: 2024/11/07 16:04:36 by thrieg #+# #+# */
|
||||
/* Updated: 2025/02/16 19:08:31 by thrieg ### ########.fr */
|
||||
/* */
|
||||
/* ************************************************************************** */
|
||||
|
||||
#include "ft_hashmap_private.h"
|
||||
|
||||
//doesn't allocate anything no error possible
|
||||
void ft_copy_hashmap_table(
|
||||
t_list **new_table,
|
||||
t_list **old_table,
|
||||
size_t new_size,
|
||||
size_t old_size)
|
||||
{
|
||||
t_list *curr;
|
||||
t_list *next;
|
||||
t_hash_element *elem;
|
||||
size_t i;
|
||||
size_t new_index;
|
||||
|
||||
i = 0;
|
||||
while (i < old_size)
|
||||
{
|
||||
curr = old_table[i];
|
||||
while (curr)
|
||||
{
|
||||
next = curr->next;
|
||||
elem = (t_hash_element *)curr->content;
|
||||
new_index = elem->hash % new_size;
|
||||
curr->next = new_table[new_index];
|
||||
new_table[new_index] = curr;
|
||||
curr = next;
|
||||
}
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
//helper function for delete_hashmap_element to delete the node once found
|
||||
void ft_delete_hashmap_list_node(
|
||||
t_list *curr,
|
||||
t_list *prev,
|
||||
size_t index,
|
||||
t_hashmap *map)
|
||||
{
|
||||
t_hash_element *elem;
|
||||
|
||||
elem = (t_hash_element *)curr->content;
|
||||
if (prev)
|
||||
prev->next = curr->next;
|
||||
else
|
||||
map->table[index] = curr->next;
|
||||
ft_free_hash_element(elem, map);
|
||||
free(curr);
|
||||
map->nb_elems--;
|
||||
}
|
||||
|
||||
//returns 0 without doing anything if the allocation of the new table fails
|
||||
//or if the table is too little in that case the old table is still valid!
|
||||
//returns 1 if the shrink is a success
|
||||
int ft_shrink_hashmap(t_hashmap *map)
|
||||
{
|
||||
size_t new_size;
|
||||
t_list **new_table;
|
||||
|
||||
if (map->hashmap_size == HASHMAP_MINIMUM_SIZE)
|
||||
return (0);
|
||||
new_size = map->hashmap_size / HASHMAP_SHRINK_FACTOR;
|
||||
if (new_size < HASHMAP_MINIMUM_SIZE)
|
||||
new_size = HASHMAP_MINIMUM_SIZE;
|
||||
new_table = ft_calloc(new_size, sizeof(t_list *));
|
||||
if (!new_table)
|
||||
return (0);
|
||||
ft_copy_hashmap_table(new_table, map->table, new_size, map->hashmap_size);
|
||||
free(map->table);
|
||||
map->table = new_table;
|
||||
map->hashmap_size = new_size;
|
||||
return (1);
|
||||
}
|
||||
BIN
libft/ft_hashmap/ft_hashmap_utils_two.o
Normal file
BIN
libft/ft_hashmap/ft_hashmap_utils_two.o
Normal file
Binary file not shown.
Loading…
Add table
Add a link
Reference in a new issue