当前位置:网站首页>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 的动作。
边栏推荐
- .net中 接口可以有默认实现了
- Delete data in SQL
- 什么是 BA ?BA怎么样?BA和BI是什么关系?
- 使用 Dumpling 备份 TiDB 集群数据到 GCS
- Que savez - vous de la sérialisation et de l'anti - séquence?
- 枚举通用接口&枚举使用规范
- Allow public connections to local Ruby on Rails Development Server
- The true face of function pointer in single chip microcomputer and the operation of callback function
- QT 项目 表格新建列名称设置 需求练习(找数组消失的数字、最大值)
- About Tolerance Intervals
猜你喜欢

机器学习笔记 - 使用机器学习进行鸟类物种分类

Kotlin Android environment construction

On file uploading of network security

Tencent cloud native database tdsql-c was selected into the cloud native product catalog of the Academy of communications and communications

Ggplot facet detail adjustment summary

My brave way to line -- elaborate on what happens when the browser enters the URL

About Tolerance Intervals

Construction of Hisilicon universal platform: color space conversion YUV2RGB

1200.Minimum Absolute Difference

codeforces每日5题(均1700)-第七天
随机推荐
Arduino droplet detection
你心目中的数据分析 Top 1 选 Pandas 还是选 SQL?
Introduction to opensea platform developed by NFT trading platform (I)
如何自定义Latex停止运行的快捷键
Restcloud ETL Community Edition June featured Q & A
小程序能运行在自有App中,且实现直播和连麦?
What is the experience of maintaining Wanxing open source vector database
Calculation of time and space complexity (notes of runners)
[safe office and productivity application] Shanghai daoning provides you with onlyoffice download, trial and tutorial
本机mysql
链表面试常见题
About Confidence Intervals
Set WiFi automatic connection for raspberry pie
使用 TiDB Lightning 恢复 GCS 上的备份数据
使用 BR 备份 TiDB 集群到 GCS
Tencent cloud native database tdsql-c was selected into the cloud native product catalog of the Academy of communications and communications
Create commonly used shortcut icons at the top of the ad interface (menu bar)
CMB's written test - quantitative relationship
ggplot 分面的细节调整汇总
web服务性能监控方案