动态字符串SDS

news2025/2/11 7:19:41

基本概括

Redis中保存的Key是字符串,value往往是字符串或者字符串的集合。可见字符串是Redis中最常用的一种数据结构。

但Redis没有直接使用C语言中的字符串,因为C语言字符串存在很多问题(C语言中实际上没有字符串,本质上是字符数组):

image-20230612223142000

C语言中字符串(字符数组)以'\0'标识字符串结束,如果字符串中本身就包含’\0’就会有问题,另外:

  • 获取字符串长度的需要通过运算
  • 非二进制安全(以’\0’标识结束)
  • 不可修改(拼接字符串需额外申请新的空间)

因此,Redis构建了一种新的字符串结构,称为简单动态字符串Simple Dynamic String),简称 SDS

执行 set name likelong 命令
实际上Redis将在底层创建两个SDS,其中一个是包含“name”的SDS,另一个是包含“likelong”的SDS。

结构如下:

image-20230612223921586

上述最大保存255(2^8 - 1)个字节字符数组

Redis源码:多种类型SDS,比较常用的还是上面的类型,无需占用多余内存

sds.h文件

struct __attribute__ ((__packed__)) sdshdr5 {
    unsigned char flags; /* 3 lsb of type, and 5 msb of string length */
    char buf[];
};
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[];
};
struct __attribute__ ((__packed__)) sdshdr16 {
    uint16_t len; /* used */
    uint16_t alloc; /* excluding the header and null terminator */
    unsigned char flags; /* 3 lsb of type, 5 unused bits */
    char buf[];
};
struct __attribute__ ((__packed__)) sdshdr32 {
    uint32_t len; /* used */
    uint32_t alloc; /* excluding the header and null terminator */
    unsigned char flags; /* 3 lsb of type, 5 unused bits */
    char buf[];
};
struct __attribute__ ((__packed__)) sdshdr64 {
    uint64_t len; /* used */
    uint64_t alloc; /* excluding the header and null terminator */
    unsigned char flags; /* 3 lsb of type, 5 unused bits */
    char buf[];
};

例如,一个包含字符串“name”的sds结构如下:

image-20230612224408882

动态扩容

SDS之所以叫做动态字符串,是因为它具备动态扩容的能力。

例如一个内容为“hi”的SDS:

image-20230612224743814

此时要给SDS追加一段字符串“,Amy”,这里空间不够首先会申请新内存空间:

动态扩容分以下两种情况:

  1. 如果新字符串小于1M,则新空间为扩展后字符串长度的两倍+1
  2. 如果新字符串大于1M,则新空间为扩展后字符串长度+1M+1。称为内存预分配

(实际使用内存比真实分配内存小一些)

为什么要这么做?申请内存这个动作非常消耗资源(用户态和内核态之间切换)预分配提高性能

扩容后变成这样:

image-20230612225157106

(alloc长度不包含’\0’)

优点

① 获取字符串长度的时间复杂度为O(1) (len值)

② 支持动态扩容

③ 减少内存分配次数(内存预分配)

④ 二进制安全(无需考虑结束标识符’\0’影响)

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

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

相关文章

面向对象的封装

9. 面向对象特征一:封装性(encapsulation) 什么是封装 就像快递一样我们在网上买的物品,快递都会给我们添加外包装,给我们封装起来,这就是封装 客观世界里每一个事物的内部信息都隐藏在其内部,外界无法直接操作和修改…

怎样才算一个计算机知识体系完整的毕业生

为什么突然想写这个话题呢? 最近有不少新关注的读者,在后台问:大学学 Java 和 C 哪个好找工作,学前端好还是后端好,该学 Vue 还是 React。。。 仿佛看到了自己当年的模样,所以觉得有必要单独写一篇文章&a…

CSS基础学习--8 盒子模型(Box Model)

一、介绍 所有HTML元素可以看作盒子,在CSS中,"box model"这一术语是用来设计和布局时使用。 CSS盒模型本质上是一个盒子,封装周围的HTML元素,它包括:边距,边框,填充,和实…

调用阿里API实现图片中的文字识别

作者介绍 王雪玉,女,西安工程大学电子信息学院,2022级研究生 研究方向:机器视觉与人工智能 电子邮件:2239580540qq.com 王泽宇,男,西安工程大学电子信息学院,2022级研究生&#xf…

网规例题(二)

