Redis Dict
字典,哈希表,HashMap僅僅是說法不同而已。本質上就是一種key,value存儲,可以高效的存儲和訪問。
定義
typedef struct dictEntry {
void *key;
void *val;
struct dictEntry *next;
} dictEntry;
typedef 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;
/* This is our hash table structure. Every dictionary has two of this as we
* implement incremental rehashing, for the old to the new table. */
typedef struct dictht {
dictEntry **table;
unsigned long size;
unsigned long sizemask;
unsigned long used;
} dictht;
typedef struct dict {
dictType *type;
void *privdata;
dictht ht[2];
int rehashidx; /* rehashing not in progress if rehashidx == -1 */
int iterators; /* number of iterators currently running */
} dict;
總結
- 該哈希表使用拉鍊法,對於衝突的元素,用單鏈錶鏈接起來。
- 當哈希表衝突嚴重,需要rehash的時候,需要擴大哈希表容量,使用h[1]來分配較大的空間,再把h[0]中的entry重新rehash到h[1]中去。如果h[0]元素很多,重新rehash一遍所有元素是需要花很多時間的,因此採用的思路是內部維護一個rehashidx變量,在每次訪問哈希表的時候,僅對其中的一個索引鏈進行搬移操作。相當於把整個哈希表的rehash平均到每次的訪問中,把需要較多的時間分散開來。當rehash完成後,把h[0]釋放掉,h[1]賦值給h[0]即可。
- 在rehash的過程中,相當於h[0]和h[1]同時有數據,因此需要訪問h[0]和h[1]。
- dictType中維護一組函數指針,用於對節點中Key和Value的通用操作。