接下来继续研究哈希对象,有两种内部编码:
ziplist:
hashtable
复制代码
那么问题又来了,分别在什么条件下对应哪种编码呢?
哈希类型元素个数小于hash-max-ziplist-entries配置(512),同时所有值都小于hash-max-ziplist-value配置(64字节),
会使用ziplist这种编码,反之为hashtable。
复制代码
是不是很熟悉?列表的首选结构也是ziplist,为什么呢?
节约内存!!!
复制代码
之前对ziplist已经解读过了,那么我们看看字典的实现,源码在dict.h中
typedef struct dictht {
dictEntry **table; //哈希表数组
unsigned long size; //哈希表的大小
unsigned long sizemask; //哈希表大小掩码,用于计算索引值,=size-1
unsigned long used; //已有节点的数量
} dictht;
typedef struct dictEntry {
void *key; //键
//值
union {
void *val;
uint64_t u64;
int64_t s64;
double d;
} v;
struct dictEntry *next; //指向下个哈希表节点,形成链表
} dictEntry;
typedef struct dict {
dictType *type; //类型特定函数
void *privdata; //私有数据,与type配合使用
dictht ht[2]; //哈希表
long rehashidx; //rehash索引
int iterators;
} dict;
注:type和privdata为创建多态字典设置的;ht[1]和rehashidx在对哈希表rehash时使用。
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;
下面我们以一幅图看看普通状态下的字典:
复制代码
哈希算法
1、计算hash值:hash = dict->type->hashFunction(k0);
2、计算索引值:index = hash&dict->ht[0].sizemask复制代码