//
//  hash.c
//
//  Created by Julien-Pierre Averous on 16/10/06.
//  Copyright 2006 SourceMac.com. All rights reserved.
//
//

#include "malloc.h"
#include "hash.h"


s_hash	*hash = NULL;


/*
** Hash init
*/
void	hash_init()
{
	int	i;

	if (hash)
		my_free(hash);
	
	hash = my_malloc(sizeof(s_hash));
	
	hash->id = 0;
	hash->alloc_sz = 0;
	hash->free_sz = 0;
	hash->count = 0;
	for (i = 0; i < HSH_SIZE; i++)
		hash->frms[i] = NULL;
 }
 

/*
** Hash append frame
*/
void	hash_append_frame(s_frame *frm)
{
	s_frame	*ifrm;
	size_t	pos;
	
	if (!hash)
		hash_init();
		
	pos = (size_t)frm->ptr % HSH_SIZE;
	
	if (frm->id == -1)
		frm->id = (hash->id)++;
	
	frm->next = NULL;

	if(!hash->frms[pos])
		hash->frms[pos] = frm;
	else
		{
		ifrm = hash->frms[pos];
		while(ifrm->next)
			ifrm = ifrm->next;
		ifrm->next = frm;
		}
	hash->alloc_sz += frm->sz;
	(hash->count)++;
}


/*
** Hash remove frame from ptr
*/
int		hash_remove_ptrframe(void *ptr)
{
	s_frame	*frm, *lfrm = NULL;
	size_t	pos;
	size_t	id;
	
	if (!hash)
		hash_init();

	pos = (size_t)ptr % HSH_SIZE;
	
	if (!hash->frms[pos])
		return -1;

	frm = hash->frms[pos];
	
	while (frm && frm->ptr != ptr)
		{
		lfrm = frm;
		frm = frm->next;
		}
		
	if (!frm)
		return -1;

	id = frm->id;
	if (!lfrm)
		hash->frms[pos] = frm->next;
	else
		lfrm->next = frm->next;
	
	hash->free_sz += frm->sz;
	(hash->count)--;
	my_free(frm);
	
	return id;
}


/*
** Search a frame from is id
*/
s_frame	*hash_found_id(int	id)
{
	int		i;
	s_frame	*frm;
	
	if (!hash)
		hash_init();

	for (i = 0; i < HSH_SIZE; i++)
		{
		frm = hash->frms[i];
		
		while (frm)
			{
			if (frm->id == id)
				return (frm);
			frm = frm->next;
			}
		}
	
	return (NULL);
}


/*
** Search a frame from is content ptr
*/
s_frame	*hash_found_ptr(void *ptr)
{
	s_frame	*frm;
	size_t	pos;
	
	if (!hash)
		hash_init();

	pos = (size_t)ptr % HSH_SIZE;

	frm = hash->frms[pos];
	while(frm)
		{
		if (frm->ptr == ptr)
			return (frm);
		frm = frm->next;
		}
	
	return (NULL);
}
