1. 程式人生 > >redis原始碼閱讀筆記-dict.h

redis原始碼閱讀筆記-dict.h

dict.h

在redis中,dict.h主要是hash的底層實現方式。
在dict.h中主要是一些資料結構的定義,以及一些巨集函式的定義相關的內容。

雜湊節點定義

原始碼中的dictEntry就是雜湊節點的相關定義

typedef struct dictEntry {
    void *key;		//存放key值
    union {			//使用一個union存放value值
        void *val;
        uint64_t u64;
        int64_t s64;
        double d;
    } v;
    struct dictEntry *
next; //hash衝突使用開鏈法,因此使用了一個next指標指向下一個節點 } dictEntry;

dictType

在dictType中,存放了一些操作函式

typedef struct dictType {
    uint64_t (*hashFunction)(const void *key);		//雜湊函式
    void *(*keyDup)(void *privdata, const void *key);	//key複製
    void *(*valDup)(void *privdata, const void *obj);	//value複製
    int (*keyCompare)
(void *privdata, const void *key1, const void *key2); //key比較函式 void (*keyDestructor)(void *privdata, void *key); //key析構 void (*valDestructor)(void *privdata, void *obj); //value析構 } dictType;

dictht

dictht就是雜湊表的結構

`typedef struct dictht {
    dictEntry **table;		//雜湊節點指標陣列
    unsigned long size;
//雜湊長度 unsigned long sizemask; //雜湊掩碼(用於計算雜湊索引) unsigned long used; //已經使用的節點數目 } dictht; `` #### dict //字典的資料結構的定義 ```c typedef struct dict { dictType *type; //儲存一些函式 void *privdata; //私有資料 dictht ht[2]; //雜湊表,注意,這裡的雜湊表有兩張,主要是為了rehash操作預備 long rehashidx; //雜湊索引 unsigned long iterators; //記錄正在使用的迭代器數量 } dict;``` #### dictIterator dictIterator充當字典迭代器的作用。 這裡的迭代器分為了兩種,一種迭代器是safe的,它可以進行讀寫操作 另外一種迭代器是unsafe的,是一種只讀迭代器 ```c `typedef struct dictIterator { dict *d; //字典 long index; //字典索引 int table, safe; //safe標誌是否為safe迭代器,table標誌當前雜湊表號碼(0或者1 dictEntry *entry, *nextEntry; //當前節點與下一個節點 long long fingerprint; //dict指紋,避免迭代器失效的作用 } dictIterator;

另外一些巨集函式

//釋放節點
#define dictFreeVal(d, entry) \
    if ((d)->type->valDestructor) \		//如果hashType中定義了valDestructor函式的話,呼叫其釋放節點
        (d)->type->valDestructor((d)->privdata, (entry)->v.val)

//設定節點的value
#define dictSetVal(d, entry, _val_) do { \
    if ((d)->type->valDup) \		//如果存在value複製函式,就呼叫value複製函式,否則直接賦值
        (entry)->v.val = (d)->type->valDup((d)->privdata, _val_); \
    else \
        (entry)->v.val = (_val_); \
} while(0)

//設定int的value值
#define dictSetSignedIntegerVal(entry, _val_) \
    do { (entry)->v.s64 = _val_; } while(0)
//設定unsigned的value值
#define dictSetUnsignedIntegerVal(entry, _val_) \
    do { (entry)->v.u64 = _val_; } while(0)
//設定double的value值
#define dictSetDoubleVal(entry, _val_) \
    do { (entry)->v.d = _val_; } while(0)
//釋放key值,呼叫dictType中的函式釋放
#define dictFreeKey(d, entry) \
    if ((d)->type->keyDestructor) \
        (d)->type->keyDestructor((d)->privdata, (entry)->key)
//設定key
//如果存在keyDup函式,那麼呼叫keyDup函式,否則直接賦值
#define dictSetKey(d, entry, _key_) do { \
    if ((d)->type->keyDup) \
        (entry)->key = (d)->type->keyDup((d)->privdata, _key_); \
    else \
        (entry)->key = (_key_); \
} while(0)
//比較key,同樣的,呼叫dictType中的keyCompare函式
#define dictCompareKeys(d, key1, key2) \
    (((d)->type->keyCompare) ? \
        (d)->type->keyCompare((d)->privdata, key1, key2) : \
        (key1) == (key2))
//獲取hash
#define dictHashKey(d, key) (d)->type->hashFunction(key)
#define dictGetKey(he) ((he)->key)		//得到節點的key
#define dictGetVal(he) ((he)->v.val)	//得到節點的value值
#define dictGetSignedIntegerVal(he) ((he)->v.s64)		//得到節點的int值
#define dictGetUnsignedIntegerVal(he) ((he)->v.u64)		//得到節點的unsigned int值
#define dictGetDoubleVal(he) ((he)->v.d)				//得到節點的value值
#define dictSlots(d) ((d)->ht[0].size+(d)->ht[1].size)	//總size
#define dictSize(d) ((d)->ht[0].used+(d)->ht[1].used)	//總的used size
#define dictIsRehashing(d) ((d)->rehashidx != -1)		//是否正在rehash