ThinkChat2.0新版上线,更智能更精彩,支持会话、画图、阅读、搜索等,送10W Token,即刻开启你的AI之旅 广告
### 触发rehash的条件 #### 负载因子计算 哈希表的负载因子计算:负载因子 = 哈希表已保存节点数量 / 哈希表大小 ``` load_factor = ht[0].used / ht[0].size ``` #### rehash的条件 触发dict的rehash主要有两种:一种是触发扩容操作,另一种是触发收缩操作。两种rehash触发的条件是不一样的,需要各自满足一下条件才能导致rehash操作 1)触发扩容操作条件:当以下条件中的任意一个被满足时, 程序会自动开始对哈希表执行扩展操作。 1. 服务器目前没有在执行 BGSAVE 命令或者 BGREWRITEAOF 命令,并且哈希表的负载因子大于等于 1 2. 服务器目前正在执行 BGSAVE 命令或者 BGREWRITEAOF 命令,并且哈希表的负载因子大于等于 5; 根据 BGSAVE 命令或 BGREWRITEAOF 命令是否正在执行,服务器执行扩展操作所需的负载因子并不相同,这是因为在执行 BGSAVE 命令或 BGREWRITEAOF命令的过程中, Redis会fork一个子进程,而大多数操作系统都采用写时复制(copy-on-write)技术来优化子进程的使用效率,所以在子进程存在期间,服务器会提高执行扩展操作所需的负载因子,从而尽可能地避免在子进程存在期间进行哈希表扩展操作,这可以避免不必要的内存写入操作, 最大限度地节约内存 2)触发收缩操作条件:当哈希表的负载因子小于0.1时,程序自动开始对哈希表执行收缩操作。 ``` (ht[0].used / ht[0].siz) < 0.1,也就是填充率必须<10% ``` 3) dict添加、查询和删除操作 1. dict添加操作:如果正在重哈希中,会把数据插入到ht[1];否则插入到ht[0]; 2. dict查询操作:先在第一个哈希表ht[0]上进行查找,再判断当前是否在重哈希,如果没有,那么在ht[0]上的查找结果就是最终结果。否则,在ht[1]上进行查找。查询时会先根据key计算出桶的位置,在到桶里的链表上寻找key; 3. dict删除操作:判断当前是不是在重哈希过程中,如果是只在ht[0]中查找要删除的key;否则ht[0]和ht[1]它都要查找删除;