Redis SDS 源码

底层数据结构的好处:

  1. 杜绝缓冲区溢出。
  2. 减少修改字符串长度时所需的内存重分配次数。
  3. 二进制安全。
  4. 兼容部分C字符串函数。

常用命令: set key value、get key 等

应用场景:共享 session、分布式锁,计数器、限流。

1、给char*定义了个别名。

typedef char *sds;

2、创建sds字符串并且分配空间

sds.c
sds结构体
/** 保存字符串对象的结构*/
struct sdshdr {// buf 中已占用空间的长度int len;// buf 中剩余可用空间的长度int free;// 数据空间char buf[];
};
//好处之一:创建sds字符串的时候会优先分配空间并且预留下一次分配空间。
sds sdsnewlen(const void *init, size_t initlen) {定义sds结构体指针struct sdshdr *sh;if (init) {//创建sds结构体并且分配空间sh = zmalloc(sizeof(struct sdshdr)+initlen+1);} else {sh = zcalloc(sizeof(struct sdshdr)+initlen+1);}if (sh == NULL) return NULL;sh->len = initlen;sh->free = 0;if (initlen && init)memcpy(sh->buf, init, initlen);sh->buf[initlen] = '\0';return (char*)sh->buf;
}

3、sds字符串的追加

/* Append the specified binary-safe string pointed by 't' of 'len' bytes to the* end of the specified sds string 's'.** After the call, the passed sds string is no longer valid and all the* references must be substituted with the new pointer returned by the call. */
//s目标字符串
//t源字符串
//len追加的长度
sds sdscatlen(sds s, const void *t, size_t len) {struct sdshdr *sh;//计算目标字符串的长度size_t curlen = sdslen(s);//根据要追加的长度len和目标字符串s的现有长度,判断是否要增加新的空间s = sdsMakeRoomFor(s,len);if (s == NULL) return NULL;sh = (void*) (s-(sizeof(struct sdshdr)));//将源字符串t中len长度的数据拷贝到目标字符串结尾memcpy(s+curlen, t, len);sh->len = curlen+len;sh->free = sh->free-len;//追加\0作为本次追加的结尾。s[curlen+len] = '\0';return s;
}

        3-1、扩容详细。

,这是一个相对耗时的操作,这里尽量在使用的时候做好计算。

/* Enlarge the free space at the end of the sds string so that the caller* is sure that after calling this function can overwrite up to addlen* bytes after the end of the string, plus one more byte for nul term.* * Note: this does not change the *length* of the sds string as returned* by sdslen(), but only the free buffer space we have. * 当计算后的新的长度小于1MB,则分配两倍空间* 当计算后的新的长度大于1MB,则在原来基础上加多1MB。
*/
#define SDS_MAX_PREALLOC (1024*1024)
sds sdsMakeRoomFor(sds s, size_t addlen) {struct sdshdr *sh, *newsh;// 获取 s 目前的空余空间长度size_t free = sdsavail(s);size_t len, newlen;// s 目前的空余空间已经足够,无须再进行扩展,直接返回if (free >= addlen) return s;// 获取 s 目前已占用空间的长度len = sdslen(s);sh = (void*) (s-(sizeof(struct sdshdr)));// s 最少需要的长度newlen = (len+addlen);// 根据新长度,为 s 分配新空间所需的大小if (newlen < SDS_MAX_PREALLOC)// 如果新长度小于 SDS_MAX_PREALLOC // 那么为它分配两倍于所需长度的空间newlen *= 2;else// 否则,分配长度为目前长度加上 SDS_MAX_PREALLOCnewlen += SDS_MAX_PREALLOC;// T = O(N)newsh = zrealloc(sh, sizeof(struct sdshdr)+newlen+1);// 内存不足,分配失败,返回if (newsh == NULL) return NULL;// 更新 sds 的空余长度newsh->free = newlen - len;// 返回 sdsreturn newsh->buf;
}

4、SDS 类型

sdshdr5、sdshdr8、sdshdr16、sdshdr32、sdshdr64

 5种结构体类型,设计是一样的,字符数组现有长度 len 和分配空间长度 alloc是不一样的。

以sdshdr8结构体为例,

 __attribute__ ((__packed__))的作用:
//告诉编译器,在编译 sdshdr8 结构时,不要使用字节对齐的方式,而是采用紧凑的方式分配内存。这是因为在默认情况下,编译器会按照 8 字节对齐的方式,给变量分配内存。也就是说,即使一个变量的大小不到 8 个字节,编译器也会给它分配 8 个字节。

struct __attribute__ ((__packed__)) sdshdr8 {uint8_t len; /* 字符数组现有长度*/uint8_t alloc; /* 字符数组的已分配空间,不包括结构体和\0结束字符*/unsigned char flags; /* SDS类型*/char buf[]; /*字符数组*/
};

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/192207.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

前端请求patch接口,只传入已修改字段值的字段

目录 前端仅传递发生更改的字段 为什么 数据举例 递归对比函数 从回显数据到提交更新接口的模拟操作 前端仅传递发生更改的字段 在实际开发中前端肯定会遇到一个更新需求&#xff0c;回显数据 > 修改数据 > 请求更新接口这个步骤。 通常建议前端仅传递发生更改的字…

【重点】【哈希】128.最长连续序列

题目 思路&#xff1a;https://leetcode.cn/problems/longest-consecutive-sequence/solutions/2362995/javapython3cha-xi-biao-ding-wei-mei-ge-l-xk4c/?envTypestudy-plan-v2&envIdtop-100-liked class Solution {public int longestConsecutive(int[] nums) {Set<…

<JavaEE> volatile关键字 -- 保证内存可见性、禁止指令重排序

目录 一、内存可见性 1.1 Java内存模型(JMM) 1.2 内存可见性演示 二、指令重排序 三、关键字 volatile 一、内存可见性 1.1 Java内存模型(JMM) 1&#xff09;什么是Java内存模型&#xff08;JMM&#xff09;&#xff1f;Java内存模型即Java Memory Model&#xff0c;简…

如何使用注解实现接口的幂等性校验

如何使用注解实现接口的幂等性校验 背景什么是幂等性为什么要实现幂等性校验如何实现接口的幂等性校验1. 数据库唯一主键2. 数据库乐观锁3. 防重 Token 令牌4. redis 如何将这几种方式都组装到一起结语 背景 最近在小组同学卷的受不了的情况下&#xff0c;我决定换一个方向卷去…

在 MySQL 中创建用户和分配权限

在 MySQL 中创建用户和分配权限 登录到 MySQL&#xff1a; 首先&#xff0c;使用 root 用户或其他具有足够权限的用户登录到 MySQL&#xff1a; mysql -u root -p创建新用户&#xff1a; 在 MySQL 提示符下&#xff0c;使用以下命令创建新用户&#xff1a; CREATE USER newuser…

基于景区智慧灯杆、智能指路牌基础设施的景区建设应用

智慧景区是指运用现代信息技术手段&#xff0c;将景区内的资源、服务、管理等进行数字化、网络化和智能化整合&#xff0c;打造出高效便捷、安全舒适、互动体验和可持续发展的景区。智慧景区可以从以下几个方面进行体现&#xff1a; 智慧导览&#xff1a;通过使用智能化的导览…

二分查找:LeetCode2035:将数组分成两个数组并最小化数组和的差

本文涉及的基础知识点 二分查找算法合集 作者推荐 动态规划LeetCode2552&#xff1a;优化了6版的1324模式 题目 给你一个长度为 2 * n 的整数数组。你需要将 nums 分成 两个 长度为 n 的数组&#xff0c;分别求出两个数组的和&#xff0c;并 最小化 两个数组和之 差的绝对…

工业机器视觉megauging(向光有光)使用说明书(一,轻量级的visionpro)

机器视觉megauging&#xff08;未名之光&#xff0c;向光有光&#xff09;程序软件资源已经发布&#xff0c;欢迎下载尝新 8:11 2023/12/2 首先&#xff0c;既然觉得可以发表了&#xff0c;就发表。 其次&#xff0c;我这个人没写过什么软件使用说明书&#xff0c;既然走到这路…

用两个队列实现栈

目录 一、队列的基本结构及其接口 二、我的栈的结构 三、 我的栈的创建及其初始化 四、我的栈的入栈 五、我的栈出栈 六、我的栈取栈顶元素 七、我的栈判空 八、我的栈销毁 一、队列的基本结构及其接口 typedef int QDataType;//队列的结构定义 typedef struct QueueNo…

Screenshot To Code

序言 对于GPT-4我只是一个门外汉&#xff0c;至于我为什么要了解screenshot to code&#xff0c;只是因为我想知道&#xff0c;在我不懂前端设计的情况下&#xff0c;能不能通过一些工具辅助自己做一些简单的前端界面设计。如果你想通过此文深刻了解GPT-4或者该开源项目&#…

【python】保存excel

正确安装了pandas和openpyxl库。 可以通过在命令行中输入以下命令来检查&#xff1a; pip show pandas pip show openpyxl 可以使用pip安装 pip install pandas pip install openpyxl#更新 pip install --upgrade pandas pip install --upgrade openpyxl 保存excel …

pygame实现贪吃蛇小游戏

import pygame import random# 游戏初始化 pygame.init()# 游戏窗口设置 win_width, win_height 800, 600 window pygame.display.set_mode((win_width, win_height)) pygame.display.set_caption("Snake Game")# 颜色设置 WHITE (255, 255, 255) BLACK (0, 0, 0…

如何确定短线的买入卖出时机?

短线投资制胜的一个关键能力&#xff0c;就是精准地找到买入卖出时机。那么&#xff0c;怎么样才能获得这种关键能力呢&#xff1f; 在这节课里&#xff0c;我们将给大家梳理一下常见的短线买入卖出时机&#xff0c;并通过案例讲解帮助大家理解。话不多说&#xff0c;赶紧进入主…

大数据基础设施搭建 - 业务数据同步策略

文章目录 一、全量同步1.1 梳理需要全量同步的业务表1.2 Sqoop: MySQL To HDFS1.2.1 开发脚本1.2.2 授予脚本执行权限1.2.3 执行脚本1.2.4 定时调度 二、增量同步2.1 梳理需要增量同步的业务表2.2 Maxwell: MySQL To Kafka2.2.1 首次全量同步2.2.2 每日增量同步2.2.2.1 编写Max…

周一到周五进行osg和渲染,周末进行ue

之所以重新规划&#xff0c;是因为我在某家小公司做Ue开发顾问。其实&#xff0c;我这烂水平&#xff0c;也有人看得上&#xff0c;哈哈。 正好督促我学习ue了&#xff0c;也不荒废掉ue&#xff0c;也不用盲目跳槽&#xff0c;时间也分得很开&#xff0c;very good。

rdf-file:SM2加解密

一&#xff1a;SM2简介 SM2是中国密码学算法标准中的一种非对称加密算法&#xff08;包括公钥和私钥&#xff09;。SM2主要用于数字签名、密钥交换和加密解密等密码学。 生成秘钥&#xff1a;用于生成一对公钥和私钥。公钥&#xff1a;用于加密数据和验证数字签名。私钥&…

javaSE学习-1-数据类型与运算符

目录 字面常量 数据类型 int Long short Byte float double char boolean 类型转换 强转 自动类型转换(隐式) 字符串类型 字符串和整形数字之间进行转换 字面常量 比如 System.Out.println("Hello World") &#xff1b; 语句&#xff0c;不论程序何时…

代码随想录第二十二天(一刷C语言)|组合总数电话号码的字母组合

创作目的&#xff1a;为了方便自己后续复习重点&#xff0c;以及养成写博客的习惯。 一、组合总数 思路&#xff1a;参考carl文档和视频 1、需要一维数组path来存放符合条件的结果&#xff0c;二维数组result来存放结果集。 2、targetSum 目标和&#xff0c;也就是题目中的…

企业数字化转型应该做什么

以下是通过学习华为数字化转型并结合自身情况引发的学习思考,供大家参考。企业做数字化转型目的是为了赋能业务,因为原有老业务发展了这么多年,好做的都已经做完了,目前已进入了深水区,需要引入新的创新源泉,需要跨界创新,特别是这几年IT技术的发展,需要通过IT进行借力…