/* ************************************************************************** */
/*                                                                            */
/*                                                        :::      ::::::::   */
/*   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);
}
