Redis中数据结构(3)字典

名词介绍:

字典:顾名思义,能根据响应的索引找到值的一种数据结构。字典又称为符号表(symbol table),关联数组(associative array),或者映射(map),是一种用于保存键值对(key-value)的抽象数据结构,一个字典中的键(key)是唯一的,能根据唯一的键找出相对应的值。在redis这种典型的key-value的内存型存储系统,自然也是使用了字典作为其底层数据结构。

Redis中字典的实现

Hash表

redis中的Hash表和Java语言中的Map数据结构类似,实际都是采用数组+链表的,链地址法来进行hash的;
redis中定义的Hash表由dict.h/dictht结构定义:

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

哈希表节点

哈希表节点使用dictEntry结构表示,每个dictEntry结构都保存着一个键值对:

typedef struct dictEntry{
    //key
    void *key;

    //value
    union{
    void *value;
    uint64_t u64;
    int64_t s64;
    }v;

    //指向下一个hash表的几点,形成链表
    struct dictEntry *next;
}

redis中使用解决hash冲突的方式是:链地址法
所谓链地址法,如果两个数据的hash值相同,则将后插入的数据以链表的形式插入到前一个后面,以此形成一个链表,所以叫链地址法。

字典

在redis中字典是由dict.h/dict数据结构表示

typedef struct dict{
    //类型特定函数
    dictType *type;

    //私有数据
    void *privatedata;

    //hash表
    dictht ht[2];

    //rehash索引,当rehash不存在时候,值为-1
    int trehsshidx;
}

这里需要解释一下,dict中的hash表,从结构中我们可以看出,hash表的大小为2,
因为当一个hash表中元素达到一定的数量的时候,需要对hash表进行扩容。则需要将原来的元素重新进行hash。

redis中计算索引的方法:

1:计算key的hash值
hash = dict->type->hashFunction(key);
2:计算索引:使用hash表的sizemask属性和哈希值,计算出索引值。
index = hash& dict->ht[x].sizemask;

redis中rehash

  1. 随着操作的不断执行,哈希表中保存的键值对会增加或者减少,程序需要对hash表进行对应的扩展或者收缩。
  2. rehash的步骤
    (1)为字典的ht[1]哈希表分配空间
    若是扩展操作,那么ht[1]的大小为>=ht[0].used*2的2^n
    若是收缩操作,那么ht[1]的大小为>=ht[0].used的2^n
    (2)将保存在ht[0]中的所有键值对rehash到ht[1]中,rehash指重新计算键的哈希值和索引值,然后将键值对放置到ht[1]哈希表的指定位置上。
    (3)当ht[0]的所有键值对都迁移到了ht[1]之后(ht[0]变为空表),释放ht[0],将ht[1]设置为ht[0],新建空白的哈希表ht[1],以备下次rehash使用。

注意:redis中hash不是一次性完成的,如果数据量特别大,需要计算很大数据量的hash值,这将很耗费cpu和系统资源,可能造成系统短时间不可用。所以系统会分批对hash值进行计算重新放入另外一个hash表;

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值