《Redis設計與實現》讀書筆記(二)
3.字典
- C語言中沒有內置字典,Redis數據庫拿字典做爲底層實現,須要構建字典結構及其增刪查改API。在Redis中,字典的底層是哈希表,dictionary hash table。dictht定義以下。

- 這裏的table是一個數組,數組中每一個元素都是指向dictEntry的指針。dictEntry保存着鍵值對,其定義以下。

- 上邊字段中,含義或者做用比較模糊的就是*next指針了。這個字段的做用是解決鍵衝突的。示例以下。

- 好,鋪墊完了,開始進入字典結構。

- 這裏的每一個字段都有重要的做用。type和privdata指針支持了字典的多態。實現多態的原理:type爲dictType結構的指針,而dictType則是保存了用於處理特定鍵值對的類型特定函數,privdata保存了須要傳給類型特定函數的可選參數。

- ht字段保存了兩個哈希表,第一個表是正常使用,第二個則是rehash的時候使用。rehashidx字段也是rehash進度相關,沒有進行rehash的時候,值爲-1。完整的字典,普通狀態下的示意圖以下。

-
添加鍵值對到字典的步驟:算法
- 根據鍵值對計算哈希值和索引值
- 根據索引值找到哈希表數組(dictEntry[])的指定索引
- 將鍵值對信息存放在dictEntry裏邊
- 上邊的三個步驟邏輯上存在一個問題——索引衝突!
- 根據哈希算法的不一樣,哈希碰撞的機率不一樣。鍵值對A和鍵值對B被分配到相同的索引,怎麼辦!
- 鏈地址法,這也就是dictEntry裏邊有個next指針的緣由了。後添加的會被添加到表頭。示意圖以下。

- 至此,字典的功能實現基本完成,可是,工程實現尚未!什麼意思?工程的意思是對字典的操做是持續不斷的,大量的。這個時候就須要rehash,優化哈希表。好比,dictEntry數組的有些索引沒有值,有些存在比較長的鏈。
- 因此,從工程的角度考慮,rehash這個步驟必不可少。dict結構中有幾個字段是用於rehash的。rehash的細節能夠看原書或者別的資料。
歡迎關注本站公眾號,獲取更多信息