当前位置:网站首页>Redis源码学习(31),字典学习,dict.c(一)
Redis源码学习(31),字典学习,dict.c(一)
2022-07-06 21:10:00 【无痕之意】
1 dictCreate
1.1 方法说明
创建一个新的 hash table
1.2 方法源码
/* Create a new hash table */
dict *dictCreate(dictType *type,
void *privDataPtr)
{
dict *d = zmalloc(sizeof(*d));//分配内存
_dictInit(d,type,privDataPtr);//字典初始化
return d;
}
1.3 相关方法
1.3.1 _dictInit
/* Initialize the hash table */
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;
}
1.3.2 _dictReset
/* Reset a hash table already initialized with ht_init(). * NOTE: This function should only be called by ht_destroy(). */
static void _dictReset(dictht *ht)
{
ht->table = NULL;
ht->size = 0;
ht->sizemask = 0;
ht->used = 0;
}
1.4 代码理解
- 先申明一个字典结构体,并分配相应内存。
- 调用 _dictInit 初始化字典。
- 调用 _dictReset 初始化字典中两个哈希表。
- 将哈希表中几个属性字段都设置为初始值。
2 dictAdd
2.1 方法说明
增加一个哈希节点到哈希表中。
2.2 方法源码
/* Add an element to the target hash table */
int dictAdd(dict *d, void *key, void *val)
{
dictEntry *entry = dictAddRaw(d,key);
if (!entry) return DICT_ERR;
dictSetVal(d, entry, val);
return DICT_OK;
}
2.3 相关代码
2.3.1 dictAddRaw
/* Low level add. This function adds the entry but instead of setting * a value returns the dictEntry structure to the user, that will make * sure to fill the value field as he wishes. * * This function is also directly exposed to the user API to be called * mainly in order to store non-pointers inside the hash value, example: * * entry = dictAddRaw(dict,mykey); * if (entry != NULL) dictSetSignedIntegerVal(entry,1000); * * Return values: * * If key already exists NULL is returned. * If key was added, the hash entry is returned to be manipulated by the caller. */
dictEntry *dictAddRaw(dict *d, void *key)
{
int index;
dictEntry *entry;
dictht *ht;
// 如果字典在进行 rahase 中,则进行一步 rahash
if (dictIsRehashing(d)) _dictRehashStep(d);
/* Get the index of the new element, or -1 if * the element already exists. */
// 获取建的索引
if ((index = _dictKeyIndex(d, key)) == -1)
return NULL;
/* Allocate the memory and store the new entry */
// 如果在 rehash 中 则返回第二个 hash 表中
// 将新的哈希节点加入第二个 hash 表中
ht = dictIsRehashing(d) ? &d->ht[1] : &d->ht[0];
entry = zmalloc(sizeof(*entry));
entry->next = ht->table[index];
ht->table[index] = entry;
ht->used++;
/* Set the hash entry fields. */
//设置哈希建
dictSetKey(d, entry, key);
return entry;
}
2.3.2 _dictKeyIndex
/* Returns the index of a free slot that can be populated with * a hash entry for the given 'key'. * If the key already exists, -1 is returned. * * Note that if we are in the process of rehashing the hash table, the * index is always returned in the context of the second (new) hash table. */
static int _dictKeyIndex(dict *d, const void *key)
{
unsigned int h, idx, table;
dictEntry *he;
/* Expand the hash table if needed */
if (_dictExpandIfNeeded(d) == DICT_ERR)
return -1;
/* Compute the key hash value */
h = dictHashKey(d, key);
for (table = 0; table <= 1; table++) {
idx = h & d->ht[table].sizemask;
/* Search if this slot does not already contain the given key */
he = d->ht[table].table[idx];
while(he) {
if (dictCompareKeys(d, key, he->key))
return -1;
he = he->next;
}
if (!dictIsRehashing(d)) break;
}
return idx;
}
2.4 代码理解
- 调用 dictAddRaw 增加一个哈希节点
- 计算键的索引值,如果该值已经存在则返回错误
- 如果正在进行 rehash 的话,会向第二个哈希表中新增节点
- 调用宏定义方法 dictSetKey 设置哈希节点的键
- 调用宏定义方法 dictSetVal 设置哈希节点的值
3 学习总结
- 增加新的哈希节点的时候,如果节点已存在则会报错。
- 调用 dictHashKey 计算键的哈希值。
- 再用哈希值与字典掩码计算出索引位置。
- 遍历两个哈希表,判断键是否已存在。
- 如果字典正在 rehash 中的话,则新增的节点会加到第二个哈希表中。
- 如果字典正在 rehash 中的话, 则会进行一步的 rehash 的动作。
边栏推荐
- About Confidence Intervals
- opencv第三方库
- cuda编程
- Code quality management
- QT opens a file and uses QFileDialog to obtain the file name, content, etc
- 20.(arcgis api for js篇)arcgis api for js面采集(SketchViewModel)
- Create commonly used shortcut icons at the top of the ad interface (menu bar)
- ERROR: Could not build wheels for pycocotools which use PEP 517 and cannot be installed directly
- Class常量池与运行时常量池
- 使用切面实现记录操作日志
猜你喜欢
太方便了,钉钉上就可完成代码发布审批啦!
About Tolerance Intervals
2022夏每日一题(一)
[MySQL] row sorting in MySQL
1.19.11.SQL客户端、启动SQL客户端、执行SQL查询、环境配置文件、重启策略、自定义函数(User-defined Functions)、构造函数参数
19. (ArcGIS API for JS) ArcGIS API for JS line acquisition (sketchviewmodel)
Ubuntu20 installation redisjson record
未来发展路线确认!数字经济、数字化转型、数据...这次会议很重要
Optimization cases of complex factor calculation: deep imbalance, buying and selling pressure index, volatility calculation
When QT uses qtooltip mouse to display text, the picture of the button will also be displayed and the prompt text style will be modified
随机推荐
三重半圆环进度条,直接拿去就能用
MySQL的索引
19. (ArcGIS API for JS) ArcGIS API for JS line acquisition (sketchviewmodel)
1200.Minimum Absolute Difference
ggplot 分面的细节调整汇总
Calculation of time and space complexity (notes of runners)
Ubuntu20 installation redisjson record
Create commonly used shortcut icons at the top of the ad interface (menu bar)
Optimization cases of complex factor calculation: deep imbalance, buying and selling pressure index, volatility calculation
SSL certificate deployment
二叉搜索树的实现
Basic concepts of Huffman tree
大白话高并发(二)
Force buckle ----- path sum III
[hcie TAC] question 3
Flutter3.0, the applet is not only run across mobile applications
我的勇敢对线之路--详细阐述,浏览器输入URL发生了什么
复杂因子计算优化案例:深度不平衡、买卖压力指标、波动率计算
一些常用软件相关
codeforces每日5题(均1700)-第七天