哈希表C开源的uthash的简单初步封装(二)
来源:互联网 发布:linux dhcp服务配置 编辑:程序博客网 时间:2024/06/02 05:12
概述:在上一篇博客中,简单封装了key为int类型的哈希表的增删,遍历等函数,但是在上一篇封装中,函数均是可见的,可能并不安全,所以这一次就将函数封装到结构体,像使用c++一样,直接通过结构体就可以运行函数。所有函数操作都是静态的,这样操作更加方便快捷。此次封装了key为int, char[],char * , void *四种类型的哈希表结构。在多线程中,依旧是不安全的,后期有时间会加入互斥锁,读写锁到里面,用于多线程。
1,这里就说一下key类型为char []的封装,先看.h文件,先封装一个hash的结构体,再定义一个hash控制结构体,将操作函数放在hash控制结构体,同时将hash的结构体也放入hash控制结构体。
#ifndef _SKY_HASH_H_#define _SKY_HASH_H_#include <stdlib.h>#include "uthash.h"#define KEY_ARR_SIZE 16typedef struct hash_arr hash_arr_t;typedef void (*hash_arr_cb_t)(hash_arr_t *, void *);/*key 为char[]类型结构体封装*/typedef hash_arr_t *(*hash_arr_find_t)(hash_arr_t **, char *);typedef int (*hash_arr_add_t)(hash_arr_t **, char *, void *);typedef int (*hash_arr_del_t)(hash_arr_t **, char *);typedef void (*hash_arr_delall_t)(hash_arr_t **);typedef int (*hash_arr_count_t)(hash_arr_t **);typedef void (*hash_arr_ergodic_t)(hash_arr_t **, hash_arr_cb_t, void *);typedef struct hash_arr_ctl hash_arr_ctl_t;struct hash_arr { char key[KEY_ARR_SIZE]; /* key */ void *data; /*数据*/ UT_hash_handle hh; /* makes this structure hashable */ };struct hash_arr_ctl { hash_arr_t *hash; hash_arr_find_t find; hash_arr_add_t add; hash_arr_del_t del; hash_arr_delall_t delall; hash_arr_count_t count; hash_arr_ergodic_t ergodic;};/*char []类型key相关操作函数*/void hash_arr_create(hash_arr_ctl_t *ha);
2,我们再看一下sky_hash.c文件,这个就没啥了,主要就是uthash的函数使用及简单封装,看uthash操作手册就可以看懂了。
#include <stdio.h>#include <stdlib.h>#include "uthash.h"#include "sky_hash.h"/***************************************************************************** 下方封装key为char []类型的增删,遍历等操作。 By Sky(Peace&Love)******************************************************************************//*查找键值*/hash_arr_t *hash_arr_find(hash_arr_t **hashlist, char key[]){ hash_arr_t *hd = NULL; HASH_FIND_STR(*hashlist,key,hd); return hd;}/*添加键值对*/int hash_arr_add(hash_arr_t **hashlist, char key[], void *data){ hash_arr_t *hd = hash_arr_find(hashlist,key); if (NULL == hd) { hd = (hash_arr_t *)malloc(sizeof(hash_arr_t)); strncpy(hd->key,key,KEY_ARR_SIZE); hd->data = data; HASH_ADD_STR(*hashlist,key,hd); } else { return -1; } return 0;}/*删除指定键值对*/static int hash_arr_del(hash_arr_t **hashlist, char key[]){ hash_arr_t *hd = hash_arr_find(hashlist,key); if (NULL == hd) { return -1; } HASH_DEL(*hashlist, hd); if (NULL != hd->data) { free(hd->data); hd->data = NULL; } free(hd); hd = NULL; return 0;}/*删除所有键值对*/static void hash_arr_delall(hash_arr_t **hashlist){ hash_arr_t *hd,*tmp; HASH_ITER(hh, *hashlist, hd, tmp) { HASH_DEL(*hashlist, hd); if (NULL != hd->data) { free(hd->data); hd->data = NULL; } free(hd); hd = NULL; } if (NULL != *hashlist) { free(*hashlist); *hashlist = NULL; }}/*遍历哈希表*/static void hash_arr_ergodic(hash_arr_t **hashlist, hash_arr_cb_t callback, void *arg){ hash_arr_t *hd,*tmp; HASH_ITER(hh, *hashlist, hd, tmp) { callback(hd,arg); }}/*获取哈希表项目个数*/static int hash_arr_count(hash_arr_t **hashlist){ return HASH_COUNT(*hashlist);}/*key为char []类型的哈希表创建初始化*/void hash_arr_create(hash_arr_ctl_t *ha){ ha->hash = NULL; ha->find = hash_arr_find; ha->add = hash_arr_add; ha->del = hash_arr_del; ha->delall = hash_arr_delall; ha->count = hash_arr_count; ha->ergodic = hash_arr_ergodic;}
3,我们做一个测试程序,验证封装函数的正确性。
#include <stdio.h>#include <stdlib.h>#include <unistd.h>#include "./hash/sky_hash.h"typedef struct sky sky_t;/*只做测试使用,可以自定义*/struct sky { int num; /*用户可以自己再增加字段*/};void callback_keyarr(hash_arr_t *hd, void *arg){ sky_t *value = hd->data; printf("key:%s,num:%d\n",hd->key,value->num);}void test_keyarr(){ hash_arr_ctl_t *ha = (hash_arr_ctl_t *)malloc(sizeof(hash_arr_ctl_t)); hash_arr_create(ha); char *key[] = {"bboy","born","sky","peace","love"}; int i; /*哈希表中添加数据*/ for (i = 0 ; i < 5 ; i ++) { sky_t *value = (sky_t *)malloc(sizeof(sky_t)); value->num = i; if (0 != ha->add(&ha->hash,key[i],value)) { printf("hash add failed\n"); free(value); } } printf("ha:%p\n",ha->hash); /*遍历哈希表*/ ha->ergodic(&ha->hash,callback_keyarr,NULL); /*获取哈希表项目个数*/ int count = ha->count(&ha->hash); printf("hash count:%d\n",count); /*查找哈希表*/ char fkey[16] = {0}; char *bb = "born"; memcpy(fkey,bb,5); hash_arr_t *node = ha->find(&ha->hash,fkey); if (NULL != node) { sky_t *value = node->data; printf("find key[born] value num = %d\n",value->num); /*修改key对应的数据值*/ value->num = 100; } else { printf("not found\n"); } /*删除指定项目*/ ha->del(&ha->hash,"bboy"); /*遍历哈希表*/ ha->ergodic(&ha->hash,callback_keyarr,NULL); /*删除整个哈希表*/ ha->delall(&ha->hash); printf("ha:%p\n",ha->hash); free(ha);}int main(){ test_keyarr(); return 0;}
4,运行结果如下:
5,所有代码传到码云,develop分支。需要的话可以看下。地址在上一篇有。
阅读全文
0 0
- 哈希表C开源的uthash的简单初步封装(二)
- 哈希表C开源的uthash的简单初步封装(一)
- C开源hash代码uthash的用法总结(1)
- C开源hash代码uthash的用法总结(2)
- C开源hash代码uthash的用法总结(1)
- 简单好用的hash表-----uthash
- C语言哈希表 uthash
- data_support/uthash(使用哈希表的一些函数)
- 超好用的uthash万岁~~~
- uthash的三个数据结构
- UThash 的数据结构
- UThash 的数据结构
- 超好用的uthash万岁~~~
- 基于uthash的GNU/linux下简单hash_table模板类
- C开源hash代码uthash的用法总结
- C开源hash代码uthash的用法总结
- 一个通用简单线程池实现的初步封装(C语言)
- 简单的分页封装(二)
- Java线程死锁查看分析方法
- 嵌入式学习文章
- Android 触摸事件传递流程解析
- 2.5 数组
- 服务器容错保护(Hystrix依赖隔离)
- 哈希表C开源的uthash的简单初步封装(二)
- 个人开发者如何通过人工智能盈利?智能原理及阿尔法狗详解
- MM 委外加工(Subconctracting)流程
- Java中四种代码块的区别
- C++移位运算符
- CentOS 7 修改主机名
- 安装单节点的zookeeper
- GDAL+VS2010
- 排列组合(c/python)