0
点赞
收藏
分享

微信扫一扫

Redis字典数据结构


关键代码位置:src/dict.h



字典是一种键值对映射,但C语言无这种数据结构,Redis自己实现了一套。另外字典是hash的底层实现之一。



 



Redis字典数据结构_Redis

 



数据结构概述说明:



- ht数组有两个元素,没有rehash情况下,默认用ht[0],而ht[1]只会在rehash即rehashidx=0时才会用到



- 每个ht都会有used标识多少个实际已有节点数量



- 采用拉链法解决hash冲突



其核心结构源码如下: 


typedef struct dict {
 
 
    // 类型处理函数
 
 
    dictType *type;
 
 
    // 类型处理函数私有值
 
 
    void *privdata;
 
 
    // 两个hash表
 
 
    dictht ht[2];
 
 
    // rehash标示,为-1表示不在rehash,不为0表示正在rehash的桶
 
 
    long rehashidx; /* rehashing not in progress if rehashidx == -1 */
 
 
    // 当前正在运行的安全迭代器数量
 
 
    int16_t pauserehash; /* If >0 rehashing is paused (<0 indicates coding error) */
 
 
} dict;
 
 
typedef struct dictht {
 
 
    dictEntry **table;// 哈希表数据,table是一个数组
 
 
    unsigned long size;// 哈希表大小
 
 
    unsigned long sizemask;// 哈希表大小掩码,用于计算哈希值
 
 
    unsigned long used;// 该hash表已有节点数量
 
 
} dictht;
 
 
typedef struct dictEntry {
 
 
    void *key;// 键
 
 
    union {// 值
 
 
        void *val;
 
 
        uint64_t u64;
 
 
        int64_t s64;
 
 
        double d;
 
 
    } v;
 
 
    struct dictEntry *next;// 指向下一个hash节点,形成链表
 
 
} dictEntry;



下面我们大概说说核心方法的执行方式



0 hash值计算的方式

h = dictHashKey(d, key);// 计算键的哈希值
  
 
  

   idx = h & d->ht[table].sizemask;// table等于0或1
  
 
  

   he = d->ht[table].table[idx];

1 缩小字典容量(函数:dictResize)



让它的已用节点数和字典大小之间的比率接近 1:1,默认有个最小的值。



2 扩展或创建一个字典(函数:_dictExpand)



1 ht[0]为空,初始化ht[0]。否则初始化ht[1],并设置rehashidx=0标识正在rehash中



3 rehash过程是渐进式(函数:dictRehash)



分为N步迁移,每步以一个桶(一个数组下标)作为单位,然后将这个桶上所有的ht[0]迁移到ht[1]上,并把ht[0].used--、ht[1].used++



4 字典添加键(函数:dictAddRaw)



执行前会看下是否rehashing,如果是dictRehash渐进式rehash。然后再判断是否rehashing中,如果是就添加到ht[1],反之添加到ht[0]



5 字典替换键对应的值(函数:dictReplace)



先调用dictAddRaw添加,如果不存在则添加成功返回1。否则设置新值,释放旧值。



6 字典删除对应的键(函数:dictGenericDelete)



如果是rehashing中,就渐进式rehash。先找ht[0]的节点(找不到就拉链法跳到下一个链表节点找),最后还找不到并且非rehashing中,就终止,否则跑去ht[1]继续找。



7 清除字典上的所有数据(函数:dictRelease)



先清除dict#ht数组的数据,然后再清除dict本身



8 返回字典中对应键的节点(函数:dictFind)



如果是rehashing中,就渐进式rehash。现在ht[0]找,找不到并且是rehashing中就去ht[1]找



其他自己看gitee~~~~~~~~~~~



 



 

举报

相关推荐

0 条评论