第一篇: Redis源码分析(数据结构)

背景:
在高并发的场景下面,我们离不开缓存,那么缓存到底是什么实现了, 由此我想到的就是去看Redis源码,他的实现是由C语言实现,那么做为一个java、golang程序员,我们如何看懂呢? 其实秉承着语言都是相通的特性,就是开始分析Redis源码。


Redis数据结构分析

第一个: 我们先弄明白 SDS 其实就是定义redis 5中数据类型的数据结构定义
SDS:字符串即 Simple Dynamic String(即简单动态字符串),其中动态的含义是内存的分配是动态的,sds的

定义如下:

struct __attribute__ ((__packed__)) sdshdr8 {
    uint8_t len; /* used */    // 表示当前开辟了多少空间,我使用了多少空间
    uint8_t alloc; /* excluding the header and null terminator */    // 空间大小
    unsigned char flags; /* 3 lsb of type, 5 unused bits */  
    char buf[];
};

C语言语法: attribute ((packed)) 告诉编译器不采用内存对齐,什么是内存对齐,可以看看博客等等资料,还是挺简单的。

字段介绍

  • len 字段就存下了这个 sds 字符串的长度;sds字符串采用空间预分配机制,
  • alloc 字段就代表当前这个字符串预先分配了多少字节的可用空间,所以 alloc 一定是大于等于 len 的;
  • flags 的低三位代表 sds 的类型,高五位存储字符串的长度
  • buf是什么。buf才是存储数据的地方

后面我会详细介绍第三位与高五位?

// 定义一些宏 
#define SDS_TYPE_5  0   
#define SDS_TYPE_8  1
#define SDS_TYPE_16 2
#define SDS_TYPE_32 3
#define SDS_TYPE_64 4
// 第三位 
#define SDS_TYPE_MASK 7   
#define SDS_TYPE_BITS 3

接下来分析数据结构提供了那些方法

计算长度

// 计算长度  指向的是buf的首地址
static inline size_t sdslen(const sds s) {
    unsigned char flags = s[-1]; //  向量往上上面偏移得到
    //  低三为存储的是字符串的长度, 那么做运算等到的就是第三位的值
    switch(flags&SDS_TYPE_MASK) { // 7  0X00000111
        case SDS_TYPE_5:
            return SDS_TYPE_5_LEN(flags);  // SDS_TYPE_5_LEN(f) ((f)>>SDS_TYPE_BITS) 其实就是得到bit位置的数据
        case SDS_TYPE_8:
	            return SDS_HDR(8,s)->len; //
        case SDS_TYPE_16:
            return SDS_HDR(16,s)->len;
        case SDS_TYPE_32:
            return SDS_HDR(32,s)->len;
        case SDS_TYPE_64:
            return SDS_HDR(64,s)->len;
    }
    return 0;
}

上面这段代码可以详细分析下

  • 如果计算falg的值。他是如何推算出来的?
    在这里插入图片描述
  • 推断出falg的存储地址之后,需要计算出第三位的值
#define SDS_TYPE_MASK 7  // 这是宏

switch(flags&SDS_TYPE_MASK) // 这行代码是怎么计算出来的呢?

总结: 合并起来就是获取到的值就是第三位,而第三为正好表示类型, 知道了类型如何取到值呢?接续分析

  • 通过类型推算出他所占的内存空间大小
// 这段代码是什么意思呢 其实看懂了这段代码,就明白了他是怎么计算结构体的首地址
#define SDS_HDR(T,s) ((struct sdshdr##T *)((s)-(sizeof(struct sdshdr##T))))

在这里插入图片描述
看了这个图,我相信你应该白交明白了。

其余还有一些简单的实现我这里就不做分析了,因为都比较简单, 后面我们分析下他是如何开辟空间?

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值