设为首页 收藏本站
查看: 1064|回复: 0

[经验分享] redis源码笔记-dict.h

[复制链接]

尚未签到

发表于 2015-7-21 09:54:31 | 显示全部楼层 |阅读模式
  这篇介绍redis最后一个基础数据结构——hash表。可以毫不夸张的说,hash表是redis一切存储的基础,也是redis得以快如飞的基础。
  注:其实还有个intset,不过intset是在持久化dump到硬盘时为节省空间设计的,和我们这里谈的不一样。
  dict的设计呢,简单的说是一个双表,“一主一从”,不定时rehash,建议大家在读代码前能够对这个设计有所了解。Anyway,随便搜一搜,很多文章的。
  dict.h



  1 #ifndef __DICT_H
  2 #define __DICT_H
  3
  4 #define DICT_OK 0
  5 #define DICT_ERR 1
  6
  7 /* Unused arguments generate annoying warnings... */
  8 #define DICT_NOTUSED(V) ((void) V)          //redis实现里很多这种NOTUSED宏,算是作者偷懒吧
  9
10 typedef struct dictEntry {
11     void *key;
12     void *val;
13     struct dictEntry *next;
14 } dictEntry;                                 //redis的一个dict表项,存的是key , val, 以及因为redis的hash是用的拉链法,所以有一个指向下一个dictEntry的指针;
                                                 //一个dictEntry的内存占用为12个字节,记住这个数字。
15
16 typedef struct dictType {
17     unsigned int (*hashFunction)(const void *key);        //hash函数
18     void *(*keyDup)(void *privdata, const void *key);     //复制key
19     void *(*valDup)(void *privdata, const void *obj);     //复制value
20     int (*keyCompare)(void *privdata, const void *key1, const void *key2);      //key的compare函数
21     void (*keyDestructor)(void *privdata, void *key);
22     void (*valDestructor)(void *privdata, void *obj);
23 } dictType;                                 //dict的类型
24
25 /* This is our hash table structure. Every dictionary has two of this as we
26  * implement incremental rehashing, for the old to the new table. */
27 typedef struct dictht {
28     dictEntry **table;
29     unsigned long size;    //size
30     unsigned long sizemask;
31     unsigned long used;    //used
32 } dictht;      //这个是hash table结构,每个dictionary有两个hash 表,实现的是递增的rehash
33
34 typedef struct dict {
35     dictType *type;     
36     void *privdata;
37     dictht ht[2];
38     int rehashidx; /* rehashing not in progress if rehashidx == -1 */  //记录是否在rehash的一个flag,rehash进行过程中,有些操作不能进行
39     int iterators; /* number of iterators currently running */         //记录在dict上正在执行的iter数
40 } dict;        //dict的数据结构
41
42 /* If safe is set to 1 this is a safe iteartor, that means, you can call
43  * dictAdd, dictFind, and other functions against the dictionary even while
44  * iterating. Otherwise it is a non safe iterator, and only dictNext()
45  * should be called while iterating. */     
     //迭代器按照是否可以执行改变hash表的函数区别为safe iterator和non safe iterator, non safe iterator只能执行dictNext函数

46 typedef struct dictIterator {
47     dict *d;
48     int table, index, safe;
49     dictEntry *entry, *nextEntry;
50 } dictIterator;
51
52 /* This is the initial size of every hash table */
53 #define DICT_HT_INITIAL_SIZE     4
54
55 /* ------------------------------- Macros ------------------------------------*/
56 #define dictFreeEntryVal(d, entry) \
57     if ((d)->type->valDestructor) \
58         (d)->type->valDestructor((d)->privdata, (entry)->val)
59
60 #define dictSetHashVal(d, entry, _val_) do { \
61     if ((d)->type->valDup) \
62         entry->val = (d)->type->valDup((d)->privdata, _val_); \
63     else \
64         entry->val = (_val_); \
65 } while(0)
66
67 #define dictFreeEntryKey(d, entry) \
68     if ((d)->type->keyDestructor) \
69         (d)->type->keyDestructor((d)->privdata, (entry)->key)
70
71 #define dictSetHashKey(d, entry, _key_) do { \
72     if ((d)->type->keyDup) \
73         entry->key = (d)->type->keyDup((d)->privdata, _key_); \
74     else \
75         entry->key = (_key_); \
76 } while(0)
77
78 #define dictCompareHashKeys(d, key1, key2) \
79     (((d)->type->keyCompare) ? \
80         (d)->type->keyCompare((d)->privdata, key1, key2) : \
81         (key1) == (key2))
82
83 #define dictHashKey(d, key) (d)->type->hashFunction(key)
84
85 #define dictGetEntryKey(he) ((he)->key)
86 #define dictGetEntryVal(he) ((he)->val)
87 #define dictSlots(d) ((d)->ht[0].size+(d)->ht[1].size)
88 #define dictSize(d) ((d)->ht[0].used+(d)->ht[1].used)
89 #define dictIsRehashing(ht) ((ht)->rehashidx != -1)
90
91 /* API */
92 dict *dictCreate(dictType *type, void *privDataPtr);
93 int dictExpand(dict *d, unsigned long size);
94 int dictAdd(dict *d, void *key, void *val);
95 int dictReplace(dict *d, void *key, void *val);
96 int dictDelete(dict *d, const void *key);
97 int dictDeleteNoFree(dict *d, const void *key);
98 void dictRelease(dict *d);
99 dictEntry * dictFind(dict *d, const void *key);
100 void *dictFetchValue(dict *d, const void *key);
101 int dictResize(dict *d);
102 dictIterator *dictGetIterator(dict *d);
103 dictIterator *dictGetSafeIterator(dict *d);
104 dictEntry *dictNext(dictIterator *iter);
105 void dictReleaseIterator(dictIterator *iter);
106 dictEntry *dictGetRandomKey(dict *d);
107 void dictPrintStats(dict *d);
108 unsigned int dictGenHashFunction(const unsigned char *buf, int len);
109 unsigned int dictGenCaseHashFunction(const unsigned char *buf, int len);
110 void dictEmpty(dict *d);
111 void dictEnableResize(void);
112 void dictDisableResize(void);
113 int dictRehash(dict *d, int n);        //进行多少个dictEntry的rehash
114 int dictRehashMilliseconds(dict *d, int ms);   //限制rehash执行的时间,这两个函数都在redis的主流程中被调用,避免因为执行rehash,无法响应client请求。
115
116 /* Hash table types */
117 extern dictType dictTypeHeapStringCopyKey;
118 extern dictType dictTypeHeapStrings;
119 extern dictType dictTypeHeapStringCopyKeyValue;  //三种预先定义好的dictType,具体定义参考其他文件。
120
121 #endif /* __DICT_H */

运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-88960-1-1.html 上篇帖子: Redis简介 下篇帖子: redis 扩展安装使用
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表