字典又称符号表、关联数组或映射,是一种用于保存键值对的抽象数据结构;
redis的数据库就是使用字典来作为底层实现的,对数据库的增、删、改、查都是构建在对字典的操作之上的;

字典的实现

1、哈希表
redis字典所使用的哈希表有dict/dictht结构定义;

typedef struct dictht
{
    dictEntry **table;//哈希表数组
    unsigned long size;//哈希表大小
    unsigned long sizemask;//哈希表大小掩码
    unsigned long used;//哈希表已有节点数量
}dictht;
哈希表节点:
typedef strcut dictEntry
{
    void *key;//键
    union{
        void *val;
        uint64_t u64;
        int64_t s64;
    }v;//值
    strcut dictEntry *next;
}dictEntry;
字典:
typedef struct dict
{
    dictType *type;//类型特定函数
    void *privdata;//私有数据
    dictht ht[2];//哈希表
    int trehashidx;//记录rehash进度,如果目前没有在进行rehash,那么它的值为-1;
}dict;

django redis 列表加字典 redis字典结构_redis

2、哈希算法
使用字典设置的哈希函数,计算key的哈希值;
hash = dict->type->hashFunction(key);
使用哈希表中的sizemask属性和哈希值,计算出索引值;
index= hash & dict->ht[x].sizemask;
3、解决键冲突
Redis的哈希表采用链地址法来解决键冲突;每个哈希表节点都有一个next指针,多个哈希表节点可以用next指针构成一个单向链表,当插入新的哈希节点时,总是使用头插法
4、rehash
随着操作的不断执行,哈希表保存的键值对会逐渐地增多或者减少,为了让哈希表的负载因子维持在一个合理的范围之内,当哈希表保存的键值对数量太多或者太少,程序需要对哈希表的大小进行相应的扩展或者收缩;
扩展和收缩的工作可以通过执行rehash操作来完成;
<1>位字典ht[1]分配空间,大小取决于要执行的工作;
<2>将保存在ht[0]中的所有键值对rehash到ht[1]中,rehash指的是重新计算键的哈希值和索引值;
<3>当ht[0]中的所有节点都迁移到了ht[1]中,就将ht[1]变为ht[0],将ht[1]新创建一个空白的哈希表;
5、渐进式rehash
扩展和收缩是将ht[0]中的所有键值对rehash到ht[1]中,但是这个动作,对于4个来说很快,如果键值对的个数达到4亿多个,庞大的计算量可能会导致服务器在一段时间没停止服务;为了避免rehash对服务器性能造成的影响,服务器不是一次性将ht[0]里面的所有键值对全部rehash到ht[1]中,而是分多次,渐进式地将ht[0]里面的键值对慢慢地rehash到ht[1]中;渐进式的好处在于它采用了分而治之的方式;
另外,在渐进式rehash执行期间,新添加到字典的键值对一律会被保存到ht[1]里面,而ht[0]则不再进行任何添加操作,这一措施保证了ht[0]包含的键值对数量只减不增;