Redis 字典的實現(1)

字典就是我們熟悉的map,鍵值對(key-value pair)的抽象數據結構。Redis數據庫就是使用字典來作爲底層實現的。

先介紹下數據結構:

1.哈希表

typeof struct dictht {

//哈希表數組

dictEntry  **table;

//哈希表大小

unsigned long size;

//哈希表大小掩碼,用於計算索引

//總是等於size-1

unsigned long sizemask;

//已有節點數量

unsigned long used;

} dictht;


這種數據結構很好理解,和Java裏面HashMap實現差不多。哈希表裏面每個節點都是一個entry對象。


2.哈希表節點

typeof struct dictEntry {

//鍵

void *key;

//值

union {

void *val;

unit64_t u64;

int64_t s64;

} v;


//指向下個哈希表節點,形成鏈表

struct dictEntry *next;

} dictEntry;


key屬性存着鍵值對中的鍵,v屬性存值。鍵可以是一個指針,也可以是一個unit64_t整數,或是一個int^4_t整數。C語言沒了解過,這種奇怪的整數也不知道什麼意思,姑且理解爲Java裏面的hashCode吧。

next屬性指向鏈表中的下一個節點,這點和Java一樣,當多個對象哈希值相同時,就造成hash衝突,多個對象的索引值都落在同一索引下標上,該節點的數據結構爲鏈表,需要遍歷該鏈表才能找到對應元素。


3.字典數據結構

typeof struct dict {

//類型特定函數

dictType *type;

//私有數據

void *privdata;

//哈希表

dictht ht[2];

//rehash索引

//當rehash不再進行時,值爲-1

int rehashidx;

} dict;

type屬性和privdata屬性針對不同類型的鍵值對,爲創建多態字典設置的。

type屬性是一個指向dictType結構的指針,每個dictType保存了一簇用於操作特定類型鍵值對的函數,Redis會爲用途不同的字典設置不同的類型特定函數。

privdata屬性保存了需要傳給那些類型特定函數的可選參數。


typeof struct dictType {

//計算哈希值的函數

unsigned int (*hashFunction) (const void *key);

//複製鍵的函數

void *(*keyDup) (void *privdata, const void *key);

//複製值的函數

void *(*valDup)(void *privdata, const void *obj);

//對比鍵的函數

int (*keyCompare) (void *privdata, const void *key1, const void *key2);

//銷燬的函數

void (*keyDestructor) (void *privdata, void *key);

//銷燬值的函數

void (*valDestructor) (void *privdata, void *obj);

} dictType;


ht屬性是一個包含2個索引的數組,每個位置都是一個dictht哈希表,一般使用ht[0],ht[1]用於存放對ht[0]哈希表進行rehash的結果。

rehashidx記錄目前rehash進度,當前沒有執行rehash,值爲-1。



發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章