/* ************************************************************************** */
/*                                                                            */
/*                                                        :::      ::::::::   */
/*   ft_hashmap.h                                       :+:      :+:    :+:   */
/*                                                    +:+ +:+         +:+     */
/*   By: thrieg <thrieg@student.42mulhouse.fr>      +#+  +:+       +#+        */
/*                                                +#+#+#+#+#+   +#+           */
/*   Created: 2024/11/07 12:14:47 by thrieg            #+#    #+#             */
/*   Updated: 2025/02/16 19:06:02 by thrieg           ###   ########.fr       */
/*                                                                            */
/* ************************************************************************** */

#ifndef FT_HASHMAP_H
# define FT_HASHMAP_H

# include "libft.h"
# include "ft_vector.h"

# define HASHMAP_FILL_PERCENT_MAX 200
# define HASHMAP_RESIZE_FACTOR 2
# define HASHMAP_MINIMUM_SIZE 16
# define HASHMAP_FILL_PERCENT_BEFORE_SHRINK 50
# define HASHMAP_SHRINK_FACTOR 2

typedef struct s_hashmap
{
	t_list	**table;
	size_t	hashmap_size;
	size_t	nb_elems;
	void	(*free_key)(void *key);
	void	(*free_value)(void *value);
	int		(*cmp)(void *key, void *key_to_compare);
}	t_hashmap;

size_t		ft_hash_int(int value);
size_t		ft_hash_uint(unsigned int value);
size_t		ft_hash_char(char value);
size_t		ft_hash_string(const char *str);
size_t		ft_hash_size_t(size_t value);
size_t		ft_hash_address(const void *key);
size_t		ft_hash_list(const t_list *list);
size_t		ft_hash_hashmap(const t_hashmap *hashmap);
size_t		ft_hash_vector(const t_vector *vec);
// Comparison function for integers
int			int_cmp(void *key1, void *key2);
// Comparison function for strings
int			cmp_str(void *key1, void *key2);
// Comparison function for unsigned chars
int			cmp_uchar(void *key1, void *key2);
// Comparison function for unsigned integers
int			uint_cmp(void *key1, void *key2);
// Comparison function for size_t
int			sizet_cmp(void *key1, void *key2);

//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);

//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);

//applies functions free_key and free_value on the element if they are not NULL
//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);

//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);

//frees the entire hashmap and then returns NULL once done
void		*ft_free_hashmap(t_hashmap *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);

//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));

#endif
