哈希表是一种数据结构,通过在记录的存储位置和它的关键字之间建立确定的对应关系,来快速查询表中的数据;

openssl lhash.h 为我们提供了哈希表OPENSSL_LHASH 的相关接口,我们可以直接使用,用来存放各种数据;

哈希表类似前面提到的栈,但是哈希表的优势是查询速度快。

1. lhash.h 提供的哈希表主要接口有

//创建哈希表,参数为两个回调函数,分别可自定义哈希值计算方法,排序方法
OPENSSL_LHASH *OPENSSL_LH_new(OPENSSL_LH_HASHFUNC h, OPENSSL_LH_COMPFUNC c); //释放哈希表内存,但是不释放表中数据的内存,需要调用下面的doall方法遍历表中数据去释放
void OPENSSL_LH_free(OPENSSL_LHASH *lh); //在表中插入一条记录,当表中有该数据时,会进行替换,成功返回插入的数据地址
void *OPENSSL_LH_insert(OPENSSL_LHASH *lh, void *data); //从表中删除一条记录,成功返回删除的该数据地址
void *OPENSSL_LH_delete(OPENSSL_LHASH *lh, const void *data); //从表中查询一条记录,参数为要查询数据的地址,成功返回表中该数据的地址
void *OPENSSL_LH_retrieve(OPENSSL_LHASH *lh, const void *data); //遍历表中的数据记录,回调函数可处理遍历每条记录
void OPENSSL_LH_doall(OPENSSL_LHASH *lh, OPENSSL_LH_DOALL_FUNC func); //遍历表中的数据记录,多了一个arg参数,可看下面的测试
void OPENSSL_LH_doall_arg(OPENSSL_LHASH *lh, OPENSSL_LH_DOALL_FUNCARG func, void *arg); //计算一条数据的哈希值
unsigned long OPENSSL_LH_strhash(const char *c); //哈希表中元素个数
unsigned long OPENSSL_LH_num_items(const OPENSSL_LHASH *lh); //查看哈希表的状态,输出到FILE
void OPENSSL_LH_stats(const OPENSSL_LHASH *lh, FILE *fp); //查看哈希表节点的状态,输出到FILE
void OPENSSL_LH_node_stats(const OPENSSL_LHASH *lh, FILE *fp); //查看哈希表节点的使用状态,输出到FILE
void OPENSSL_LH_node_usage_stats(const OPENSSL_LHASH *lh, FILE *fp);

//以下接口为哈希表状态,输出到BIO
void OPENSSL_LH_stats_bio(const OPENSSL_LHASH *lh, BIO *out);
void OPENSSL_LH_node_stats_bio(const OPENSSL_LHASH *lh, BIO *out);
void OPENSSL_LH_node_usage_stats_bio(const OPENSSL_LHASH *lh, BIO *out);

2. 测试代码

unsigned long hashff(void *hf)
{
printf("%s\n",hf);
return ;
} int hashfCmp(int *a,int *b)
{
return *a > *b; } void printArg(int *a,char *b)
{
printf("doall_arg: %d %s\n",*a,b);
} void printValue(int *value)
{
printf("doall: %d\n",*value);
} int main(int argc, const char * argv[]) { OPENSSL_LHASH *lh = OPENSSL_LH_new(NULL, NULL); int item = ;
OPENSSL_LH_insert(lh, &item); int item2 = ;
OPENSSL_LH_insert(lh, &item2); int item3 = ;
OPENSSL_LH_insert(lh, &item3); //因为表中已经存在数据5,如果再插入,将会替换之前的数据5
int item4 = ;
int *ret=;
ret = OPENSSL_LH_insert(lh, &item4);
if (*ret==item4) {
printf("insert replace PASS\n");
} int *fd = ;
fd = OPENSSL_LH_retrieve(lh,&item2);
if (*fd == item2) {
printf("find value PASS\n");
} OPENSSL_LH_doall(lh, printValue);
OPENSSL_LH_doall_arg(lh, printArg, "arg"); int *delRet = ;
delRet = OPENSSL_LH_delete(lh, &item4);
if (*delRet==item4) {
printf("delete value PASS\n");
} int numLen = OPENSSL_LH_num_items(lh);
printf("len=%d\n"); OPENSSL_LH_stats(lh, stdout); OPENSSL_LH_free(lh); return ;
}

输出日志

insert replace PASS
find value PASS
doall:
doall:
doall:
doall_arg: arg
doall_arg: arg
doall_arg: arg
delete value PASS
len=
num_items =
num_nodes =
num_alloc_nodes =
num_expands =
num_expand_reallocs =
num_contracts =
num_contract_reallocs =
num_hash_calls =
num_comp_calls =
num_insert =
num_replace =
num_delete =
num_no_delete =
num_retrieve =
num_retrieve_miss =
num_hash_comps =
Program ended with exit code:

测试使用 openssl 1.1.0c

参考:https://www.openssl.org/docs/man1.0.2/crypto/lhash.html

