Redisbook學習筆記(1)字典(1)

2021-09-03 09:30:27 字數 2707 閱讀 8278

字典(dictionary),又名對映(map)或關聯陣列(associative array), 它是一種抽象資料結

構,由一集鍵值對(key-value pairs)組成,各個鍵值對的鍵各不相同,程式可以將新的鍵值對

新增到字典中,或者基於鍵進行查詢、更新或刪除等操作。

字典的主要用途有以下兩個:

1. 實現資料庫鍵空間(key space)

2. 用作hash 型別鍵的其中一種底層實現

實現資料庫鍵空間

redis 是乙個鍵值對資料庫,資料庫中的鍵值對就由字典儲存:每個資料庫都有乙個與之相對

應的字典,這個字典被稱之為鍵空間(key space)。

當使用者新增乙個鍵值對到資料庫時(不論鍵值對是什麼型別),程式就將該鍵值對新增到鍵空

間;當使用者從資料庫中刪除乙個鍵值對時,程式就會將這個鍵值對從鍵空間中刪除;等等。

用作hash 型別鍵的其中一種底層實現

redis 的hash 型別鍵使用以下兩種資料結構作為底層實現:

1. 字典;

2. 壓縮列表;

因為壓縮列表比字典更節省記憶體,所以程式在建立新hash 鍵時,預設使用壓縮列表作為底層

實現,當有需要時,程式才會將底層實現從壓縮列表轉換到字典。

字典的實現

實現字典的方法有很多種:

最簡單的就是使用鍊錶或陣列,但是這種方式只適用於元素個數不多的情況下;

要兼顧高效和簡單性,可以使用雜湊表;

如果追求更為穩定的效能特徵,並且希望高效地實現排序操作的話,則可以使用更為復

雜的平衡樹;

在眾多可能的實現中,redis 選擇了高效且實現簡單的雜湊表作為字典的底層實現。

dict.h/dict 給出了這個字典的定義:

/*

* 字典

**每個字典使用兩個雜湊表,用於實現漸進式rehash ,即雜湊表擴容

*/typedef struct dict dict;

注意dict 型別使用了兩個指標分別指向兩個雜湊表。

其中,0 號雜湊表(ht[0])是字典主要使用的雜湊表,而1 號雜湊表(ht[1])則只有在程式

對0 號雜湊表進行rehash 時才使用。

雜湊表實現

字典所使用的雜湊表實現由dict.h/dictht 型別定義:

/*

* 雜湊表

*/typedef struct dictht dictht;

table 屬性是乙個陣列,陣列的每個元素都是乙個指向dictentry 結構的指標。

每個dictentry 都儲存著乙個鍵值對,以及乙個指向另乙個dictentry 結構的指標:

/*

* 雜湊表節點

*/typedef struct dictentry v;

// 鏈往後繼節點

struct dictentry *next;

} dictentry;

next 屬性指向另乙個dictentry 結構,多個dictentry 可以通過next 指標串連成煉表,從

這裡可以看出,dictht 使用鏈位址法來處理鍵碰撞:當多個不同的鍵擁有相同的雜湊值時,哈

希錶用乙個鍊錶將這些鍵連線起來。

下圖展示了乙個由dictht 和數個dictentry 組成的雜湊表例子:

如果再加上之前列出的dict 型別,那麼整個字典結構可以表示如下:

在上圖的字典示例中,字典雖然建立了兩個雜湊表,但正在使用的只有0 號雜湊表,這說明字

典未進行rehash 狀態。

建立新字典

新建立的兩個雜湊表都沒有為table 屬性分配任何空間:

ht[0]->table 的空間分配將在第一次往字典新增鍵值對時進行;

ht[1]->table 的空間分配將在rehash 開始時進行;

新增鍵值對到字典

根據字典所處的狀態,將乙個給定的鍵值對新增到字典可能會引起一系列複雜的操作:

如果字典為未初始化(也即是字典的0 號雜湊表的table 屬性為空),那麼程式需要對0

號雜湊表進行初始化;

如果在插入時發生了鍵碰撞,那麼程式需要處理碰撞;

如果插入新元素使得字典滿足了rehash 條件,那麼需要啟動相應的rehash 程式;

當程式處理完以上三種情況之後,新的鍵值對才會被真正地新增到字典上。

整個新增流程可以用下圖表示:

在接下來的三節中,我們將分別看到新增操作如何在以下三種情況中執行:

1. 字典為空;

2. 新增新鍵值對時發生碰撞處理;

3. 新增新鍵值對時觸發了rehash 操作;

~~每次遇到指標,就有點頭大,明天繼續吧!

Redisbook學習筆記(1)雙端鍊錶

雙端鍊錶作為一種通用的資料結構在redis 內部使用得非常多它既是redis 列表結構的底 層實現之一還被大量redis 模組所使用用於構建redis 的其他功能。對列表型別的鍵進行操作 比如執行 rpush lpop 或llen 等命令時程式在底層操作的可能就是雙端鍊錶。note redis 列表...

python學習筆記1 字串

小點總結 sentence input input the sentence words sentence.split 同樣適用於任何其它分隔符 9.letters list word 可以直接將word變成乙個list,其中每個元素都是乙個字母 判斷一句話中是否有正讀反讀都一樣的單詞 senten...

python學習筆記(五) 字典(1)

上集回顧 python學習筆記 四 if語句 python學習筆記 三 列表 2 python學習筆記 二 列表 1 python學習筆記 一 hello world 變數 字串 數字 禪 student print student age print student name 字典是一系列鍵 值對...