美文网首页
哈希公共服务

哈希公共服务

作者: github_lincy | 来源:发表于2019-01-10 11:40 被阅读0次

哈希链地址法

哈希的引入是数组和链表的结合体,有效解决了查询/插入/删除的性能问题。但不可避免的引入了哈希冲突问题,解决冲突的方法有多种,本文只针对链地址法的设计进行描述。

链地址法

链地址法简而言之即将所有哈希地址相同的记录都链接在同一链表中

算法设计

  • 数据结构设计
/* 哈希单元定义 */
typedef struct {
    struct list_head list;
    void   *item;
} lib_hash_item_t;
/*  哈希表结构定义 */
typedef struct {
    u_int32_t   hash_table_size;
    u_int32_t   hash_item_num;
    u_int32_t   hash_bucket_warn_size;
    u_int32_t   max_conflict_size;
    u_int8_t    *hash_bucket_size;
    struct list_head *hash_table;
    hash_get_index_func_t  hash_get_index;
    hash_cmp_key_func_t    hash_cmp_key;
} lib_hash_t;
  • 哈希函数声明
/* 创建哈希表 */
lib_hash_t *lib_create_hash(u_int32_t item_num, hash_get_index_func_t hash_get_index,  hash_cmp_key_func_t hash_cmp_key);

/* 删除哈希表 */
void lib_destroy_hash(lib_hash_t *hash);

/* 插入哈希单元 */
int lib_hash_insert_item(lib_hash_t * hash, void *item);

/* 删除哈希单元 */
void lib_hash_del_item(lib_hash_t * hash, void *item);

/* 查找哈希单元 */
void *lib_hash_find_item(lib_hash_t * hash, void *item);
  • 哈希函数定义
/* 创建一张哈希表 */
lib_hash_t *lib_create_hash(u_int32_t item_num, hash_get_index_func_t hash_get_index, hash_cmp_key_func_t hash_cmp_key)
{
    int32_t     i;
    u_int32_t   hash_table_size;
    struct list_head *hash_table;
    lib_hash_t *hash;

    hash = malloc(sizeof(libss_hash_t));
    if (hash == NULL) {
        return NULL;
    }
    
    item_num = item_num == 0 ? MIN_HASH_SZ : item_num;
    hash_table_size = ((double)item_num) / HASH_GENE;
    hash_table = malloc(sizeof(struct list_head) * hash_table_size);
    if (hash_table == NULL) {
        free(hash);
        return NULL;
    }
    if ( (hash->hash_bucket_size = malloc( sizeof(hash->hash_bucket_size[0]) * 
     hash_table_size )) == NULL ){
        free(hash);
        free(hash_table );
        return NULL;
    }
        
    for (i = 0; i < hash_table_size; i++) {
        hash->hash_bucket_size[i] = 0;
        INIT_LIST_HEAD(&hash_table[i]);
    }
    
    hash->hash_item_num     = 0;
    hash->hash_table_size   = hash_table_size;
    hash->hash_table        = hash_table;
    hash->hash_get_index    = hash_get_index;
    hash->hash_cmp_key      = hash_cmp_key;
    hash->hash_bucket_warn_size = 0;
    hash->max_conflict_size = 0;
    
    return hash;
}
/* 删除哈希表 */
void lib_destroy_hash(lib_hash_t *hash)
{
    free(hash->hash_bucket_size);
    free(hash->hash_table);
    free(hash);
    
    return;
}
/* 哈希表中插入一个单元 */
int32_t lib_hash_insert_item(lib_hash_t *hash, void *item)
{
    u_int32_t              index;
    lib_hash_item_t        *hash_item;

    hash_item = malloc(sizeof(lib_hash_item_t));
    if (hash_item == NULL) {
        return (-ENOMEM);
    }
    /* 获取hash地址 */
    index = hash->hash_get_index(item) % hash->hash_table_size;
    hash_item->item = item;
   /* hash地址所在链表添加单元 */
    list_add(&hash_item->list, &hash->hash_table[index]);
    hash->hash_bucket_size[index]++;
   /* 更新hash冲突的最大节点数 */
    if (hash->hash_bucket_size[index] > hash->max_conflict_size) {
        hash->max_conflict_size = hash->hash_bucket_size[index];
    }
    hash->hash_item_num++;

    return 0;
}
/* 哈希表中删除一个单元 */
void lib_hash_del_item(lib_hash_t *hash, void *item)
{
    u_int32_t            index;
    struct list_head *pos, *n;
    lib_hash_item_t *hash_item;

    index = hash->hash_get_index(item) % hash->hash_table_size;
   /* 遍历哈希地址所在链表 */
    list_for_each_safe(pos, n, &hash->hash_table[index]) {
        hash_item = list_entry(pos, lib_hash_item_t, list);
        if (hash->hash_cmp_key(hash_item->item, item) == 0) {
            hash->hash_bucket_size[index]--;
            hash->hash_item_num--;
            list_del(&hash_item->list);
            free(hash_item);
            break;
        }
    }
}
/* 查找哈希表单元 */
void *lib_hash_find_item(lib_hash_t *hash, void *item)
{
    u_int32_t index;
    struct list_head *pos;
    lib_hash_item_t *hash_item;

    index = hash->hash_get_index(item) % hash->hash_table_size;
    list_for_each(pos, &hash->hash_table[index]) {
        hash_item = list_entry(pos, libss_hash_item_t, list);
        if (hash->hash_cmp_key(hash_item->item, item) == 0) {
            return hash_item->item;
        }
    }
    return NULL;
}

相关文章

  • 哈希公共服务

    哈希链地址法 哈希的引入是数组和链表的结合体,有效解决了查询/插入/删除的性能问题。但不可避免的引入了哈希冲突问题...

  • 剑指offer-两个链表的第一个公共节点-JavaScript

    题目描述:输入两个链表,找出它们的第一个公共节点。 解法 1: 遍历+哈希表记录 比较容易想到的思路: 开辟哈希表...

  • 2018.4.2

    二、改善和提升公共服务,需要创新公共服务模式,资料中的做法值得借鉴。 (一)建立移动服务平台,实现公共资源共享。 ...

  • 动态 | 哈希未来与EGBOX达成战略合作

    EGBOX与哈希未来携手将推动构建区块链生态,打造去中心化的服务平台。哈希未来旗下产品哈希世界是区块链版大富翁游戏...

  • 通过建立隧道链接内网数据库

    内网有两台主机,一台做公共服务,一台做数据库,其中公共服务有外网ip,而数据库服务没有。公共服务可以链接数据库,但...

  • (1) 面试

    哈希算法处理冲突的机制: 1.开放寻址法2. 再散列法3. 链地址法(拉链法)4. 建立一个公共溢出区参考:哈希表...

  • 2020-04-11

    公益(现代公益 读慈善法) 公共文化服务 公共服务 公有产品 公共空间 以回应国家治理能力体系 (解决社会问题)年...

  • python操作redis

    连接redis服务 Redis 字符串(String) Redis 哈希(Hash) Redis 列表(List)...

  • 2018-07-13

    车主电台接口文档 1、公共参数 1.1、客户端接入API公共参数 1.2、服务端接入API公共参数 公共参数如下:...

  • 华为云计算培训小编和你谈谈公有云

    1、公共云市场规模分析 我国公共云服务市场增长提速。2015年国内公共云服务逐步从互联网向行业市场延伸,市场整体规...

网友评论

      本文标题:哈希公共服务

      本文链接:https://www.haomeiwen.com/subject/boworqtx.html