redis 系列——3、redis 哈希表原理

概述

上篇博客我簡單整理了 redis 中鏈表的實現原理。本篇博客我打算就哈希類型簡單整理一下。


redis 數據類型

redis 有以下五種常用的數據類型:

  • String:字符串類型
  • Hash:哈希類型
  • list:鏈表類型
  • set:集合類型
  • zSet:有序集合類型

1、哈希表

redis 中哈希表使用頭文件 dict.h 中的 dictht 結構體定義:

typedef struct dictht {
    // 哈希表數組
    dictEntry **table;
    // 哈希表大小
    unsigned long size;
    //哈希表大小掩碼,用於計算索引值
    //總是等於size-1
    unsigned long sizemask;
    // 該哈希表已有節點的數量
    unsigned long used;
} dictht;
  • table 屬性是一個數組,數組元素都是指向 dictEnty 結構的指針,每個 dictEntry 都包含一個鍵值對
  • size 屬性記錄哈希表的大小,即 table 數組的大小
  • sizemask 的值總等於 size-1,這個屬性和 hash 值一起決定鍵被放到數組的哪個索引上
  • used 屬性記錄已有節點的數量

鍵值對:一個鍵可以和一個值進行關聯,這些關聯的鍵和值就稱爲鍵值對。

下面我們看一張大小爲4的空哈希表結構圖:
空hash表結構


哈希表節點

哈希表節點使用 dictEntry 表示,它的結構如下所示:

typedef struct dictEntry {
    // 鍵
    void *key;
    // 值
    union{
        void *val;
        uint64_tu64;
        int64_ts64;
    } v;
    // 指向下個哈希表節點,形成鏈表
    struct dictEntry *next;
} dictEntry;
  • key 屬性表示鍵值對中的鍵
  • v 屬性保存鍵值對中的值,值可以是一個指針,也可以是 uint64_t 類型整數,還可以是 int64_t 類型整數
  • next 屬性是指向另一個節點的指針,通過它可以將 hash 值相同的鍵值對連接在一起,避免衝突

下面我給出大小爲4,包含兩個相同 hash 值節點的哈希表示意圖:
哈希表示意圖
從這裏也就可以看出,redis 哈希表的實現也是通過數組+鏈表,和之前我們介紹的 hashmap 相同。


字典與哈希表

字典:字典是一個抽象概念,它是描述鍵映射到值的一般概念。

也就是說字典表有很多種實現方式,哈希表是字典的一種實現方式。redis 中字典底層是通過哈希表實現的,關於哈希表更多細節,我打算放到下一篇博客詳細介紹,一來是想區分字典和哈希表的概念,二來是儘可能讓每篇博客都專注一些,儘可能不搞混


參考:
《redis設計與實現》黃健宏著
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章