Redis源码:dict数据结构(实现)
来源:互联网 发布:中国 美国 差距 知乎 编辑:程序博客网 时间:2024/04/29 06:18
高屋建瓴
本文分析的是src/dict.c文件。
从结构上来说,可以分为:
1. 私有函数(以下划线开头的一般都是,一般都是一些辅助函数);
2. 公开API。
从功能来说,可以分为:
1. dict初始化、析构;
2. 元素操作:查找、删除、插入、替换/修改值、清空数据;
3. 遍历dict,迭代器相关(比如需要持久化哈希表的数据时就很有用);
4. 扩展哈希表(也就是增量扩展哈希表);
5. 哈希函数(这些需要数学知识才能懂,个人觉得开箱即用就好了);
6. 随机化函数……(目前不知道有什么用)。
读完之后,我个人觉得,重点是理解好incremental rehashing是怎么做的以及哈希表的基本操作,其它的都很容易了。
创建与销毁dict
先回顾一下dict的定义,这对理解初始化和析构有好处:
typedef struct dict { dictType *type; void *privdata; dictht ht[2]; long rehashidx; /* rehashing not in progress if rehashidx == -1 */ int iterators; /* number of iterators currently running */} dict;
可以看到,其中除了基础类型(long和int)之外,还有指针和一个dictht数组。一般指针初始化为NULL就好了,然后rehashidx的初始值应该是-1,iterators的初始值应该是0,然后我的一些想法写成了注释放在代码里。
关于创建和初始化,涉及到下面三个函数:
// 其实我觉得这个函数名应该改为_dicthtInit才对,// 因为既不是对dict修改(而是对dictht进行修改),// 也不是Reset操作(而是初始化操作)static void _dictReset(dictht *ht){ ht->table = NULL; ht->size = 0; ht->sizemask = 0; ht->used = 0;}/* Create a new hash table */// 其实我到现在还不知道privdata是什么……待补充dict *dictCreate(dictType *type, void *privDataPtr){ // 注意Redis对malloc封装了,这使得可以自己选择不同的malloc方案 dict *d = zmalloc(sizeof(*d)); _dictInit(d,type,privDataPtr); return d;}/* Initialize the hash table */// 上面这行注释也有问题,其实是Initialize the dict……// 机灵的朋友赶紧做pull request,说不定真的可以被accept// 还有很多地方的代码风格不统一,比如函数传参时多个参数之间只有逗号没有空格int _dictInit(dict *d, dictType *type, void *privDataPtr){ _dictReset(&d->ht[0]); _dictReset(&d->ht[1]); d->type = type; d->privdata = privDataPtr; d->rehashidx = -1; d->iterators = 0; return DICT_OK;}
关于dict的销毁,涉及到下面两个函数,关键知识点是,如何释放动态创建的内容。
/* Destroy an entire dictionary */// 噢...注释又错了,应该是Destroy an entire dict hash tableint _dictClear(dict *d, dictht *ht, void(callback)(void *)) { unsigned long i; /* Free all the elements */ // 讲道理,ht->used > 0这个判断应该是已经够了的,i < ht->size还需要吗?(为了更安全?) for (i = 0; i < ht->size && ht->used > 0; i++) { dictEntry *he, *nextHe; if (callback && (i & 65535) == 0) callback(d->privdata); if ((he = ht->table[i]) == NULL) continue; // 释放一条链表 // 需要先保存下一个结点,因为当前这个结点在赋值之前会被free掉 while(he) { nextHe = he->next; dictFreeKey(d, he); dictFreeVal(d, he); zfree(he); ht->used--; he = nextHe; } } /* Free the table and the allocated cache structure */ zfree(ht->table); /* Re-initialize the table */ _dictReset(ht); return DICT_OK; /* never fails */}/* Clear & Release the hash table */// 值得注意的是,只有动态创建的数据需要自己释放// 还有,它的编程风格,一下子有空格,一下子没有,but not big deal.void dictRelease(dict *d){ _dictClear(d,&d->ht[0],NULL); _dictClear(d,&d->ht[1],NULL); zfree(d);}
增量扩展
later……
1 0
- Redis源码:dict数据结构(实现)
- Redis源码:dict数据结构(声明)
- redis源码系列-数据结构(adlist/ziplist/dict)
- Redis源码分析(dict)
- Redis源码分析(dict)
- redis源码分析(一)-字典(dict)的实现
- 【Redis源码剖析】 - Redis内置数据结构之字典dict
- 【Redis源码剖析】 - Redis内置数据结构之字典dict
- Redis内部数据结构总结(2)dict
- 结合redis设计与实现的redis源码学习-4-dict(字典)
- redis源码分析 dict字典的实现和内部应用
- 【Redis学习】Dict实现
- 解读Redis dict核心数据结构
- redis数据结构之dict 概要
- redis dict.h源码分析
- redis dict.c源码分析
- 【redis源码分析】字典---dict
- Redis源码剖析--字典dict
- 后台不挂断运行命令--linux中nohup的使用
- 小鑫の日常系列故事(六)——奇遇记
- springMVC接收JSON数据转java对象以及Java对象转JSON数据
- 线程信息、中断、等待与休眠(二)
- FZU-2230 翻翻棋(博弈论,规律题)
- Redis源码:dict数据结构(实现)
- Codeforces Round #394 (Div. 2) F. Dasha and Photos 二维前缀和 矩阵神器
- 前端知识点百科大全
- 匹配子串
- 微服务相关
- 欢迎使用CSDN-markdown编辑器
- 17-4-7 学习js基础加强计划暂停
- 【LeetCode】19. Remove Nth Node From End of List
- 伟大的第一步