sds

Redis源码阅读笔记—sds Redis系统当中,针对字符串进行的更加完善的封装,建立了一个动态字符串,并构建了大量的实用api。相关的实现代码为sds.h及sds.c,以下为我的源码阅读笔记。内容较多,逐步更新 阅读详情

双向链表(adlist.h/adlist.c)

链表(list)是Redis中最基本的数据结构,由adlist.h和adlist.c定义。

数据结构

typedef struct listNode {

        //指向前一个节点
    struct listNode *prev;

    //指向后一个节点
    struct listNode *next;

    //值
    void *value;
} listNode;

listNode是最基本的结构,表示链表中的一个结点。结点有向前(next)和向后 (prev)两个指针,链表是双向链表。保存的值是void*类型。

typedef struct list {

    listNode *head;

    listNode *tail;

    void *(*dup)(void *ptr);

    void (*free)(void *ptr);

    int (*match)(void *ptr, void *key);

    unsigned long len;
} list;

链表通过list定义,提供头(head)、尾(tail)两个指针,分别指向头部的结点和尾部的结点;提供三个函数指针,供用户传入自定义函数,用于复制(dup)、释放(free)和匹配(match)链表中的结点的值(value);通过无符号长整数len,标示链表的长度。

typedef struct listIter {

    listNode *next;

    int direction;
} listIter;

listIter是访问链表的迭代器,指针(next)指向链表的某个结点,direction表示迭代访问的方向(宏AL_START_HEAD表示向前,AL_START_TAIL表示向后)。

digraph adlist {    rankdir=LR;    node [shape=record, style = filled, fillcolor = "#95BBE3"];    edge [style = bold];    list_node_1 [label = "<head>listNode |{<prev> prev| value|<next> next}", ];    list_node_2 [label = "<head>listNode |{<prev> prev| value|<next> next}"];    list_node_3 [label = "<head>listNode |{<prev> prev| value|<next> next}"];    list_node_1:next -> list_node_2:head;    list_node_2:next -> list_node_3:head;    list_node_2:prev -> list_node_1:head;    list_node_3:prev -> list_node_2:head;    node [width=1.5, style = filled, fillcolor = "#A8E270"];    list [label = "list |<head> head|<tail> tail|<dup> dup|<free> free|<match> match|<len> len"];    list:tail -> list_node_3:head;    list:head -> list_node_1:head;}

使用方法

Redis定义了一系列的宏,用于访问list及其内部结点。

链表创建时(listCreate),通过Redis自己实现的zmalloc()分配堆空间。链表释放(listRelease)或删除结点(listDelNode)时,如果定义了链表(list)的指针函数free,Redis会使用它释放链表的每一个结点的值(value),否则需要用户手动释放。结点的内存使用Redis自己实现的zfree()释放。

对于迭代器,通过方法listGetIterator()、listNext()、 listReleaseIterator()、listRewind()和listRewindTail()使用,例如对于链表list,要从头向尾遍历,可通过如下代码:

iter = listGetIterator(list, AL_START_HEAD); // 获取迭代器
while((node = listNext(iter)) != NULL)
{
        dosomething;
}
listReleaseIterator(iter);

listDup()用于复制链表,如果用户实现了dup函数,则会使用它复制链表结点的value。listSearchKey()通过循环的方式在O(N)的时间复杂度下查找值,若用户实现了match函数,则用它进行匹配,否则使用按引用匹配。

应用

除了实现列表类型以外, 双端链表还被很多 Redis 内部模块所应用:

  • 事务模块使用双端链表依序保存输入的命令;
  • 服务器模块使用双端链表来保存多个客户端;
  • 订阅/发送模块使用双端链表来保存订阅模式的多个客户端;
  • 事件模块使用双端链表来保存时间事件(time event);

字符串(sds.h/sds.c)

为了方便计算字符串的长度、以及提高字符串的拼接效率,作者实现了自己的字符串结构sdshdr,是二进制安全的,并在后面自动添加0。

数据结构

typedef char *sds;

