Redis study notes (3) dictionary

Redis's dictionary uses a hash table as the underlying implementation. A hash table can have multiple hash table nodes, and each hash node is stored in a key-value pair in the dictionary.

The hash table used by the redis dictionary is defined by the disht structure.

typedef struct dictht{
    
    
    dictEntry **table;//哈希表数组
    unsigned long size;//哈希表大小
    unsigned long sizemask;//哈希表大小掩码,用于计算索引值 ,总是等于size -1
    unsigned long used;//该哈希表已有节点数量
}

The table attribute is an array. Each element in the array is a pointer to a dictEntry structure. Each dictEntry structure holds a key-value pair. Not much to say about other attributes.

Hash table node

Hash table nodes are identified by the dictEntry structure, and each dictEntry stores a key-value pair.

typedef struct dictEntry{
    
    
    void *key;//键
    union{
    
    
    void *val;
    uint64_tu64'
    int64_ts64'
    } v;//值
    struct dictEntry *next;//指向下个哈希节点,形成链表
} ductEntry;

The *next attribute is a pointer to another hash table node. This pointer can connect multiple key-value pairs with the same hash value to solve the problem of key conflicts. Therefore, each hash index is a singly linked list.

The dictionary in Redis is represented by the dict structure:

typedef struct dict{
    
    
    dictType *type;//类型特定函数
    void *orivdata;//私有数据
    dictht ht[2];//哈希表
    int trehashidx;//rehash 索引 ,当rehash不再进行时,值为-1
} dict;

Redis calculates hash value and index value:

hash = dict->type->hashFunction(key);
index = hash & dict->ht[x].sizemask;

Resolve key conflicts:

When two or two keys of the same number are assigned to the same index in the hash table array, it is called these keys conflict for us. Redis's hash table uses the chain address method to resolve conflicts. The next pointer of each hash table node forms a singly linked list to resolve key conflicts.

In addition, because the linked list does not have a pointer to the end of the linked list, in order to consider the speed, the newly added node is placed at the head of the linked list every time (complexity is O(1)).

Rehash

As the keys stored in the hash table increase or decrease, in order to keep the load factor of the hash table within a reasonable range, the program will rehash (re-hash) the size of the hash table.

1、为字典表的ht[1]哈希表分配空间,这个哈希表的空间大小取决于要执行的操作以及ht[0]包含的键值对数量

    (1)如果执行扩展,ht[1] =第一个>=ht[0].used * 2 的2的n次方幂。

    (2)如果收缩 ht[1] = 第一个>=ht[0].used 的2的n次方幂

2、h[0] 迁移至h[1]。

3、清空h[0],将h[1]设置为h[0],新建h[1]。

Progressive rehash

The dictionary table simultaneously uses ht[0], ht[1], and ht[0] to migrate to ht[1] in batches through the index counter, in order to solve the problem of too much key-value pairs held by ht[0].


Learn a little every day, there will always be gains.

Note: Respect the author's intellectual property rights, refer to "Redis Design and Implementation" for the content in the article, and only learn here to share with you.


Insert picture description here

Guess you like

Origin blog.csdn.net/xuetian0546/article/details/106882585