解题思路: 1.发送150000字节大小IP报文 数据帧长1518字节 首部18字节 可用数据1500字节 因此需要发送 100个数据帧 1518字节 1518*8 bit 带宽10 Mb/s 10 000 000 bps (一)发送100个数据帧的发送时延 0.12144 秒 (二&#…

Java程序员不得不知道的一些设计模式

1、什么是设计模式 设计模式(Design pattern)是一套被反复使用、多数人知晓的、经过分类编目的、代码设计经验的总结。使用设计模式是为了可重用代码、让代码更容易被他人理解、保证代码可靠性。 毫无疑问,设计模式于己于他人于系统都是多赢…

【arXiv2303】Learning with Explicit Shape Priors for Medical Image Segmentation

Learning with Explicit Shape Priors for Medical Image Segmentation, aXiv2303 解读:SPM: 一种即插即用的形状先验模块,可轻松嵌入任意编解码架构,助力涨点并显著改善分割效果! (qq.com) 论文:https://arxiv.org/…

基于Air103的DAP-link的硬件介绍

原文及固件链接 视频介绍链接 xkb7070-z 自锁式按键 上电开关 WAFER-SH1.0-6PWB 1.0间距卧贴插座 下载及通信接口 A2-4PA-2.54DS 4Pin接插件 纯下载接口 Air32F103CBT6 lqfp48 216MHz 256K Flash 32K RAM UD/UD- DP&DM信号 USB的差信号 R1 DIO监听 限流 PM254-2-04-W…

【3DsMAX】从零开始建房(7)

目录 1. 制作屋顶小船剩余部分 2. 制作小广告牌 1. 制作屋顶小船剩余部分 新建一个平面 长度分段设置为1 转换成可编辑多边形后,对边进行缩放 同样的方法再添加一个平面 添加“壳” 新建一个圆柱体作为桅杆 选中圆柱的底面,点击插入 挤出 将顶部的点缩…

深入理解深度学习——Transformer:编码器(Encoder)部分

分类目录:《深入理解深度学习》总目录 Transformer中的编码器不止一个,而是由一组 N N N个编码器串联而成。一个编码器的输出作为下一个编码器的输入。在下图中有 N N N个编码器,每一个编码器都从下方接收数据,再输出给上方。以此…

7年测试经验之谈,什么是模糊测试?

背景:近年来,随着信息技术的发展,各种新型自动化测试技术如雨后春笋般出现。其中,模糊测试(fuzz testing)技术开始受到行业关注,它尤其适用于发现未知的、隐蔽性较强的底层缺陷。这里&#xff0…

类的多继承的派生类的虚表的一些问题

虚表保存的其实并不是虚函数的地址,而是他的到jmp地址。 上我们的操作代码 class A { public:virtual void func1(){}virtual void func2(){}int a 1; };class B { public:virtual void func1(){}virtual void func2(){}int b 2; };class C : public A, public …

SAP HANA内存

用着用着HANA 数据库就慢了,原因都出在内存。 内存不足无非几个原因: 1.你的机器物理内存不足,这个好办,花钱扩。 2.你的HANA License容量不足,这个也好办,申请更大容量的内存License 3.你机器分配给HAN…

爬虫案例-使用Session登录指定网站(JS逆向AES-CBC加密+MD5加密)

总体概览:使用Session登录该网站,其中包括对password参数进行js逆向破解 (涉及加密:md5加密AES-CBC加密) 难度:两颗星 目标网址:aHR0cHM6Ly93d3cuZnhiYW9nYW8uY29tLw 下面文章将分为四个部分…

在后大流行时代利用Airbnb实现逆周期增长

回望近十年共享经济的发展历程,谁也不曾想到,最被看好的共享经济代表Uber竟在连年亏损后忍痛IPO,上市首日即破发,而主打「互联网房地产」模式的独角兽WeWork则上市失败,迅速失血,一度走到破产边缘。作为“共…

模型剪枝:Network Slimming剪枝实战

本文来自公众号“AI大道理” ​ Network Slimming剪枝是比较广泛的一种模型剪枝方法,作者来自清华大学、英特尔中国实验室、复旦大学和科内尔大学。 1、Network Slimming剪枝理论 Network Slimming剪枝是结构性剪枝,是通道剪枝,是静态剪枝…

mac安装hive_20230609

竟然是今年第一篇 hhhh 过两天把上半年的东西梳理好的话 陆续放上来吧~ 公司本地测试环境的hive版本不支持不等式关联操作,而现在用hive也比较多,所以在本地装了一个hive,主要写一下大致步骤和过程中遇到的问题~&#…

win10任务栏卡死解决

现象: win10 更新后,开机任务栏卡死,点开始反应,设置页面无法打开。 原因: 原因是Win10更新的任务栏资讯和兴趣,而资讯和兴趣是Edge浏览器的,该服务器是在国外,国内的网络加载不出来…

【lvs集群】HAProxy搭建Web集群

HAProxy搭建Web集群 一、 HAProxy简介1.1HAProxy主要特性1.2HAProxy负载均衡策略非常多,常见的有如下8种1.3LVS、Nginx、HAproxy的区别1.4常见的Web集群调度器 二、Haproxy搭建 Web 群集haproxy服务器部署节点服务器部署 三、定义监控页面与定义日志3.1定义监控页面…

stm32f103最小系统板详细介绍

一.什么是单片机最小系统 常见的单片机最小系统为单片机能独立运行程序及控制外围电路的最简单电路,主要由单片机、晶振电路、复位电路三部分构成。Stm32f103c8t6也不例外,构成最小的运行电路也需要以上三部分。 Stm32f103最小系统板原理图如下&#xf…