浅析uthash系列之二:宏函数

uthash版本 :2.0.2
作者:jafon.tian
转载请注明出处:https://blog.csdn.net/JT_Notes

简要说明

uthash是采用宏函数来完成hash表功能。总体上可以分为两大类:
1. API宏函数
2. 内部宏函数

总图

API宏函数

uthash提供了两大类对外API宏函数:
1. 快捷宏函数。快捷宏可以操作key数据类型是整数,指针或字符串的hash表(需要将UT_hash_handle名称取为hh)。快捷宏比一般宏使用更少的参数,对那些采用一般数据类型做key的情形使用起来会简单一些。
2. 一般宏函数。一般宏定义可以被用在key不是一般数据类型或者是多个成员组合或者UT_hash_handle名称不是hh的情形。这些宏需要更多的参数,因而也提供了更大的灵活性。

如果快捷宏已经可以满足你的需要,那就使用快捷宏,这样会使你的代码更具可读性。

  • 便捷宏定义
名称 参数及简要说明
HASH_ADD_INT (head, intfield, add)
基于HASH_ADD的类型定制宏,key类型为int,key大小为sizeof(int)
HASH_ADD(hh,head,intfield,sizeof(int),add)
HASH_REPLACE_INT (head, intfield, add, replaced)
基于HASH_REPLACE的类型定制宏,key类型为int,key大小为sizeof(int)
HASH_REPLACE(hh,head,intfield,sizeof(int),add,replaced)
HASH_FIND_INT (head, findint, out)
基于HASH_FIND的类型定制宏,key类型为int,key大小为sizeof(int)
HASH_FIND(hh,head,findint,sizeof(int),out)
HASH_ADD_STR (head, strfield, add)
基于HASH_ADD的类型定制宏,key类型为char [ ] ,key大小使用uthash_strlen计算
HASH_REPLACE_STR (head, strfield, add, replaced)
基于HASH_REPLACE的类型定制宏,key类型为char [ ] ,key大小使用uthash_strlen计算
HASH_FIND_STR (head, findstr, out)
基于HASH_FIND的类型定制宏,key类型为char [ ] ,key大小使用uthash_strlen计算
HASH_ADD_PTR (head, ptrfield, add)
基于HASH_ADD的类型定制宏,key类型为指针,key大小为sizeof(void *)
HASH_REPLACE_PTR (head, ptrfield, add, replaced)
基于HASH_REPLACE的类型定制宏,key类型为指针,key大小为sizeof(void *)
HASH_FIND_PTR (head, findptr, out)
基于HASH_FIND的类型定制宏,key类型为指针,key大小为sizeof(void *)
HASH_DEL (head, delptr)
基于HASH_DELETE的宏
HASH_SORT (head, cmpfcn)
基于HASH_SRT的宏
HASH_COUNT (head)
基于HASH_CNT的宏

注:使用便捷宏的前提是结构体中的UT_hash_handle成员名称必须为hh,key类型只能是int,char [ ]和指针类型。

  • 一般宏定义
名称 参数
HASH_ADD (hh_name, head, keyfield_name, key_len, item_ptr)
基于HASH_ADD_KEYPTR的宏
HASH_ADD_KEYPTR (hh_name, head, key_ptr, key_len, item_ptr)
通过HASH_VALUE计算出hashvalue之后,直接调用HASH_ADD_KEYPTR_BYHASHVALUE
HASH_ADD_INORDER (hh_name, head, keyfield_name, key_len, item_ptr, cmp)
基于HASH_ADD_KEYPTR_INORDER的宏
HASH_ADD_BYHASHVALUE_INORDER (hh_name, head, keyfield_name, key_len, key_hash, item_ptr, cmp)
基于HASH_ADD_KEYPTR_BYHASHVALUE_INORDER的宏
HASH_ADD_KEYPTR_INORDER (hh_name, head, key_ptr, key_len, item_ptr, cmp)
通过HASH_VALUE计算出hashvalue之后,直接调用HASH_ADD_KEYPTR_BYHASHVALUE_INORDER
HASH_REPLACE (hh_name, head, keyfield_name, key_len, item_ptr, replaced_item_ptr)
通过HASH_VALUE计算出hashvalue之后,直接调用HASH_REPLACE_BYHASHVALUE
HASH_REPLACE_INORDER (hh_name, head, keyfield_name, key_len, item_ptr, replaced_item_ptr, cmp)
通过HASH_VALUE计算出hashvalue之后,直接调用HASH_REPLACE_BYHASHVALUE_INORDER
HASH_FIND (hh_name, head, key_ptr, key_len, item_ptr)
通过HASH_VALUE计算出hashvalue之后,直接调用HASH_FIND_BYHASHVALUE
HASH_DELETE (hh_name, head, item_ptr)
基于HASH_DELETE_HH的宏
HASH_SRT (hh_name, head, cmp)
O(n log(n))的排序算法
HASH_CNT (hh_name, head)
获取hash表所有元素个数
HASH_CLEAR (hh_name, head)
释放uthash资源
HASH_SELECT (dst_hh_name, dst_head, src_hh_name, src_head, condition)
将源hash表中复合条件的元素添加到目标hash表
HASH_ITER (hh_name, head, item_ptr, tmp_item_ptr)
hash表迭代器
HASH_OVERHEAD (hh_name, head)
统计hash表内部结构消耗的内存

