//此链表具有StringBuffer, HashTab, List, Vector 的功能
#ifndef _list_
#define _list_
#include "stdbool.h"
struct item
{
char * data;
unsigned int size;
unsigned int hash;
struct item * last;
struct item * next;
};
struct list
{
struct item * head;
struct item * end;
unsigned int items; //子节点个数
unsigned int length;
};
#define PUSH_FL_EMPTY 0
#define PUSH_FL_DATA 1
#define PUSH_FL_HASH 2
#define PUSH_FL_ALL PUSH_FL_DATA|PUSH_FL_HASH
#define init_list(plist) memset(plist,0,sizeof(struct list))
void push_list(struct list *plist, void *pdata, unsigned int size, unsigned int flag); //将p指向的size个字节数据存入链表
void clear_list(struct list *plist); //清除链表
void pop_list(struct list *plist); //弹出最后一个节点数据
void *compress_list(struct list *plist); //将链表压缩为数据流
#endif //(_list_)
#include <stdlib.h>
#include <stdio.h>
#include "list.h"
// BKDR Hash Function
unsigned int BKDRHash(char *str, unsigned int len)
{
unsigned int seed = 131; // 31 131 1313 13131 131313 etc..
unsigned int hash = 0;
unsigned int i;
if (len)
{
for(i=0;i<len;i++)
{
hash = hash * seed + (str[i]);
}
}else{
while (*str)
{
hash = hash * seed + (*str++);
}
}
return (hash & 0x7FFFFFFF);
}
void push_list(struct list *plist, void *pdata, unsigned int size, unsigned int flag)
{
struct item *pitem;
if (pdata==0 || size==0) return ;
pitem=(struct item *)malloc(sizeof(struct item)+((flag&PUSH_FL_DATA)?size+1:0));
if (pitem)
{
if (flag&PUSH_FL_DATA)
{
pitem->size=size;
pitem->data=(char *)pitem+sizeof(struct item);
memcpy(pitem->data,pdata,size);
pitem->data[size]=0;
}else{
pitem->size=0;
pitem->data=0;
}
if (flag&PUSH_FL_HASH)
{
pitem->hash=BKDRHash((const char *)pdata,size);
}else{
pitem->hash=0;
}
pitem->next=0;
pitem->last=0;
if (plist->head==0)
{
plist->end=plist->head=pitem;
}else if (plist->end){
pitem->last=plist->end;
plist->end->next=pitem;
}
plist->end=pitem;
plist->length+=pitem->size;
plist->items++;
}
}
//从链表里寻找
int find_item(struct list *plist, void *pdata, unsigned int size)
{
if (pdata==0 || size==0) return -1;
int i;
unsigned int hash;
struct item *pitem;
struct item *next;
pitem=plist->head;
hash=BKDRHash((const char *)pdata,size); //计算要查找数据的hash值
i=0;
while(pitem)
{
//如果hash值非0,则使用hash值匹配
if (pitem->hash)
{
if (pitem->hash==hash) return i;
//负责逐字节匹配
}else if (strncmp((const char *)pitem->data,(const char *)pdata,size)==0){
return i;
}
pitem=pitem->next; i++;
}
return -1;
}
void clear_list(struct list *plist)
{
struct item *pitem;
struct item *next;
pitem=plist->head;
while(pitem)
{
//保存下一个节点指针
next=pitem->next;
//释放当前节点内存
free(pitem);
pitem=next;
}
plist->end=plist->head=0;
}
void pop_list(struct list *plist)
{
}
void * compress_list(struct list *plist)
{
struct item *pnew;
struct item *pitem;
struct item *next;
char *pdata;
pnew=(struct item *)malloc(sizeof(struct item)+plist->length+1);
if (pnew)
{
pnew->size=plist->length;
pnew->data=(char *)pnew+sizeof(struct item);
pnew->next=0;
pitem=plist->head;
pdata=(char *)pnew->data;
while(pitem)
{
//保存下一个节点指针
next=pitem->next;
if (pitem->size)
{
//复制节点数据
memcpy(pdata,pitem->data,pitem->size);
pdata+=pitem->size;
}
//释放当前节点内存
free(pitem);
pitem=next;
}
*pdata=0;
plist->head=pnew;
return pnew->data;
}
return 0;
}
//#include <time.h>
/*
int main(int argc, char **argv)
{
unsigned int i,j;
struct list l;
init_list(&l);
char temp[10];
srand(time(0));
for (i=0;i<10000;i++)
{
for(j=0;j<10;j++)
{
temp[j]=rand()%256;
}
if (find_item(&l,temp,10)==-1)
{
push_list(&l,temp,10,PUSH_FL_HASH);
}
}
printf("items:%d length:%d\n", l.items, l.length);
clear_list(&l);
return 0;
}
*/