关于uthash 的初步源码阅读

本文深入探讨了nutHash开源库的使用方法与内部结构,重点介绍了如何在用户自定义结构体中集成UT_hash_handle,以及库中head节点的作用。通过对UT_hash_handle和UT_hash_table结构体的详细分析,揭示了哈希表的工作原理和优化机制。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

背景:

在偶然的mqtt(mosquitto)中的源码中查看的关于topic的处理,知道了哈希表这种的数据结构,最近花了一点时间将这个部分的源码看了一部分,不知道后面还有没有时间继续查看所以就写一篇文档作为笔记吧。

uthash 使用

uthash 这个开源库使用起来很方便,只有一个头文件(uthash .h),在源代码中只要包含这个头文件就可以进行使用了这个里面的接口
针对使用在网络上能够搜索到的示例代码比较多。这里就是记录一些不一样的地方。
(1)用户结构体

struct my_struct {  
    char name[10];             /* key (string is WITHIN the structure) */  
    int id;  
    UT_hash_handle hh;         /* makes this structure hashable */  
}; 

用户定义的结构体中需要包含这个UT_hash_handle,这个元素,这个元素将会在库的内部使用
(2)head
库提供的函数都会有一个head节点,这个实际上也是一个指针,这个指针相当于链表的头或者数组结构体,在这个head添加之后的节点,搜索的时候就只会搜索head下面的节点

源码结构体分析

首先是这个结构体

typedef struct UT_hash_handle {
   struct UT_hash_table *tbl;
   void *prev;                       /* prev element in app order      */
   void *next;                       /* next element in app order      */
   struct UT_hash_handle *hh_prev;   /* previous hh in bucket order    */
   struct UT_hash_handle *hh_next;   /* next hh in bucket order        */
   void *key;                        /* ptr to enclosing struct's key  */
   unsigned keylen;                  /* enclosing struct's key len     */
   unsigned hashv;                   /* result of hash-fcn(key)        */
} UT_hash_handle;

tbl----存放在数组成员
prev—用户添加的上一个成员
next–该节点之后添加的成员
hh_prev—计算出key的hash冲突的上一个节点
hh_next–hash冲突的下一个节点
key----关键词的内容
keylen—关键词的长度
hashv—关键词的hash结果

typedef struct UT_hash_table {
   UT_hash_bucket *buckets;
   unsigned num_buckets, log2_num_buckets;
   unsigned num_items;
   struct UT_hash_handle *tail; 
   ptrdiff_t hho; 
   unsigned ideal_chain_maxlen;
    unsigned nonideal_items;
   unsigned ineff_expands, noexpand;
   uint32_t signature; /* used only to find hash tables in external analysis */
#ifdef HASH_BLOOM
   uint32_t bloom_sig; /* used only to test bloom exists in external analysis */
   uint8_t *bloom_bv;
   char bloom_nbits;
#endif
} UT_hash_table;

buckets—数组的地址,存放这个head下面的成员
num_buckets—数组的大小
log2_num_buckets—数组的大小的log
num_items—暂时不清楚
tail----添加的最后一个元素
hho----节点的hh和节点的偏差
UT_hash_handle结构在用户结构中的偏移位置,通过UT_hash_handle对象减去hho定位到用户结构对象
ideal_chain_maxlen—暂时不涉及
nonideal_items—暂时不涉及
.ineff_expands—暂时不涉及
noexpand—暂时不涉及
signature--------0xa0111fe1

typedef struct UT_hash_bucket {
   struct UT_hash_handle *hh_head;
   unsigned count;
   unsigned expand_mult;
} UT_hash_bucket;

UT_hash_handle – 存放节点
count----当前这个位置的节点个数
expand_mult—暂时不涉及

额外的基础知识

typeof的用法
把y定义成x指向的数据类型:
typeof(*x) y;

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值