字典中,一个键key和一个值value关联起来,这称为键值对。
字典中的每个键都是独一无二的, 程序可以在字典中根据键查找与之关联的值, 或者通过键来更新值, 又或者根据键来删除整个键值对, 等等。
Redis 的字典使用哈希表作为底层实现, 一个哈希表里面可以有多个哈希表节点, 而每个哈希表节点就保存了字典中的一个键值对。
typedef struct dictht { dictEntry **table; // 哈希表数组 unsigned long size; // 哈希表大小 unsigned long sizemask; // 哈希表大小掩码 unsigned long used; // 该哈希表已有节点的数量 } dictht;
table是一个数组,其中每个元素都是一个指向dictEntry结构的指针。
typedef struct dictEntry { void *key; // 键 union { void *val; uint64_t u64; int64_t s64; double d; } v; // 值 struct dictEntry *next; // 指向下一个哈希表节点,形成链表,因此是通过链地址法来 } dictEntry;
我们发现在dictEntry定义中有next指针指向下一个哈希表节点,举个例子:
typedef struct dict { dictType *type; // 类型特定函数 void *privdata; // 私有数据 dictht ht[2]; // 哈希表,一般情况下,字典只使用ht[0]哈希表,ht[1]哈希表只会在对ht[0]哈希表进行rehash时进行 // rehash索引 long rehashidx; /* rehashing not in progress if rehashidx == -1 */ int16_t pauserehash; /* If >0 rehashing is paused (<0 indicates coding error) */ } dict;
普通状态下的字典如下图所示: