一、Redis Hash
1、Redis的字典使用哈希表作為底層實現,一個哈希表里面可以有多個哈希表節點,而每個哈希表節點就保存了字典中的一個鍵值對。
2、Redis 字典所使用的哈希表由 dict.h/dictht
結構定義:
typedef struct dictht { // 哈希表數組 dictEntry **table; // 哈希表大小 unsigned long size; // 哈希表大小掩碼,用於計算索引值 // 總是等於 size - 1 unsigned long sizemask; // 該哈希表已有節點的數量 unsigned long used; } dictht;
1.table屬性是一個屬組,數組中的每個元素都是一個指向dict.h/dictEntry結構的指針,每個
dictEntry結構保存着一個鍵值對;
2.size屬性記錄了哈希表的大小,也即是table數組的大小,而used屬性則記錄了哈希表目前已有節點(鍵值對)的數量;
3.sizemask屬性的值總是等於size-1,這個屬性和哈希值一起決定一個鍵應該被放到table數組的哪個索引上面;
3、哈希表節點使用dictEntry
結構表示, 每個 dictEntry
結構都保存着一個鍵值對:
typedef struct dictEntry { // 鍵 void *key; // 值 union { void *val; uint64_t u64; int64_t s64; } v; // 指向下個哈希表節點,形成鏈表 struct dictEntry *next; } dictEntry;
1.key屬性保存着鍵值對中的鍵,而v屬性則保存着鍵值對中的值,其中v的值可以是一個指針,或者是一個uint64_t整數,或者是一個int64_t整數;
2.next屬性是指向另一個哈希表節點的指針,這個指針可以將多個哈希值相同的鍵值對連接在一起,以此來解決鍵沖突的問題;
舉例說明,如何通過next指針,將兩個索引值相同的鍵k1和k0連接在一起:
4、Redis 中的字典由 dict.h/dict
結構表示:
typedef struct dict { // 類型特定函數 dictType *type; // 私有數據 void *privdata; // 哈希表 dictht ht[2]; // rehash 索引 // 當 rehash 不在進行時,值為 -1 int rehashidx; /* rehashing not in progress if rehashidx == -1 */ } dict;
1.type
屬性和 privdata
屬性是針對不同類型的鍵值對, 為創建多態字典而設置的;
2.ht
屬性是一個包含兩個項的數組, 數組中的每個項都是一個 dictht
哈希表, 一般情況下, 字典只使用 ht[0]
哈希表, ht[1]
哈希表只會在對 ht[0]
哈希表進行 rehash 時使用;
3.除了 ht[1]
之外, 另一個和 rehash 有關的屬性就是 rehashidx
: 它記錄了 rehash 目前的進度, 如果目前沒有在進行 rehash , 那么它的值為 -1
。
4.舉例說明一個普通狀態下(沒有進行rehash)的字典: