redis中的字典与hash结构

Redis中的字典作为数据库底层实现,用于保存键值对,并通过哈希表处理增删改查操作。字典在哈希键值对较多或字符串较长时生效,采用dictEntry结构处理冲突形成链表。字典的ht属性包含两个哈希表,用于扩展和收缩,rehash操作分多次渐进完成,以平衡负载因子。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

字典是redis中的一种数据结构实现,用来保存键值对。

字典中的每个键都是独一无二的,程序可以根据键来找到与之关联的值。


redis的数据库的底层实现是字典,对于数据库的增删改查操作也都是通过对字典进行操作来实现的。

字典还是hash键的底层实现之一,如果一个hash键包含的键值对比较多或字符串长度比较长的时候,redis就会使用字典作为hash键的底层实现。

---------------------------------------------------


redis的字典底层实现为hash表、



hash表由dict.h/dictht结构定义:

typedef struts dictht{
  //哈希表数组
  dictEntry **table;
  //哈希表数组
  unsigned long size;
  //哈希表大小掩码,用于计算索引值
  //总是等于size-1
  unsigned long sizemask;
  //该hash表已有节点的数量
  unsigned long used;
}dictth;
table属性是一个数组,每个元素指向一个 hash表节点的指针。


hash表节点的由dict.h/dictEntry结构定义

<pre name="code" class="cpp">typedef struts dictEntry{
  //键
  void *key;
  //值  
 union{
     void *val;
     uint64_tu64;
     int64_ts64;
  }
  //指向下个hash表节点,形成链表
  strut dictEntry *next;
}dictEntry;

 键值对的值可以是指针,uint64_t整数,或者是int64_t整数 
 

next属性的作用是:如果多个键值对的hash值相同,它们会成为一个单向链表,来解决冲突。

redis中的字典由 dict.h/dict结构来定义

typedef struts dict{
<pre name="code" class="cpp"><pre name="code" class="cpp">  //类型特定函数
  dictType *type;
  //私有数据
  void *private;
 //hash表
  dictth ht[2]
  //rehash索引
  //当rehash不再进行的时候,值为-1
 int trehashidx;
}dict;

 
 type属性和private属性针对不同类型的键值对,用来创建多态字典。 

dictType结构保存了一些用于操作键值对的函数,redis会为用途不同的字典设置不同的函数。

private保存了传给函数的 参数。

ht属性保存了两个hash表,通常情况下只使用一个hash表,另一个hash表用作复制。


该图展示了一个普通状态下的字典:




--------------------------------------------------------------------------------------


当一个键值对需要存储到字典中的时候,

1 .程序会使用hash算法根据 键值算出该键的hashcode,

2. 根据key算出的hashcode与sizemask属性算出该键值对的索引。

3. 根据索引将该键值对放在hash表数组的指定索引上。

   3.1 如果在该索引位置已经存在了键值对,则会形成单向链表,而且会把新加入的键值对放在该链表的表头。

   3.2如果没有,则直接加入。


rehashc操作

在不断加入新数据的过程中,为了减小hash表的负载因子,程序会通过rehash操作对hash表的大小进行拓展或伸缩。

该操作就用到了字典中的 h【0】 和 h【1】。

负载因子=ht【0】.used / ht【0】.size

当负载因子小于0.1的时候程序会执行收缩操作。

扩展:ht[1] >= ht[0].used*2 的 2^n
收缩 : ht[1] = ht[0].used 的 2^n

          rehash操作的时候,rehash动作是分多次,渐进式的完成的。避免了集中式rehash带来的庞大计算量。

在进行渐进式rehash操作期间,在字典中添加新值的时候 会保存在h[1]中,h[0]中的键值对只会减少,不会增加。



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值