redis源码阅读之redis五种对象的底层数据结构

title:redisObject

redis 的 对象

Redis 使用对象来表示数据库中的键和值,每次当我们在redis的数据库创建一个键值对时,至少会创建两个对象,一个键对象,一个值对象。
set msg "hello world"

redisObject 的对象结构

typedef struct redisObject{
    //类型  REDIS_STRING/REDIS_LIST/REDIS_HASH/REDIS_SET/REDIS_ZSET
    unsigned type: 4;
    //编码  REDIS_ENCODING_INT/REDIS_ENCODING_EMBSTR/REDIS_ENCODING_RAW/REDIS_ENCODING_HT/REDIS_ENCODING_LINKEDLIST/REDIS_ENCODING_ZOPLIST/REDIS_ENCODING_INTSET/SKIPLIST
    unsigned encoding:4;
    //指向底层实现数据结构的指针
    void *ptr;
    //..
}

使用object encoding 可以实现数据库键的值对象的编码

字符串对象 String

String的字符串结构可能为 int raw embstr

  1. 如果字符串对象保存的是整数值,并且这个对象可以用long类型来表示,那么字符串对象会将整数值保存在字符串对象结构的ptr属性里面(void* 转化为 long),encoding 设置为 int
  2. 如果字符串对象保存的是一个字符串值,并且这个字符串值的长度大于32字节,那么字符串对象将使用SDS保存。encoding设置为raw 使用APPEND可以将其他编码转换为raw方式。
  3. embstr 对象保存短字符串的优化编码方式
String 的API
  1. INCRBY
  2. DECRBY
  3. STRLEN

列表对象 List

列表对象的编码可能为 ziplist 和 linkedlist

当列表对象满足如下条件时,列表对象使用ziplist编码

  1. 列表对象保存的所以字符串元素的长度都小于64字节
  2. 列表对象保存的元素数量小于512个,不能满足这两个条件就使用linkedlist。

哈希对象 hash

哈希对象的编码可以是 ziplist 或者 hashtable。

zip 编码的哈希对象使用ziplist作为底层实现。每当有新的键值对要加入到哈希对象时,程序会先保存键的压缩列表节点推入到压缩列表表尾。然后再将保存了的值压缩节点推入到压缩列表表尾。

hashtable 编码的哈希对象使用字典作为底层实现。哈希对象中的值都是使用一个字典键值对来保存。

  1. 字典的每一个键都是一个字符串对象,对象中保存了键值对的键。
  2. 字典的每一个值都是一个字符串对象,对象中保存了键值对的值。

编码转换

  1. 哈希对象保存的所有键值对的键和值的字符串长度都小于64字节;
  2. 哈希对象保存的键值对数量小于512个,不能满足这两个条件的哈希对象需要使用hashtable编码。

集合对象 set

集合对象的编码可以是intSet 或者 hashtable.

intset 编码的集合对象使用整数集合作为底层实现,集合对象包含的所有元素都被保存在整数集合里面。

hashtable 编码的集合对象使用字典作为底层实现。字典的每个键都是一个字符串对象,每个字符串对象包含一个集合元素,而字典的值全部被修改为NULL。

类型转换 以下两个条件使用intset编码

  1. 集合对象保存的所有元素都是整数值
  2. 集合对象保存的元素数量不超过512个

有序集合对象 ziplist 或者 skiplist

有序集合的编码可以是ziplist 或者 skiplist。

ziplist编码使用压缩列表作为底层实现。每个集合元素使用两个紧挨在一起的压缩列表节点来保存。第一个节点保存元素的成员(member),第二个元素保存元素的分值(score)。

SkipList编码的有序集合对象使用zset结构作为底层实现,一个zset结构同时包含一个字典和一个跳跃表:

typedef struct zset{
    zskiplist *zsl; // 实现范围型的操作
    dict *dict; // 键-元素成员 值-保存元素的分值 O(1);
}zset;
//虽然两种结构,但是使用的是指针共享,不浪费额外的内存。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值