dict.h
在redis中,dict.h主要是hash的底层实现方式。
在dict.h中主要是一些数据结构的定义,以及一些宏函数的定义相关的内容。
哈希节点定义
源代码中的dictEntry就是哈希节点的相关定义
typedef struct dictEntry {
void *key; //存放key值
union { //使用一个union存放value值
void *val;
uint64_t u64;
int64_t s64;
double d;
} v;
struct dictEntry *next; //hash冲突使用开链法,因此使用了一个next指针指向下一个节点
} dictEntry;
dictType
在dictType中,存放了一些操作函数
typedef struct dictType {
uint64_t (*hashFunction)(const void *key); //哈希函数
void *(*keyDup)(void *privdata, const void *key); //key复制
void *(*valDup)(void *privdata, const void *obj); //value复制
int (*keyCompare)(void *privdata, const void *key1, const void *key2); //key比较函数
void (*keyDestructor)(void *privdata, void *key); //key析构
void (*valDestructor)(void *privdata, void *obj); //value析构
} dictType;
dictht
dictht就是哈希表的结构
`typedef struct dictht {
dictEntry **table; //哈希节点指针数组
unsigned long size; //哈希长度
unsigned long sizemask; //哈希掩码(用于计算哈希索引)
unsigned long used; //已经使用的节点数目
} dictht;
``
#### dict
//字典的数据结构的定义
```c
typedef struct dict {
dictType *type; //保存一些函数
void *privdata; //私有数据
dictht ht[2]; //哈希表,注意,这里的哈希表有两张,主要是为了rehash操作预备
long rehashidx; //哈希索引
unsigned long iterators; //记录正在使用的迭代器数量
} dict;```
#### dictIterator
dictIterator充当字典迭代器的作用。
这里的迭代器分为了两种,一种迭代器是safe的,它可以进行读写操作
另外一种迭代器是unsafe的,是一种只读迭代器
```c
`typedef struct dictIterator {
dict *d; //字典
long index; //字典索引
int table, safe; //safe标志是否为safe迭代器,table标志当前哈希表号码(0或者1
dictEntry *entry, *nextEntry; //当前节点与下一个节点
long long fingerprint; //dict指纹,避免迭代器失效的作用
} dictIterator;
另外一些宏函数
//释放节点
#define dictFreeVal(d, entry) \
if ((d)->type->valDestructor) \ //如果hashType中定义了valDestructor函数的话,调用其释放节点
(d)->type->valDestructor((d)->privdata, (entry)->v.val)
//设置节点的value
#define dictSetVal(d, entry, _val_) do { \
if ((d)->type->valDup) \ //如果存在value复制函数,就调用value复制函数,否则直接赋值
(entry)->v.val = (d)->type->valDup((d)->privdata, _val_); \
else \
(entry)->v.val = (_val_); \
} while(0)
//设置int的value值
#define dictSetSignedIntegerVal(entry, _val_) \
do { (entry)->v.s64 = _val_; } while(0)
//设置unsigned的value值
#define dictSetUnsignedIntegerVal(entry, _val_) \
do { (entry)->v.u64 = _val_; } while(0)
//设置double的value值
#define dictSetDoubleVal(entry, _val_) \
do { (entry)->v.d = _val_; } while(0)
//释放key值,调用dictType中的函数释放
#define dictFreeKey(d, entry) \
if ((d)->type->keyDestructor) \
(d)->type->keyDestructor((d)->privdata, (entry)->key)
//设置key
//如果存在keyDup函数,那么调用keyDup函数,否则直接赋值
#define dictSetKey(d, entry, _key_) do { \
if ((d)->type->keyDup) \
(entry)->key = (d)->type->keyDup((d)->privdata, _key_); \
else \
(entry)->key = (_key_); \
} while(0)
//比较key,同样的,调用dictType中的keyCompare函数
#define dictCompareKeys(d, key1, key2) \
(((d)->type->keyCompare) ? \
(d)->type->keyCompare((d)->privdata, key1, key2) : \
(key1) == (key2))
//获取hash
#define dictHashKey(d, key) (d)->type->hashFunction(key)
#define dictGetKey(he) ((he)->key) //得到节点的key
#define dictGetVal(he) ((he)->v.val) //得到节点的value值
#define dictGetSignedIntegerVal(he) ((he)->v.s64) //得到节点的int值
#define dictGetUnsignedIntegerVal(he) ((he)->v.u64) //得到节点的unsigned int值
#define dictGetDoubleVal(he) ((he)->v.d) //得到节点的value值
#define dictSlots(d) ((d)->ht[0].size+(d)->ht[1].size) //总size
#define dictSize(d) ((d)->ht[0].used+(d)->ht[1].used) //总的used size
#define dictIsRehashing(d) ((d)->rehashidx != -1) //是否正在rehash