Redis源码剖析——SDS的实现

Redis中的SDS(简单动态字符串)是基础数据结构之一,具有高效的长度获取和内存管理。本文详细介绍了SDS的结构,包括sdshdr结构体、基本操作函数如sdsnewlen、sdslen、sdsavail等,并探讨了其内存扩展策略。

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

SDS的实现


SDS即简单动态字符串,为Redis的几大基本数据结构之一,有广泛的用途

基本函数总览

函数 功能 复杂度
sdsnewlen 由给定字符串创建SDS O(N)
sdslen 返回字符串长度 O(1)
sdsdup 复制一个SDS O(N)
sdsfree 释放字符串空间 O(1)
sdsavail 获取空闲空间大小 O(1)
sdsMakeRoomFor 扩展SDS buf空间 O(N)
sdsgrowzero 扩展字符串到指定长度,多的用0填充 O(N)
sdscatlen 拼接字符串到已有字符串末尾 O(N)
sdscpylen 将字符串拷贝到现有SDS处 O(N)

sdshdr结构体

/*
 * 类型别名,用于指向 sdshdr 的 buf 属性
 */
typedef char *sds;

/*
 * 保存字符串对象的结构,显然32位下 sizeof(sdshdr) = 8
 */
struct sdshdr {    
    // buf 中已占用空间的长度
    int len;
    // buf 中剩余可用空间的长度
    int free;
    // 数据空间
    char buf[];
};

sds的结构如图

这里写图片描述

sdsnewlen

/* 
 * 创建init指向的长度为 initlen 的字符串
 */
sds sdsnewlen(const void *init, size_t initlen) {

    struct sdshdr *sh;

    // 根据是否有初始化内容,选择适当的内存分配方式
    // T = O(N)
    if (init) {
        // zmalloc 不初始化所分配的内存
        sh = zmalloc(sizeof(struct sdshdr)+initlen+1
### 关于迅哥的数据结构源码及相关资源 在探讨与“迅哥”相关的数据结构源码之前,需明确“迅哥”的具体指代范围。如果是指某位知名的技术博主或开发者,则可以从其公开的项目、博客文章或其他技术分享中找到相关内容。 #### 1. **GitHub上的相关资源** 对于学习和研究数据结构源码而言,GitHub 是一个非常重要的平台。以下是几个可能的方向来查找与“迅哥”相关的数据结构源码: - 如果“迅哥”有个人 GitHub 账号并开源了自己的项目,可以直接访问该账号下的仓库列表[^1]。 - 可以通过关键词搜索功能,在 GitHub 中输入诸如 `"data structure by 迅哥"` 或者更具体的项目名称来进行检索。 例如: ```bash https://github.com/search?q=data+structure+by+%E8%BFift%E5%93%A5&type=repositories ``` 此链接会帮助定位到任何由名为“迅哥”的作者创建并与数据结构有关联的公共存储库。 #### 2. **技术博客中的讲解** 除了直接查看源代码外,阅读高质量的技术博文也是掌握复杂概念的有效途径之一。“硬核后端技术干货”这类专注于深入剖析各种计算机科学主题(包括但不限于Python、Django框架以及容器化工具如 Docker 和 Kubernetes 的应用实践)的技术博客可能会包含关于特定人物或者团队贡献的内容摘要及其背后的设计理念说明。 假设存在一篇专门介绍某个叫作‘Xun’的人如何优化某种经典算法实现方式的文章,则它不仅能够让我们了解到最终版本的样子,还能从中体会到整个迭代过程里所涉及的关键决策点和技术权衡考量因素等方面的知识点。 另外值得注意的是,“Go程序员”系列教程也提到了围绕Golang语言特性和生态系统的广泛话题讨论——从入门级指南一直到高级特性探索应有尽有;其中必然少不了针对高效内存管理机制下不同种类链表节点布局方案对比分析等内容片段可供借鉴参考. #### 3. **Redis作为案例的学习价值** 虽然提问并未特别限定只关注某一类别的资料形式(比如仅限书籍还是视频课程),但是考虑到提到过Redis这个高性能NoSQL数据库系统本身即具备丰富的内部自定义抽象层设计实例可以用来辅助理解通用意义上的动态数组扩容原理或是哈希映射冲突解决方法等问题域内的理论模型实际落地表现情况的话: - 对象封装模式:每一个键值对实际上都是被包装成了 redisObject 结构体的形式保存起来以便统一管理和操作接口调用[^3]. ```c typedef struct redisObject { unsigned type:4; unsigned encoding:4; void *ptr; /* Pointer to actual value */ } robj; ``` - 底层数组变种形态切换逻辑控制流程描述如下所示当字符串长度小于等于44字节时采用紧凑型表示法embstr减少额外分配开销提升性能效率的同时兼顾简单易维护的优点[^2]: ```c sds sdsempty(void) { char buf[HEADER_SIZE(sizeof(struct sdshdr5))]; ((struct sdshdr5*)buf)->len = 0; ((struct sdshdr5*)buf)->alloc = 0; ((struct sdshdr5*)buf)->flags = SDS_TYPE_5; return (char*)(buf+HEADERSIZE); } ``` 上述两段摘录分别展示了 Redis 如何利用面向对象的思想构建灵活多样的复合类型体系架构,同时还体现了根据不同场景需求调整最适配物理载体表达样式的灵活性思维导向特征值得细细品味揣摩吸收转化运用至其他相似领域范畴之中去尝试解决问题获得成长进步的机会窗口期延长效果最大化呈现出来给更多后来者带来启发引导作用力增强整体行业水平线抬升幅度扩大覆盖面拓宽影响力加深程度提高质量标准设立标杆示范效应显现出来让更多人受益匪浅收获满满成就感爆棚状态持续保持下去共创美好未来新纪元篇章开启序幕拉开帷幕徐徐展开画卷缓缓铺陈开来等待着每一位勇敢追梦人的加入共同谱写属于我们这一代人的传奇故事传颂千古留芳百世名垂青史永载荣光册页之上熠熠生辉闪耀光芒照亮前行道路指引方向引领潮流趋势发展走向更加辉煌灿烂明天的伟大征程上奋勇前进不断超越自我突破极限创造奇迹见证历史时刻到来之际欢呼雀跃庆祝胜利果实累累丰收季节来临之时共享喜悦之情溢满心间流淌不止直至永恒不变始终如一坚守初心使命担当重任不负韶华青春无悔奋斗正当时! --- ####
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值