struct sdshdr {
        // 记录 buf 数组中已使用字节的数量
        // 等于 SDS 所保存字符串的长度
        int len;
        // 记录 buf 数组中未使用字节的数量
        int free;
        // 字节数组,用于保存字符串
        char buf[];
};

那么一个sds字符串实际申请的内存为:sizeof(sdshdr)+len+free+1,free新申请空间的时候为0,拼接字符串的时候free就不为0。

技巧

  1. 在函数sdsnewlen中,根据是否需要初始化使用zmalloc和zcalloc两个不同函数。
  2. 计算字符串长度的时候,直接使用函数sdslen,不需要调用strlen。

3. 需要扩展free的空间时,需要调用函数sdsMakeRoomFor,该函数空间分配策略比较有意思,如果free>=addlen,直接返回。否则判断free+addlen是否小于SDS_MAX_PREALLOC这个宏,如果小于,那么这次就分配2*(free+addlen)的空间,这样每次多分配一陪的空间;否则就分配free+addlen+SDS_MAX_PREALLOC的空间。这样可以控制最大多分配多少的空间,以至于不要浪费太多空间。例如:sds old=sdsnew("test one");sds new=sdscat(old,"test");此时有12的空余空间,如果再次调用``sdscat(new,”test”)``,那么就不需要分配空间。

4. 在函数sdscatvprintf中,空间申请是以16,32,64..这样增长的,无处不透露提高性能。

5. 在函数sdscmp中,调用memcmp,性能要比strcmp好,而且还是二进制安全的。

6. 在函数sdssplitlen中,默认分配的数组为5,然后按照2的倍数进行增长,这样做法,有点浪费空间,但是加快速度,不要每分割出来一个字符串就要申请空间。比较的时候把seplen为1分出来,也是加快字符串比较速度的考虑,大部分时候应该是seplen为1。

[原创]Redis BUG系列(I)——SDS字符串的sdssplitlen函数实现顺序BUG,浪费了计算与内存资源 这里写自定义目录标题欢迎使用Markdown编辑器新的改变功能快捷键合理的创建标题,有助于目录的生成如何改变文本的样式插入链接与图片如何插入一段漂亮的代码片生成一个适合你的列表创建一个表格设定内容居中、居左、居右SmartyPants创建一个自定义列表如何创建一个注脚注释也是必不可少的KaTeX数学公式新的甘特图功能,丰富你的文章UML 图表FLowchart流程图导出与导入导出导入 欢迎使用Ma... 阅读详情

相关推荐

PCIe SDS Ordered Set 详解

PCIe协议中的SDS(数据流起始序列)是用于标记从有序集向数据流转换的关键控制信号。SDS在特定链路状态(如Configuration.Idle、Recovery.Idle)下发送,其编码格式和发送规则随传输速率(8GT/s至64GT/s)而变化。发送SDS后必须进入非Flit模式的数据块传输,且后续需发送控制SKP有序集以确保数据流同步。SDS的异常处理会影响链路稳定性,错误解码可能触发接收错误事件。该机制有效保障了PCIe链路层数据的正确同步和传输完整性。

Summer的博客 1410

Redis源码(1)SDS和IntSet数据类型

Redis源码之SDS和IntSet数据类型

weixin_43823462的博客 1408

Redis使用SDS的原因

