当前位置:网站首页>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 的动作。
边栏推荐
- 预处理——插值
- Force buckle ----- path sum III
- Preprocessing - interpolation
- Introduction to opensea platform developed by NFT trading platform (I)
- QT thread and other 01 concepts
- Calculation of time and space complexity (notes of runners)
- Allow public connections to local Ruby on Rails Development Server
- 20.(arcgis api for js篇)arcgis api for js面采集(SketchViewModel)
- Native MySQL
- Enumeration general interface & enumeration usage specification
猜你喜欢

Clock in during winter vacation
![[security attack and Defense] how much do you know about serialization and deserialization?](/img/1c/e5ae74e65bacf688d7f61cc1b71d3e.png)
[security attack and Defense] how much do you know about serialization and deserialization?

自适应非欧表征广告检索系统AMCAD

GPT-3当一作自己研究自己,已投稿,在线蹲一个同行评议

小程序能运行在自有App中,且实现直播和连麦?

Basic concepts of Huffman tree

太方便了,钉钉上就可完成代码发布审批啦!

VHDL implementation of arbitrary size matrix addition operation

预处理——插值

List interview common questions
随机推荐
【开发软件】 tilipa开发者软件
MySQL的存储引擎
如何检测mysql代码运行是否出现死锁+binlog查看
Confirm the future development route! Digital economy, digital transformation, data This meeting is very important
【安全攻防】序列化與反序列,你了解多少?
哈夫曼树基本概念
19. (ArcGIS API for JS) ArcGIS API for JS line acquisition (sketchviewmodel)
[MySQL] row sorting in MySQL
自适应非欧表征广告检索系统AMCAD
代码质量管理
1200.Minimum Absolute Difference
Native MySQL
Optimization cases of complex factor calculation: deep imbalance, buying and selling pressure index, volatility calculation
.net中 接口可以有默认实现了
Arduino droplet detection
【mysql】mysql中行排序
1200.Minimum Absolute Difference
Open3D 网格滤波
使用切面实现记录操作日志
Tencent cloud native database tdsql-c was selected into the cloud native product catalog of the Academy of communications and communications