Redis資料結構 字典

2022-08-01 08:00:13 字數 1910 閱讀 2636

字典在redis中應用廣泛,redis資料庫的底層就是使用字典來實現的,對資料庫的增刪查改也都是建立在字典的操作之上的。

此外,字典還是雜湊鍵的實現之一。

雜湊表由dict.h/dictht結構定義:

typedef struct dictht  dictht;
雜湊表節點使用dictentry結構表示,每個dictentry結構都儲存著乙個鍵值對:

typedef struct dictentry  v;

//指向下乙個雜湊表節點,形成鍊錶

struct dictentry *next;

} dictentry;

next屬性是指向另乙個雜湊表節點的指標,這個指標可以將多個雜湊值相同的鍵值對連線在一起,以此來解決鍵值衝突的問題(雜湊衝突)。

字典由dict.h/dict結構表示:

typedef struct dict  dict;
type屬性和privdata屬性是針對不同型別的鍵值對,為建立多型字典而設定的:

typedef struct dicttype  dicttype;
所以乙個字典裡是包含兩個雜湊表,ht。 一般情況下,字典只使用ht[0]雜湊表,ht[1]雜湊表只會在對ht[0]雜湊表進行rehash時使用。

當要將乙個新的鍵值對新增到字典裡面時,程式需要先根據鍵值對的鍵計算出雜湊值和索引值,然後再根據索引值,將包含新鍵值對的雜湊表節點先放到雜湊表陣列的指定索引上面。

從字典整個hash表設計上看,就知道它使用鏈位址法解決has衝突。在雜湊節點都有乙個next指標構成乙個單向鍊錶。

由於沒有指向鍊錶尾部的指標,因此為了速度考慮,程式總是將新節點新增到鍊錶的表頭位置。

為了讓hash表的負載因子維持在乙個比較合理的範圍,當hash表儲存的鍵值對數量太或者太少時,程需要對雜湊表的大小進行相應的擴充套件或者收縮。

擴充套件和收hash表的工作通過rehash實現,步驟如下:

為字典ht[1]雜湊表分配空間,這個雜湊表的空間大小取決於要執行的操作,以及ht[0]當前包含的鍵值對數量(也就是ht[0].used屬性的值):

如果執行的是擴充套件操作,那麼ht[1]的大小為第乙個大於等於ht[0].used*2的2^n;

執行的是收縮操作,那麼ht[1]的大小為第乙個大於等於ht[0].used的2^n。

將儲存在ht[0]中的所有鍵值對rehash到ht[1]上,rehash指的是重新計算hash值和索引值,然後將鍵值對放置到ht[1]雜湊表的指定位置上。

當ht[0]包含的所有鍵值對都遷移到ht[1]之後,釋放ht[0],將ht[1]設定為ht[0],並在ht[1]新建立乙個空白的雜湊表,為下一次rehash做準備。

為避免大資料量一次性rehash可能對伺服器效能造成的影響,伺服器不是一次性地將ht[0]裡面所有的鍵值對全部rehash到ht[1],而是分多次、漸進式地將ht[0]裡面的鍵值對慢慢地rehash到ht[1]:

為ht[1]分配空間;

在字典中維持乙個索引計數器rehashidx,並將它置為0,表示rehash工作正式開始。

在rehash進行期間,每次對字典執行新增、刪除、查詢或者更新操作時,程式出了執行執行指定的操作外,還會順帶將ht[0]雜湊表在rehashidx索引上的所有鍵值對rehash到ht[1],當rehash工作完成後,程式將rehashidx屬性的值增1.

隨著字典操作的不斷執行,最終在某個時間點上,ht[0]的所有鍵值對都會被rehash至ht[1],這是程式將rehashidx屬性的值設定為-1,表示rehash操作完成。

由於在rehash期間,字典同時在使用兩個雜湊表,所以字典的刪除、查詢、更新等操作會在兩個雜湊表上進行;而新增操作則會在ht[1]上進行,不對ht[0]進行操作,保證ht[0]只減不增。

redis資料結構 字典

1.1 雜湊表資料結構typedef struct dictht dictht 1.2 字典資料結構typedef struct dict dict 2.1 擴縮容條件 2.2 擴容流程 2.3 漸進式rehash 2.4 漸進式rehash場景3.1 迭代器資料結構 迭代器主要用於遍歷字典,遍歷資...

Redis資料結構 字典

1,字典,又稱為符號表 關聯陣列 或對映,是一種用於儲存鍵值對的抽象資料結構。2,redis的字典使用雜湊表作為底層實現,雜湊表的結構定義如下 typedef struct dicthtdicket table屬性是乙個陣列,陣列中的每個元素都是乙個指向dict.h dictentry結構的指標,每...

redis資料結構之字典

字典 dictionary 其實和符號表 symbol table 關聯陣列 associative array 對映 map 是乙個東東,都是為了儲存鍵值對 k v pair 的資料結構,屌屌噠。php中因為能很方便的用關聯陣列,因此能寫出很多實用高效的 有空一定要去好好了解下php的關聯陣列是如...