字典在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的關聯陣列是如...