Redis设计与实现 笔记(2)——对象系统

——上一篇文章记录的是Redis最底层用到的主要数据结构,但Redis不是直接以这些数据结构构建键值对数据库的,而是:

  • 基于基础数据结构构建出多个对象,从而与Redis提供的数据类型相匹配(字符串、列表、集合、哈希表、有序集合)
对象结构 redisObject
typedef struct redisObject {
	unsigned type:4;//类型(对应5种数据类型)
	unsigned encoding:4//编码(对应用于底层实现的基本数据结构)
	void *ptr;//指向底层实现数据结构的指针
} robj;

一、 字符串对象
可用编码为:

  • int ——若对象保存的是整数,且可以用long类型表示,则以保存为int编码。
  • raw ——如果对象保存的是字符串值,且长度>32字节,则会使用**SDS(简单动态字符串)**来保存字符串值。raw编码会调用两次内存分配函数来分别创建robj结构和sdshdr结构。
  • embstr——如果对象保存的是字符串值,且长度 ≤ 32字节。该方式在raw基础上优化,只调用一次内存分配函数,将robj和sdshdr结构连续存放。(但该种编码方式,是只读的,即若采取了append函数后,底层变为raw编码)

二、列表对象
可用编码为:

  • ziplist ——压缩列表(顺序表)
  • linkedlist——双端链表,节点值类型是字符串。

三、哈希对象
可用编码为:

  • ziplist ——压缩列表,此时同一键值对的两个节点总是紧挨在一起,key在前,value在后。【此时不能用计算哈希值来快速得到索引,性能不会慢吗?大概是压缩列表适用于结点数较少情况下,所以性能不会说太慢?】
  • hashtable——使用字典来作为哈希对象底层实现。哈希表的键值对与用户所存的键值对是一致的。

四、集合对象
可用编码为:

  • intset ——整数集合(条件,所有元素都是整数值,元素数量不超过512个)
  • hashtable——字典。此时字典的键存储所需保存的元素,值则为null。【大概是使用hashtable后,每次存储元素需要计算哈希值,找到对应的索引位置,因此很方便去重】

五、有序集合
可用编码为:

  • ziplist ——第一个结点保存元素成员,第二个节点保存元素的分值。
  • skiplist ——使用的是zset结构作为底层实现(包含跳跃表zskiplist,字典dict);跳跃表用于查找范围值,字典用于快速获取某个元素的分值。
typedef struct zset {
	zskiplist *zsl;//跳跃表,用于范围型操作。
	dict *dict;//字典,存储的是成员到分值的映射
}zset;//虽然采取两个数据结构来构建zset,但会通过指针共享相同元素的成员和分值,不会浪费内存。

六、内存回收

  • 采取的是引用计数法
  • 创建一个新对象时,引用计数值初始化为1;
  • 当对象被一个新程序使用时,计数值自增1;
  • 当对象不再被一个程序使用时,计数值自减1;
  • 计数值变为0时,对象占用内存会被释放。

七、对象共享

  • 目前,Redis会在初始化服务器时,创建一万个字符串对象,包含了0~9999的所有整数值。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值