概述
上篇博客我簡單整理了 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的空哈希表結構圖:
哈希表節點
哈希表節點使用 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 中字典底層是通過哈希表實現的,關於哈希表更多細節,我打算放到下一篇博客詳細介紹,一來是想區分字典和哈希表的概念,二來是儘可能讓每篇博客都專注一些,儘可能不搞混