内部宏函数

内部函数分为:
1. api支持类
2. bucket操作类
3. hash算法类
4. hh和element转换类
5. 库封装类
6. bloom类
7. 调试和异常处理类

api支持类

名称 参数及简要说明
HASH_VALUE (key_ptr, key_len, key_hash)
计算hashvalue
HASH_ADD_BYHASHVALUE (hh_name, head, keyfield_name, key_len, key_hash, item_ptr)
基于HASH_ADD_KEYPTR_BYHASHVALUE的宏
HASH_ADD_KEYPTR_BYHASHVALUE (hh_name, head, key_ptr, key_len, key_hash, item_ptr)
添加操作的核心宏定义
HASH_ADD_KEYPTR_BYHASHVALUE_INORDER (hh_name, head, key_ptr, key_len, key_hash, item_ptr, cmp)
顺序添加操作的核心宏定义
HASH_REPLACE_BYHASHVALUE (hh_name, head, keyfield_name, key_len, key_hash, item_ptr, replaced_item_ptr)
HASH_FIND_BYHASHVALUE、HASH_DELETE和HASH_ADD_KEYPTR_BYHASHVALUE的组合
HASH_REPLACE_BYHASHVALUE_INORDER (hh_name, head, keyfield_name, key_len, key_hash, item_ptr, replaced_item_ptr, cmp)
HASH_FIND_BYHASHVALUE、HASH_DELETE和HASH_ADD_KEYPTR_BYHASHVALUE_INORDER的组合
HASH_FIND_BYHASHVALUE (hh_name, head, key_ptr, key_len, key_hash, item_ptr)
查找操作的核心宏定义
HASH_DELETE_HH (hh_name, head, delptrhh)
删除操作的核心宏定义

bucket操作类

在bucket中添加、删除、查找元素,根据hashvalue找到对应的bucket,并在适当时机进行bucket回滚和扩张。

名称 参数及简要说明
HASH_TO_BKT (hashv,num_bkts,bkt)
根据hashvalue和bucket总数计算出该hashvalue所在的bucket
HASH_FIND_IN_BKT (tbl,hh,head,keyptr,keylen_in,hashval,out)
在一个bucket中找到拥有指定key的元素
HASH_ADD_TO_BKT (head,hh,addhh,oomed)
将元素添加到bucket中
HASH_DEL_IN_BKT (head,delhh)
将元素从bucket中删除
HASH_ROLLBACK_BKT (hh, head, itemptrhh)
在HASH_ADD_TO_BKT失败时,将bucket滚回添加操作之前的状态
HASH_EXPAND_BUCKETS (hh,tbl,oomed)
扩张bucket数量,核心宏定义

hash算法类

目前版本的uthash支持七种hash算法,具体使用哪一种是通过HASH_FCN来指定的

/* default to Jenkin's hash unless overridden e.g. DHASH_FUNCTION=HASH_SAX */
#ifdef HASH_FUNCTION
#define HASH_FCN HASH_FUNCTION
#else
#define HASH_FCN HASH_JEN
#endif
名称 参数及简要说明
HASH_BER
HASH_FNV
HASH_JEN
HASH_MUR
HASH_SAX
HASH_OAT
HASH_SFH
(key,keylen,hashv)
计算hashvalue

hh和element转换类

名称 参数及简要说明
ELMT_FROM_HH (tbl,hhp)
给定应用结构体变量找到hash表句柄
HH_FROM_ELMT (tbl,elp)
给定hash表句柄找到应用结构体变量

库封装类

#ifndef uthash_malloc
#define uthash_malloc(sz) malloc(sz)      /* malloc fcn                      */
#endif
#ifndef uthash_free
#define uthash_free(ptr,sz) free(ptr)     /* free fcn                        */
#endif
#ifndef uthash_bzero
#define uthash_bzero(a,n) memset(a,'\0',n)
#endif
#ifndef uthash_memcmp
#define uthash_memcmp(a,b,n) memcmp(a,b,n)
#endif
#ifndef uthash_strlen
#define uthash_strlen(s) strlen(s)
#endif

bloom类

名称 参数及简要说明
HASH_BLOOM_BYTELEN bloom占用内存空间的大小(单位是字节)
HASH_BLOOM_MAKE (tbl, oomed)
建立bloom结构
HASH_BLOOM_FREE (tbl)
释放bloom结构
HASH_BLOOM_ADD (tbl, hashv)
根据hashv进行计算出位置,并设置bloom对应位
HASH_BLOOM_TEST (tbl, hashv)
根据hashv进行计算出位置,并判断bloom中相应位是否已置位

调试和异常处理类

名称 参数及简要说明
HASH_RECORD_OOM (oomed)
异常已发生,进行记录
IF_HASH_NONFATAL_OOM 在可恢复情况下,判断异常是否已经发生
uthash_fatal 不可恢复情况下,异常处理
uthash_nonfatal_oom 可恢复情况下,异常处理

猜你喜欢

转载自blog.csdn.net/JT_Notes/article/details/81330023