#include <string.h>
#include "mem.h"
#include "struct.h"
#define HASHMAX 500000
struct hashlist *hashini()
{
	return (struct hashlist *)s_calloc(sizeof(struct hashlist)*(HASHMAX+1),1)+1;
}
int str_hashing(const char *title)
{
	unsigned int sum,i;
	i=0;sum=0;
	while(title[i])
	{
		sum=(sum*31+title[i])%HASHMAX;
		i++;
	}
	return sum;
}

int int_hashing(unsigned int num)
{
	return num%HASHMAX;
}
int str_hashquery(struct hashlist *hsh,const char *title,void **p)
{
	int k;
	struct ext *node;
	k=str_hashing(title);
	node=hsh[k].node;
	while(node)
	{
		if(!strcmp(node->key.str,title))
		{
			*p=node->p;
			return 1;
		}
		node=node->next;
	}
	return 0;
}
int int_hashquery(struct hashlist *hsh,unsigned int num,void **p)
{
	int k;
	struct ext *node;
	k=int_hashing(num);
	node=hsh[k].node;
	while(node)
	{
		if(node->key.num==num)
		{
			*p=node->p;
			return 1;
		}
		node=node->next;
	}
	return 0;

}
int str_hashadd(struct hashlist *hsh,const char *title,void *p)
{
	struct ext *temp,*node;
	int k=str_hashing(title);
	if(!hsh[k].node)
	{
		temp=(struct ext *)s_calloc(sizeof(struct ext),1);
		hsh[k].node=temp;
	}
	else
	{
		for(node=hsh[k].node;node;node=node->next)
		{
			if(!strcmp(node->key.str,title))
			{
				node->p=p;
				return 1;
			}
		}
		temp=(struct ext *)s_calloc(sizeof(struct ext),1);
		hsh[k].cur->next=temp;
	}
	hsh[k].cur=temp;
	hsh[k].flag++;
	temp->key.str=(char *)s_calloc(strlen(title)+3,1);
	strcpy(temp->key.str,title);
	temp->p=p;
	temp->vnext=hsh[-1].node;
	hsh[-1].node=temp;
	return 0;
}
int int_hashadd(struct hashlist *hsh,unsigned int num,void *p)
{
	int k;
	struct ext *temp;
	k=int_hashing(num);
	temp=(struct ext *)s_calloc(sizeof(struct ext),1);
	temp->next=0;
	temp->key.num=num;
	temp->p=p;
	if(!hsh[k].node)
	{
		hsh[k].node=temp;
		hsh[k].cur=temp;
	}
	else
	{
		hsh[k].cur->next=temp;
		hsh[k].cur=temp;
	}
	hsh[k].flag++;
	temp->vnext=hsh[-1].node;
	hsh[-1].node=temp;
	return 0;
}
int str_hashdestroy(struct hashlist *p)
{
	struct hashlist *real_p=p-1;
	struct ext *cur,*pre;
	pre=cur=real_p->node;
	while(cur)
	{
		s_free(cur->key.str);
		pre=cur;
		cur=cur->vnext;
		s_free(pre);
	}
	s_free(real_p);
	return 0;
}
int str_hashdestroy_withfree(struct hashlist *p, void freefunc(void *))
{
	struct hashlist *real_p=p-1;
	struct ext *cur,*pre;
	pre=cur=real_p->node;
	while(cur)
	{
		s_free(cur->key.str);
		if(cur->p) freefunc(cur->p);
		pre=cur;
		cur=cur->vnext;
		s_free(pre);
	}
	s_free(real_p);
	return 0;
}
struct queue *queueini()
{
	return (struct queue*)s_calloc(sizeof(struct queue),1);
}
int queueisnull(struct queue *q)
{
	return !(q->length);
}
int queuepush(struct queue *q,void *title)
{
	struct ext *temp;
	temp=(struct ext *)s_calloc(sizeof(struct ext),1);
	temp->p=title;
	temp->next=0;
	if(!q->length)
	{
		q->head=q->end=temp;
		q->length=1;
	}
	else
	{
		q->end->next=temp;
		q->end=temp;
		q->length++;
	}
	return q->length;
}
int queuepop(struct queue *q,void **title)
{
	struct ext *temp;
	if(!q->length) return -1;
	if(q->length==1)
	{
		*title=q->head->p;
		s_free(q->head);
		q->head=q->end=0;
		q->length=0;
	}
	else
	{
		*title=q->head->p;
		temp=q->head;
		q->head=temp->next;
		s_free(temp);
		q->length--;
	}
	return q->length;
}