key value 数据结构
哈希键类型 在1 元素超过一定数目 或 2key或value中存储的串过长时 将会由压缩列表转为字典进行存储
Redis 字典通过哈希表实现
哈希表:
typedef struct dictht {
dictEntry **table;
unsigned long size;
unsigned long sizemark; //等于size-1,用于计算索引值 避免-1操作
unsigned long used; //已有节点数目
} dictht;
哈希表节点:
typedef struct dictEntry{
void *key;
union{
void *val;
uint64_t u64;
int64_t s64;
} v;
struct dictEntry *next; //拉链解决hash冲突
} dictEntry;
值 v 可以为 1 指针 2 uint64_t 的整数 3 int64_t的整数
字典:
typedef struct dict {
dictType *type; // 函数指针
void *privdata; // 传给上述函数的可选参数
dictht ht[2]; // 哈希表 2个的原因是进行rehash 不能一次完成,又不能阻塞需要满足可读写,用空间换时间 保证rehash时依然可读
int trehashidx; // rehash索引 当没有rehash时值为-1
}
type是指向 dictType的指针 dictType结构体中定义了计算哈希值函数、复制键函数、复制值函数、对比键函数、销毁键函数、销毁值的函数
为不同类型的字典 设置不同 的特定类型函数
hash算法:
1 调用dictType中的哈希值函数计算出当前键的哈希值
2 hash&sizemask
出现hash冲突的时候使用拉链法 解决hash冲突
rehash
哈希表在扩展或收缩的时候会进行rehash:
扩展的条件:
1 哈希表负载因子大于等于1且未执行BGSAVE且未执行BGREWRITEAOF命令
2 负载因子大于等于5
负载因子=已保存节点数目/哈希表大小
收缩的条件:
负载因子小于等于0.1
渐进式rehash读写逻辑:
查找、更新、删除:先在ht[0]上查找,没有再查找ht[1]
增加:在ht[1]进行