openssl lhash 数据结构哈希表的更多相关文章

  1. (js描述的)数据结构[哈希表1.1](8)

    (js描述的)数据结构[哈希表1.1](8) 一.数组的缺点 1.数组进行插入操作时,效率比较低. 2.数组基于索引去查找的操作效率非常高,基于内容去查找效率很低. 3.数组进行删除操作,效率也不高. ...

  2. C#数据结构----------------------------哈希表源码解析

    转载: C# Hashtable源码剖析 源代码版本为 .NET Framework 4.6.1 本系列持续更新,敬请关注 有投入,有产出. Hashtable实现一个哈希表(也叫散列表),将键映射到 ...

  3. JAVA数据结构--哈希表的实现(分离链接法)

    哈希表(散列)的定义 散列表(Hash table,也叫哈希表),是根据关键码值(Key value)而直接进行访问的数据结构.也就是说,它通过把关键码值映射到表中一个位置来访问记录,以加快查找的速度 ...

  4. java数据结构----哈希表

    1.哈希表:它是一种数据结构,可以提供快速的插入操作和查找操作.如果哈希表中有多少数据项,插入和删除操作只需要接近常量的时间.即O(1)的时间级.在计算机中如果需要一秒内查找上千条记录,通常使用哈希表 ...

  5. 数据结构 -- 哈希表(hash table)

    简介   哈希表(Hash table,也叫散列表),是根据关键码值(Key value)而直接进行访问的数据结构.也就是说,它通过把关键码值映射到表中一个位置来访问记录,以加快查找的速度.这个映射函 ...

  6. Redis原理再学习04:数据结构-哈希表hash表(dict字典)

    哈希函数简介 哈希函数(hash function),又叫散列函数,哈希算法.散列函数把数据"压缩"成摘要,有的也叫"指纹",它使数据量变小且数据格式大小也固定 ...

  7. 数据结构 哈希表(Hash Table)_哈希概述

    哈希表支持一种最有效的检索方法:散列. 从根来上说,一个哈希表包含一个数组,通过特殊的索引值(键)来访问数组中的元素. 哈希表的主要思想是通过一个哈希函数,在所有可能的键与槽位之间建立一张映射表.哈希 ...

  8. java数据结构——哈希表(HashTable)

    哈希表提供了快速的插入操作和查找操作,每一个元素是一个key-value对,其基于数组来实现. 一.Java中HashMap与Hashtable的区别: HashMap可以接受null键值和值,而Ha ...

  9. 数据结构---哈希表的C语言实现(闭散列)

    原文地址:https://blog.csdn.net/weixin_40331034/article/details/79461705 构造一种存储结构,通过某种函数(hashFunc)使元素的存储位 ...

随机推荐

  1. Xubuntu VNC Xfce4

    sudo mousepad ~/.vnc/xstartup #!/bin/sh # Uncomment the following two lines for normal desktop: unse ...

  2. 关于缺少nvToolsExt64_1.lib时的PhysX的处理

    我本人之所以缺少这个文件是因为我的PhysX如果你的PhysX是从UE4源代码中提取的,那么可能会出现如下错误,提示找不到nvToolsExt64_1.lib(本机是64bit的操作系统) 那就执行u ...

  3. ORA-12637解决问题

    今天用Oracle客户端连接服务端时,总是连接不上,错误信息:ORA-12637,问题解决如下: 找到 本地 SQLNET.ORA 文件 打开: # sqlnet.ora Network Config ...

  4. LDD3 字符设备驱动简单分析

    最近在看LDD3,理解了一下,为了加深自己的印象,自己梳理一下.我用的CentOS release 6.6 (Final)系统. 一.编写编译内核模块的Makefile 以下是我用的Makefile ...

  5. Cellebrite UFED 5.1 发布,全面支持三星 S6 S6 Edge Note5 HUAWEI series

    世界级取证公司Cellebrite 昨天发布了最新的 UFED 5.1 系统更新,4PC全面支持三星S6,S6EDGE NOTE5 以及HUAWEI,LG系列恢复,锁屏密码XX!下面是部分截图 有需要 ...

  6. Prince2七大主题之风险

    Prince2七大主题之风险   我们前几个节学习了PRINCE2七大主题的商业论证.组织.质量和计划,今天我们开展对于风险模块的讲解. 风险:目的是识别.评估和控制不确定性,从而提高项目的成功率.P ...

  7. TopCoder kawigiEdit插件配置

    kawigiEdit插件可以提高 TopCoder编译,提交效率,可以管理保存每次SRM的代码. kawigiEdit下载地址:http://code.google.com/p/kawigiedit/ ...

  8. java动态代理原理

    我们经常会用到Java的动态代理技术, 虽然会使用, 但是自己对其中的原理却不是很了解.比如代理对象是如何产生的, InvocationHandler的invoke方法是如何调用的?今天就来深究下Ja ...

  9. tomcat7 日志设置为log4j

    tomcat的日志设置用log4j的官方文档:http://tomcat.apache.org/tomcat-7.0-doc/logging.html 1. 下载tomcat-juli.jar, to ...

  10. table表格在设置文字垂直居中后,在表格显示相同排列的数据(比如:testtesttesttsttesttesstestse很多的test)时此表格不能换行

    table设置了垂直居中后在表格显示相同排列的数据(比如:testtesttesttsttesttesstestse很多的test)时此表格不能换行, 此时会导致table会把页面撑的很宽,导致表格后 ...