Redis字典总结

Redis字典采用哈希表作为底层实现。

typedef struct dictht{
   //哈希表数组    
    dictEntry **table;  
    //哈希表大小
    unsigned long size;
    //哈希表大小掩码,用于计算索引值
    //总是等于size-1
    unsigned long sizemask;
    //哈希表已有节点数量
    unsgined long used;
}dictht;

table指向dicEntry数组。

typedef struct dictEntry{
    //
    void *key;
    //
    union{
        void *val;
        uint64_tu 64;
        int64_ts 64;
    }v;
    
    //指向下一个哈希表节点,形成链表
    struct dictEntry *next;
} dictEntry;

其中next是用于在链地址法中使用,用于解决冲突。

typedef struct dict {
    //类的特定函数,其中第一个函数为哈希函数,将key转换成unsigned int
    dicType *type;
    //私有数据,作为特定函数的参数
    void *private;
    //哈希表
    dictht ht[2];
    //rehash索引
    //当rehash不在进行时,为-1
    int rehashidx;
}dict;

ht属性用于rehash。当哈希表的元素过多或者很少,会触发哈希表的扩容或者收缩,具体的时机与哈希表的负载有关(当前哈希表中的元素个数除以哈希表大小)。

当哈希表新插入元素而触发扩容时,首先会先为ht[1]申请两倍的ht[0]的空间,将新元素先插入ht[1],再从ht[0]中拿出rehashidx++对于的所有键值元素,重新计算键的哈希值后插入ht[1]。之后每次插入,查询,更新,删除都会导致ht[0]的一个rehashidx++对应的所有键值被转移到ht[1]。直到所有元素都转移到ht[1]中,再将ht[1]的内容拷贝到ht[0]并释放ht[1]。(这种方法称为渐进式rehash,java中的哈希表需要扩容时是直接将哈希表转换成红黑树)。

原文地址:https://www.cnblogs.com/fish-fly/p/12783456.html