当前位置:网站首页>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 的动作。
边栏推荐
- 枚举通用接口&枚举使用规范
- Enter the rough outline of the URL question (continuously updated)
- Hisilicon 3559 universal platform construction: RTSP real-time playback support
- Can the applet run in its own app and realize live broadcast and connection?
- 再AD 的 界面顶部(菜单栏)创建常用的快捷图标
- 2022夏每日一题(一)
- Ubuntu 20 installation des enregistrements redisjson
- Docker部署Mysql8的实现步骤
- . Net interface can be implemented by default
- Introduction to opensea platform developed by NFT trading platform (I)
猜你喜欢
GPT-3当一作自己研究自己,已投稿,在线蹲一个同行评议
opencv第三方库
Free PHP online decryption tool source code v1.2
Kalman filter-1
22. (ArcGIS API for JS) ArcGIS API for JS Circle Collection (sketchviewmodel)
Que savez - vous de la sérialisation et de l'anti - séquence?
Search of linear table
Codeworks 5 questions per day (1700 average) - day 7
What is Ba? How about Ba? What is the relationship between Ba and Bi?
qt-线程等01概念
随机推荐
Leetcode: interview question 17.24 Maximum cumulative sum of submatrix (to be studied)
接口数据安全保证的10种方式
How to detect whether the MySQL code runs deadlock +binlog view
浅谈网络安全之文件上传
我的勇敢对线之路--详细阐述,浏览器输入URL发生了什么
Introduction to opensea platform developed by NFT trading platform (I)
ubuntu20安裝redisjson記錄
Optimization cases of complex factor calculation: deep imbalance, buying and selling pressure index, volatility calculation
About Tolerance Intervals
一些常用软件相关
map和set的实现
PIP download only, not install
使用 TiDB Lightning 恢复 GCS 上的备份数据
使用 BR 备份 TiDB 集群到 GCS
Baidu map JS development, open a blank, bmapgl is not defined, err_ FILE_ NOT_ FOUND
Gpt-3 is a peer review online when it has been submitted for its own research
web服务性能监控方案
20. (ArcGIS API for JS) ArcGIS API for JS surface collection (sketchviewmodel)
QT opens a file and uses QFileDialog to obtain the file name, content, etc
预处理——插值