哈希表和字典
结构:要点rehash时机redis内的使用
哈希表和字典
我就不明白了,c里面没有,c++的stl里有啊,redis为什么要自己实现
结构:
typedef struct dictEntry{
void *key;
union{
void *val;
uint64_tu64;
int64_ts64;
}
struct dictEntry *next;
}
typedef struct dictht{
dictEntry **table;
unsigned long size;
unsigned long sizemark;
unsigned long used;
}
typedef struct dict{
dictType *type;
void *privatedata;
dictht ht[
2];
int rehashIndex;
}
要点
哈希表使用链表法解决hash冲突的问题,而且链表使用头插法,将最近的冲突节点放到链表头部,复杂度为o(1),这里的链表是单链表 2 rehash,当达到负载因子的阈值的时候,启动rehash,redis的rehash不是一口气完成的,而是将其拆解到每一次对字典的操作(增删改查)当中,每一次rehash原哈希表的一个数组的链表到另一个哈希表中,这个时候rehashIndex的作用就是表明下一个将要进行rehash操作的数组下标。进行完rehash后,会将新的哈希表设为ht[0]使用
rehash时机
负载因子计算:和java 的hashmap一样,使用节点数/数组大小表示,需要注意的是,节点数不是已使用的桶(bucket)数量,也就是说,如果所有节点hash都一样,进而解决hash冲突放到同一个dictEntry的链表里,它们每一个都会被用于负载因子的计算。什么时候扩大:负载因子大于等于1,并且服务器没有执行BGSAVE,BGREWRITEAOF指令;或者服务器在执行BGSAVE或BGREWRITEAOF指令,并且负载因子大于等于5如何扩大:当前已有节点数*2的最近的2的幂次为什么要区别BGSAVE和BGREWRITEAOF指令?这两个指令会导致redis服务器启动子进程,而在子进程内,数据是和父进程共享的,只有需要改变时使用写时复制的方式将修改的数据新建一份,所以为了防止子进程新建数据,提高性能,会区别这两个指令。什么时候缩小:当负载因子小于0.1的时候如何缩小:当前已有节点数,的最近的2的幂次
redis内的使用
redis数据库本身,以及哈希键值等