inux内核的哈希算法实现
//1、数据结构
struct hashtab_node
{
void *key;//通过哈希算法得到的关键字
void *datum;//存储的数据
struct hashtab_node *next;//单个节点的指针域,形成一个链表
};
//2、这是一张哈希表,hashtab是这张表的首地址
struct hashtab
{
struct **hashtab_node **htable;
u32 size;
u32 nel;
u32 (*hash_value)(struct hashtab *h,void *key);
int (*keycmp)(struct hashtab *h,void *key1,void *key2)
};
struct hashtab_info
{
u32 slots_used;
u32 max_chain_len;
};
struct hashtab *hashtab_create(u32 (*hash_value)(struct hashtab *h, const void *key),
int (*keycmp)(struct hashtab *h, const void *key1, const void *key2),
u32 size)//
{
struct hashtab*p;
u32 i;
p = kzalloc(sizeof(*p),GFP_KERNEL);
if(p == NULL)
return p;
p->size = size;//可以存储的节点htable的个数,而且申请的内存是连续的,方便通过key来哈希一个数据位置,直接查找
p->nel = 0;
p->keycmp = keycmp;//链表插入时的比较函数
p->htable = kmalloc(sizeof(*(p->htable)) * size, GFP_KERNEL);//向内核空间申请连续的内存空间
if (p->htable == NULL)
{
kfree(p);
return NULL;
}
for (i = 0; i < size; i++)//初始化申请的节点空间
p->htable[i] = NULL;
return p;
}
int hashtab_insert(struct hashtab *h, void *key, void *datum)
{
u32 hvalue;
struct hashtab_node *prev, *cur, *newnode;
if(!h || h->nel == HASHTAB_MAX_NODES)//超出数据范围
return -EINVAL;
hvalue = h->hash_value(h,key);//通过哈希算法得到一个关键字
prev = NULL;
cur = h->htable[hvalue];
while(cur && h->keycmp(h,key,cur->key)>0)
{
prev = cur;
cur = cur->next;
}//每个hvalue对应下的节点。是一个立体的结构
if (cur && (h->keycmp(h, key, cur->key) == 0))
return -EEXIST;//存在重复的节点
newnode = kzalloc(sizeof(*newnode), GFP_KERNEL);//构造新的节点
newnode->key = key;
newnode->datum = datum;
if(prev)
{
newnode->next = pre->next;
prev->next = newnode;//插入到指定的位置
}
else
{
newnode->next = h->htable[hvalue];//成为首节点
h->htable[hvalue] = newnode;//h->htable[hvalue] 重新指向首节点
}
h->nel++;//节点个数加1,这张表中总的节点是size * HASHTAB_MAX_NODES
return 0;
}
void *hashtab_search(struct hashtab *h, const void *key)
{
u32 hvalue;
struct hashtab_node *cur;
if (!h)
return NULL;
hvalue = h->hash_value(h, key);
cur = h->htable[hvalue];//定位到哈希key值的头结点
while (cur != NULL && h->keycmp(h, key, cur->key) > 0)
cur = cur->next;//遍历整个链表查询
if (cur == NULL || (h->keycmp(h, key, cur->key) != 0))
return NULL;
return cur->datum;//获取到值,找打与key相同的节点
}
void hashtab_destroy(struct hashtab *h)
{
u32 i;
struct hashtab_node *cur, *temp;
if (!h)
return;
for(i = 0; i < h->size; i++)
{
cur = h->htable[i];//每个链表的头结点
while(cur)
{
temp = cur;
cur = cur->next;
kfree(temp);
}
}
kfree(h->htable);
h->htable = NULL;
kfree(h);
}