SDS定义 struct sdsher{ //记录buf中已保存字符的长度 //等于SDS所保存的字符串的长度 int len; //记录buf数组中未使用字节的数量 int free; //字节数组,用于保存字符串 char buf[]; }; 说明:SDS为了能够使用部分C字符串函数,遵循了C字符串以空字符结尾的惯例,保存空字符的1字节不计算在SDSlen属性中,并且为空字符分配额外...

keq_keq的博客 2674

Redis源码解析—SDS

SDS(简单动态字符串),是Redis中用于存储字符串数据的内部数据结构。redis 的sds结构实现字符串的基础。具体的文件有两个sds.c、sds.h。

Whisper的博客 1295

从源码中分析SDS相较于C字符串的优势

从本篇文章开始会持续更新有关"redis数据结构源码"的分析。[分析的源码是redis7.2.2版本的,有时候会结合之前的版本]。由于能力有限,有些地方可能有些错误,还望指正。在分析"intset"的源码的发现。在7.2.2版本,数据类型"set"的底层编码多了一种"listpack",但是之前的版本并没有。本着严谨的态度重新查看了源码以及配置文件,并作出相应的修改。主要修改的地方就是各个版本的数据类型和底层编码的对应图以及编码之间的阈值。编码为embstr的字符串是无法被修改的字符串。

weixin_46290302的博客 1436

Redis源码阅读——SDS

Redis源码阅读——SDS 参考Redis设计与实现 以及网上博客阅读Redis源码。 SDS相关知识点见读书笔记。 创建和销毁 为了能够对sds进行相关API的测试,因此把sds模块单独提出来。阅读Redis的Makefile发现,编译sds模块需要的源文件包括sds.c, sds.h zmalloc.c test-sds: sds.c sds.h $(REDIS_CC) s...

qq_33620071的博客 1038

Redis设计与实现(第一部分 第二章 简单动态字符串)

1、简单动态字符串 ​ redis是用C语言写的,而redis语言没有直接使用C语言的字符串(以\0结尾的的字符数组),而是自己构建一种名为SDS(简称)的抽象类型。 ​ 在redis内如果仅仅需要字符串字面量,无需对字符串进行修改的时候,redis会使用C字符串进行表示(打印日志),当不仅仅需要字面量,redis会用SDS进行表示。 例: redis> SET msg "Hello World!" 以上例子实际保存着msg与Hello World!的两个SDS。 1.1 SDS的定义 每个sds.

weixin_45275107的博客 231

SAP SD跨公司销售IDOC自动记账配置实战指南

本文详细介绍了SAP SD模块中跨公司销售IDOC自动记账的配置实战指南。通过IDOC技术实现集团企业间交易的自动化处理,显著提升财务效率和准确性。文章涵盖前置配置、RFC连接、合作伙伴参数设置及财务科目分配等关键步骤,并提供了常见错误排查和性能优化建议,帮助用户快速掌握这一高效业务流程。

weixin_29284885的博客 769

Redis深入浅出——字符串和SDS

一、字符串 字符串的类信息定义 1.1 字符串介绍 字符串是Redis中最为常见的数据存储类型,其底层实现是简单动态字符串sds(simple dynamic string),是可以修改的字符串。 它类似于Java中的ArrayList,它采用预分配冗余空间的方式来减少内存的频繁分配。 如图中所示,内部为当前字符串实际分配的空间 。其中capacity是最大容量,len是实际长度...

我的博客 2万+

服务器被攻击植入挖矿病毒,CPU占用高问题排查处理(.systemd-service.sh)

客户服务器遭攻击,部署的应用服务经常性被停止,服务器CPU占用居高不下,top查看如下: 可以看到第一个bash任务,占用cpu近400%,非正常的应用程序和脚本任务,多半是被植入了木马信息。 查看该进程的符号连接,发现已经是被删除的状态 /usr/bin/-bash (deleted),无法查看其启动程序的信息 查看定时任务:cat /etc/crontab,发现都是正常的应用程序定时脚本 又用 crontab -l 查看了一下,发现了异常定时任务如下,同top里的异常任务一致...

gottst0113的博客 2120

DeepSpeed Zero3 Offload实战:从GCC版本检查到环境配置的完整避坑指南

本文是一份针对DeepSpeed Zero3 Offload部署的完整避坑指南。针对训练中常见的`AttributeError: ‘DeepSpeedCPUAdam‘ object has no attribute ‘ds_opt_adam`报错,文章深入剖析了其根源在于GCC编译器版本过低。指南提供了从系统GCC版本深度探查、安全启用高版本GCC环境,到DeepSpeed一致性安装验证的全链路实战方案,旨在帮助用户构建稳定的大模型训练环境。

weixin_29070721的博客 474

redis源码之sds

sds是redis中一个很重要的数据结构,今天看学一下它源码的实现。 typedef char *sds; /* Note: sdshdr5 is never used, we just access the flags byte directly. * However is here to document the layout of type 5 SDS strings...

1万+

基于GIS的生态安全网络格局构建(附练习数据下载)

基于GIS的生态安全网络格局构建(附练习数据下载)

qq_43173805的博客 3124

Redis底层数据结构——SDS

7//sdshdr类型掩码,3//sdshdr类型位数因为sdshdr只有4种类型,用3个bit位即可表示10241024//sds字符串最大预分配空间,1MB。

qq_41637232的博客 1882

基于微信小程序的扫码签到系统源码

大等于jdk1.8,大于mysql5.5,idea(eclipse),微信开发者工具。代码注释齐全,没有多余代码,适合学习(毕设),二次开发,包含论文技术相关文档。签到管理:新增签到,点击查看码展示二维码(有时效性)springboot mybatis 小程序。签到管理:查看用户创建的签到,可删除。用户管理:查看注册用户信息,及删除。签到记录:查看用户签到记录:可删除。个人信息:展示个人信息,可修改。统计分析:查看用户,签到数量。签到记录:查看用户签到记录。登录注册(含授权登录)我的签到:查看签到记录。

wfuhui的博客 5224

假期搞定!2026国社科申报AI全攻略指南:从选题到创新,7大核心要点手把手教你!

最后给大家推荐的400多所高校教师都在用的AI平台——高级学术版专业应用平台,集成了国际主流学术应用,以及ChatGPT、Claude、Gemini、Grok等Al大模型的高级版本平台,还有,可以辅助大家高效完成科研和学术写作任务,当然撰写硕博论文,课题、职称论文、国社科、国自然基金本子也是手拿把掐。你的任务是:用高度凝练的方式说明在(某一明确国家战略 / 政策方向,如:中国式现代化、共同富裕、基层治理现代化、数字中国、文化强国、国家安全等)背景下,我究竟要研究一个什么“具体而可操作的问题”。

智能AI让学术科研更容易 624

Redis数据结构之——sds

Redis数据结构之——sds

weixin_46935110的博客 5773

飞牛fnNAS存储模式RAID 5数据恢复

中介绍了fnNAS存储空间的几个模式,细心的网友应该能感受到,我是非常推崇RAID 5的。但我认为,一般人出现1块硬盘损坏后,就能够赶紧采取处理措施了,再高的容灾等级也无法满足这个用户的需求了。》就完成了飞牛NAS存储空间的说明,包括了如何创建、怎么选择空间模式、RAID 5 硬盘故障后的更换、系统更换/重装后数据盘的恢复等等。在VMware中新建虚拟机,安装好fnNAS后,再向虚拟机添加“已有硬盘”(这就是所谓崩溃虚拟机的数据盘),此时新的fnNAS出现提示。在“选择要添加的硬盘”中,选择刚添加硬盘。

dgnankai的专栏 3010

redis SDS介绍

Redis面试中经常被问到,Redis效率为什么这么快,很多同学往往回答: ① Redis基于内存操作 ② Redis是单线程的,采用了IO多路复用技术 ③ Redis未使用C语言字符串,使用了SDS字符串 然而,很少有人能说清楚SDS字符串到底是什么,为什么使用SDS字符串比使用C语言字符串效率要高。 redis字符串(String)内存结构 字符串对象底层数据结构实现为简单动态字符串(SDS)和直接存储,但其编码方式可以是int、raw或者embstr,区别在于内存结构的不同。 1. int.

选择与努力 2401

Agentic-Desktop-Pet:构建本地智能桌面助手的架构与实践

智能体(Agent)作为人工智能领域的重要概念,是指能够感知环境、自主决策并执行任务以实现目标的软件实体。其核心原理在于结合感知、决策与执行模块,通过大语言模型(LLM)等推理引擎处理信息并驱动行动。这种架构的技术价值在于将AI的认知能力与具体的操作系统环境深度融合,从而创造出能主动理解用户上下文、提供个性化服务的智能伙伴。在应用场景上,智能体技术正从云端对话机器人向本地化、场景化的桌面助手演进,旨在解决传统自动化工具缺乏智能、而纯聊天机器人脱离操作环境的问题。本文探讨的Agentic-Desktop-Pe

weixin_27210125的博客 623

深度学习工具包 DeepLearningToolbox

深度学习工具包Deprecation notice.-----This toolbox is outdated and no longer maintained.There are much better tools available for deep learning than this toolbox, e.g. [Theano](http://deeplearning.net/software/theano/), [torch](http://torch.ch/) or [tensorflow](http://www.tensorflow.org/)I would suggest you use one of the tools mentioned above rather than use this toolbox.Best, Rasmus.DeepLearnToolbox================A Matlab toolbox for Deep Learning.Deep Learning is a new subfield of machine learning that focuses on learning deep hierarchical models of data.It is inspired by the human brain's apparent deep (layered, hierarchical) architecture.A good overview of the theory of Deep Learning theory is[Learning Deep Architectures for AI](http://www.iro.umontreal.ca/~bengioy/papers/ftml_book.pdf)For a more informal introduction, see the following videos by Geoffrey Hinton and Andrew Ng.* [The Next Generation of Neural Networks](http://www.youtube.com/watch?v=AyzOUbkUf3M) (Hinton, 2007)* [Recent Developments in Deep Learning](http://www.youtube.com/watch?v=VdIURAu1-aU) (Hinton, 2010)* [Unsupervised Feature Learning and Deep Learning](http://www.youtube.com/watch?v=ZmNOAtZIgIk) (Ng, 2011)If you use this toolbox in your research please cite [Prediction as a candidate for learning deep hierarchical models of data](http://www2.imm.dtu.dk/pubdb/views/publication_details.php?id=6284)```@MASTERSTHESIS\{IMM2012-06284, author = "R. B. Palm", title = "Prediction as a candidate for learning deep hierarchical models of data", year = "2012",}```Contact: rasmusbergpalm at gmail dot comDirectories included in the toolbox-----------------------------------`NN/` - A library for Feedforward Backpropagation Neural Networks`CNN/` - A library for Convolutional Neural Networks`DBN/` - A library for Deep Belief Networks`SAE/` - A library for Stacked Auto-Encoders`CAE/` - A library for Convolutional Auto-Encoders`util/` - Utility functions used by the libraries`data/` - Data used by the examples`tests/` - unit tests to verify toolbox is workingFor references on each library check REFS.mdSetup-----1. Download.2. addpath(genpath('DeepLearnToolbox'));Example: Deep Belief Network---------------------```matlabfunction test_example_DBNload mnist_uint8;train_x = double(train_x) / 255;test_x = double(test_x) / 255;train_y = double(train_y);test_y = double(test_y);%% ex1 train a 100 hidden unit RBM and visualize its weightsrand('state',0)dbn.sizes = [100];opts.numepochs = 1;opts.batchsize = 100;opts.momentum = 0;opts.alpha = 1;dbn = dbnsetup(dbn, train_x, opts);dbn = dbntrain(dbn, train_x, opts);figure; visualize(dbn.rbm{1}.W'); % Visualize the RBM weights%% ex2 train a 100-100 hidden unit DBN and use its weights to initialize a NNrand('state',0)%train dbndbn.sizes = [100 100];opts.numepochs = 1;opts.batchsize = 100;opts.momentum = 0;opts.alpha = 1;dbn = dbnsetup(dbn, train_x, opts);dbn = dbntrain(dbn, train_x, opts);%unfold dbn to nnnn = dbnunfoldtonn(dbn, 10);nn.activation_function = 'sigm';%train nnopts.numepochs = 1;opts.batchsize = 100;nn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.10, 'Too big error');```Example: Stacked Auto-Encoders---------------------```matlabfunction test_example_SAEload mnist_uint8;train_x = double(train_x)/255;test_x = double(test_x)/255;train_y = double(train_y);test_y = double(test_y);%% ex1 train a 100 hidden unit SDAE and use it to initialize a FFNN% Setup and train a stacked denoising autoencoder (SDAE)rand('state',0)sae = saesetup([784 100]);sae.ae{1}.activation_function = 'sigm';sae.ae{1}.learningRate = 1;sae.ae{1}.inputZeroMaskedFraction = 0.5;opts.numepochs = 1;opts.batchsize = 100;sae = saetrain(sae, train_x, opts);visualize(sae.ae{1}.W{1}(:,2:end)')% Use the SDAE to initialize a FFNNnn = nnsetup([784 100 10]);nn.activation_function = 'sigm';nn.learningRate = 1;nn.W{1} = sae.ae{1}.W{1};% Train the FFNNopts.numepochs = 1;opts.batchsize = 100;nn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.16, 'Too big error');```Example: Convolutional Neural Nets---------------------```matlabfunction test_example_CNNload mnist_uint8;train_x = double(reshape(train_x',28,28,60000))/255;test_x = double(reshape(test_x',28,28,10000))/255;train_y = double(train_y');test_y = double(test_y');%% ex1 Train a 6c-2s-12c-2s Convolutional neural network %will run 1 epoch in about 200 second and get around 11% error. %With 100 epochs you'll get around 1.2% errorrand('state',0)cnn.layers = { struct('type', 'i') %input layer struct('type', 'c', 'outputmaps', 6, 'kernelsize', 5) %convolution layer struct('type', 's', 'scale', 2) %sub sampling layer struct('type', 'c', 'outputmaps', 12, 'kernelsize', 5) %convolution layer struct('type', 's', 'scale', 2) %subsampling layer};cnn = cnnsetup(cnn, train_x, train_y);opts.alpha = 1;opts.batchsize = 50;opts.numepochs = 1;cnn = cnntrain(cnn, train_x, train_y, opts);[er, bad] = cnntest(cnn, test_x, test_y);%plot mean squared errorfigure; plot(cnn.rL);assert(er<0.12, 'Too big error');```Example: Neural Networks---------------------```matlabfunction test_example_NNload mnist_uint8;train_x = double(train_x) / 255;test_x = double(test_x) / 255;train_y = double(train_y);test_y = double(test_y);% normalize[train_x, mu, sigma] = zscore(train_x);test_x = normalize(test_x, mu, sigma);%% ex1 vanilla neural netrand('state',0)nn = nnsetup([784 100 10]);opts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samples[nn, L] = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.08, 'Too big error');%% ex2 neural net with L2 weight decayrand('state',0)nn = nnsetup([784 100 10]);nn.weightPenaltyL2 = 1e-4; % L2 weight decayopts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex3 neural net with dropoutrand('state',0)nn = nnsetup([784 100 10]);nn.dropoutFraction = 0.5; % Dropout fraction opts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex4 neural net with sigmoid activation functionrand('state',0)nn = nnsetup([784 100 10]);nn.activation_function = 'sigm'; % Sigmoid activation functionnn.learningRate = 1; % Sigm require a lower learning rateopts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex5 plotting functionalityrand('state',0)nn = nnsetup([784 20 10]);opts.numepochs = 5; % Number of full sweeps through datann.output = 'softmax'; % use softmax outputopts.batchsize = 1000; % Take a mean gradient step over this many samplesopts.plot = 1; % enable plottingnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex6 neural net with sigmoid activation and plotting of validation and training error% split training data into training and validation datavx = train_x(1:10000,:);tx = train_x(10001:end,:);vy = train_y(1:10000,:);ty = train_y(10001:end,:);rand('state',0)nn = nnsetup([784 20 10]); nn.output = 'softmax'; % use softmax outputopts.numepochs = 5; % Number of full sweeps through dataopts.batchsize = 1000; % Take a mean gradient step over this many samplesopts.plot = 1; % enable plottingnn = nntrain(nn, tx, ty, opts, vx, vy); % nntrain takes validation set as last two arguments (optionally)[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');```[![Bitdeli Badge](https://d2weczhvl823v0.cloudfront.net/rasmusbergpalm/deeplearntoolbox/trend.png)](https://bitdeli.com/free "Bitdeli Badge")

Redis为什么要采取SDS结构以及SDS在对象中的应用

buf属性是一个char类型的数组,数组的前五个字节分别保存了'R'、'e'、'd'、'i'、's'五个字符,而最后一个字节则保存了空字符'\0'。len的长度为5说明保存了一个长度为5的字符串,Free的值为0,说明没有未分配空间,这是一个记录Redis字符串的实例,

chenci200109的博客 1099

pscad IEEE标准系统搭建说明

pscad IEEE标准系统搭建说明,包含典型的IEEE 9节点、14节点、30节点、39节点和118节点系统。内含标准测试系统的原始数据和潮流结果。

Redis之SDS

1、概述 Redis没有直接使用C语言传统的字符串表示(以空字符结尾的字符数组,以下简称C字符串),而是自己构建了一种名为简单动态字符串(simple dynamic string,SDS)的抽象类型,并将SDS用作Redis的默认字符串表示。 当Redis需要的不仅仅是一个字符串字面量,而是一个可以被修改的字符串值时,Redis就会使用SDS来表示字符串值。 2、SDS结构 struct sdshdr { // 记录buf数组中已使用字节的数量 /...

sssxlxwbwz的博客 1289

visio安装包

Microsoft Office Visio 是一款专业的制图软件。利用经过更新的形状、协作工具和数据链接图表,创建专业级图表以简化复杂的信息。

Probability and Statistics - 4th edition

Probability and Statistics - 4th edition

Redis底层数据结构之SDS

Redis 中的 SDS(Simple Dynamic String,简单动态字符串)是 Redis 用于存储字符串值的底层实现,是对 C 语言传统字符串(以 null 结尾的字符数组)的改良,内部结构类似于 C 语言的字符数组,但额外存储了字符串长度和分配空间大小,避免了 C 字符串的缺陷。SDS用于解决 C 字符串的一些限制和安全性问题, 具有动态扩容的特点. 其实现位于src/sds.h与src/sds.c中。

xiong_tai的博客 1614

String类型之SDS

Redis采用SDS(简单动态字符串)而非C原生char[]的原因在于:1)SDS通过预分配和惰性释放策略减少内存重分配开销;2)内置len字段实现O(1)复杂度获取字符串长度;3)支持二进制安全,允许存储包含'\0'的数据;4)兼容C字符串函数的同时通过结构体封装元数据。这种设计有效解决了char[]在频繁修改、长度获取和二进制存储方面的缺陷,特别适合Redis作为高性能数据库对字符串操作的需求。SDS通过空间预分配和元数据维护,在内存效率和操作性能上取得了最佳平衡。

2302_81141145的博客 976

【Redis】SDS 与 C 字符串的区别

SDS 与 C 字符串的区别 根据传统, C 语言使用长度为N+1的字符数组来表示长度为N的字符串, 并且字符数组的最后一个元素总是空字符'\0'。 比如说, 图 2-3 就展示了一个值为"Redis"的 C 字符串: C 语言使用的这种简单的字符串表示方式, 并不能满足 Redis 对字符串在安全性、效率、以及功能方面的要求, 本节接下来的内容将详细对比 C 字符串和 ...

最怕一生碌碌无为,还安慰自己平凡可贵 2万+

【Redis】简单动态字符串 SDS

虽然 Redis 是使用标准 C 语言开发的,但并没有直接使用 C 语言中传统的字符串表示,而是自定义了一 种字符串。这种字符串本身的结构比较简单,但功能却非常强大,称为简单动态字符串,简称 SDSRedis 中的所有字符串并不都是 SDS,也会出现 C 字符串。C 字符串只会出现在字符串“字面常量”中,并且该字符串不可能发生变更。

m0_61057201的博客 1413
上一篇: Lombok 之 ToString
下一篇: 数据库键空间
TuxedoLinux
博客等级 码龄9年 268粉丝 34原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值