Redis数据结构--字典Dict
Redis的数据库就是使用字典来作为底层实现的,对数据库的增,删,改,查也是构建在对字典的操作之上的。
除了用用来表示数据库之外,字典还用作哈希键的底层实现之一,当一个哈希键包含的键值对比较多,又或者键值对中元素都是比较长的字符串时,Redis就会使用字典作为哈希键的底层实现。
Redis的字典使用哈希表作为底层实现,一个哈希表里面可以有多个哈希表节点,而每个哈希表节点就保存了字典中的一个键值对。
当向dict添加键值对时,Redis首先根据key计算hash值,然后利用hash&sizemask来计算元素应该存储到数组中的哪一个位置。
Dict由三部分组成:
哈希表
哈希节点
字典
下面分别是Dict的三种数据结构:
哈希表
typedef struct dictht{ //哈希表数组 dictEntry **table; //哈希表大小 unsighed long size; //哈希表大小掩码,用于计算索引值,总是等于size-1 sunsigned long sizemask; //该哈希表已有节点的数量 unsigned long used; }dictht;
哈希表节点
typedef struct dictEntry{ //键 void *key; //值 union{ void *val; uint64_t u64; int64_t s64; } v; //指向下一个哈希表节点,形成链表 struct dictEntry *next; }dictEntry;
字典:
typedef struct dict{ //类型特定函数 dictType *type; //私有数据 void *privdata; //哈希表 dictht ht[2]; //rehash索引 //当rehash不再进行时,该值为-1 int trehashidx; } dict;
ht属性是一个包含了两个项的数组,数组中的每个项都是一个哈希表,字典只使用ht[0]哈希表,ht[1]哈希表只会在对ht[0]哈希表进行rehash时使用。
哈希算法
当要将一个新的键值对添加到字典里面时,程序需要先根据键值对的键计算出哈希值和索引值,然后根据索引值,将包含新键值对的哈希表节点放到哈希表数组的指定索引上面。