Redis研究ノート(3)辞書

Redisの辞書は、基礎となる実装としてハッシュテーブルを使用します。ハッシュテーブルは複数のハッシュテーブルノードを持つことができ、各ハッシュノードは辞書のキーと値のペアに格納されます。

redisディクショナリで使用されるハッシュテーブルは、disht構造によって定義されます。

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

table属性は配列です。配列内の各要素は、dictEntry構造へのポインターです。各dictEntry構造は、キーと値のペアを保持します。他の属性について言うことはあまりありません。

ハッシュテーブルノード

ハッシュテーブルノードはdictEntry構造によって識別され、各dictEntryはキーと値のペアを格納します。

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

* next属性は、別のハッシュテーブルノードへのポインタです。このポインタは、同じハッシュ値を持つ複数のキーと値のペアを接続して、キーの競合の問題を解決できます。したがって、各ハッシュインデックスは単一にリンクされたリストです。

Redisの辞書は、dict構造で表されます。

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

Redisはハッシュ値とインデックス値を計算します。

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

キーの競合を解決します。

同じ量の2つまたは2つのキーがハッシュテーブル配列の同じインデックスに割り当てられている場合、これらのキーは競合していると呼ばれます。Redisのハッシュテーブルは、チェーンアドレス方式を使用して競合を解決します。各ハッシュテーブルノードの次のポインタは、キーの競合を解決するために単一リンクリストを形成します。

また、リンクリストにはリンクリストの末尾へのポインタがないため、速度を考慮するために、新しく追加されたノードは毎回リンクリストの先頭に配置されます(複雑さはO(1)です)。

再ハッシュ

ハッシュテーブルに格納されているキーが増減すると、ハッシュテーブルの負荷率を適切な範囲内に保つために、プログラムはハッシュテーブルのサイズを再ハッシュ(再ハッシュ)します。

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]。

プログレッシブリハッシュ

ディクショナリテーブルは、ht [0]、ht [1]、およびht [0]を同時に使用して、ht [0]が保持するキーと値のペアが多すぎるという問題を解決するために、インデックスカウンタを介してバッチでht [1]に移行します。


毎日少しずつ学びましょう。常に利益があります。

注:著者の知的財産権を尊重し、記事の内容については「Redisの設計と実装」を参照し、ここでのみ学習して共有してください。


ここに写真の説明を挿入

おすすめ

転載: blog.csdn.net/xuetian0546/article/details/106882585