Linux内核哈希算法简单理解和注释



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;
};
 Linux内核哈希算法简单理解和注释_第1张图片
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);
}

你可能感兴趣的:(Linux内核哈希算法简单理解和注释)