Redis入门到通关之数据结构解析-动态字符串SDS

文章目录

  • Redis数据结构-动态字符串
  • 动态扩容举例
  • 二进制安全
  • SDS优点
  • 与C语言中的字符串的区别



在这里插入图片描述



Redis数据结构-动态字符串

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

不过 Redis 没有直接使用C语言中的字符串,因为C语言字符串存在很多问题:

  • 获取字符串长度的需要通过运算

  • 非二进制安全

  • 不可修改

Redis 构建了一种新的字符串结构,称为简单动态字符串(Simple Dynamic String),简称 SDS
例如,我们执行命令:

set name 技术

那么 Redis 将在底层创建两个 SDS,其中一个是包含“name”的 SDS,另一个是包含“技术”的 SDS。

Redis 是 C 语言实现的,其中 SDS 是一个结构体,源码如下:

在这里插入图片描述

#include <stdio.h>
#include <stdlib.h>
#include <string.h>typedef struct sds {int len;         // 记录字符串的长度int free;        // 记录未使用的字节数char buf[];      // 字符串的实际存储空间
} sds;// 创建一个新的 sds
sds *sds_new(int init_len) {sds *s = malloc(sizeof(sds) + init_len + 1);if (!s) return NULL;s->len = 0;s->free = init_len;s->buf[0] = '\0';return s;
}// 释放 sds
void sds_free(sds *s) {if (s) free(s);
}// 追加字符串到 sds
sds *sds_append(sds *s, const char *append) {int append_len = strlen(append);if (s->free < append_len) {s = realloc(s, sizeof(sds) + s->len + append_len + 1);if (!s) return NULL;s->free = append_len;}memcpy(s->buf + s->len, append, append_len);s->len += append_len;s->free -= append_len;s->buf[s->len] = '\0';return s;
}// 打印 sds
void sds_print(const sds *s) {printf("Length: %d\n", s->len);printf("Free: %d\n", s->free);printf("String: %s\n", s->buf);
}int main() {sds *str = sds_new(10);if (!str) {printf("Error: Unable to create SDS.\n");return 1;}str = sds_append(str, "Hello, ");if (!str) {printf("Error: Unable to append to SDS.\n");return 1;}str = sds_append(str, "world!");if (!str) {printf("Error: Unable to append to SDS.\n");return 1;}sds_print(str);sds_free(str);return 0;
}

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

在这里插入图片描述


动态扩容举例

SDS 之所以叫做动态字符串,是因为它具备动态扩容的能力,例如一个内容为“hi”的SDS:

在这里插入图片描述

假如我们要给SDS追加一段字符串“,Amy”,这里首先会申请新内存空间:

  • 如果新字符串小于1M,则新空间为扩展后字符串长度的两倍+1;

  • 如果新字符串大于1M,则新空间为扩展后字符串长度+1M+1。称为内存预分配
    在这里插入图片描述

二进制安全

  • Redis 可以存储各种数据类型,那么二进制数据肯定也不例外。但二进制数据并不是规则的字符串格式,可能会包含一些特殊的字符,比如 ‘\0’ 等。
  • 前面我们提到过,C 中字符串遇到 ‘\0’ 会结束,那 ‘\0’ 之后的数据就读取不上了。但在 SDS 中,是根据 len 长度来判断字符串结束的。
  • 如此, 二进制安全的问题就解决了。

SDS优点

SDS 优点:

  1. 获取字符串长度的时间复杂度为O(1)
  2. 支持动态扩容, 减少内存分配次数
  3. 二进制安全

与C语言中的字符串的区别

SDS(Simple Dynamic String)是Redis使用的一种字符串表示方式,与C语言中的字符串有一些显著的区别:

  • 动态调整大小:SDS是动态分配内存的,可以根据需要动态增加或减少其大小,而C语言中的字符串通常是静态分配的,大小在创建时就确定了,后续无法直接调整大小。

  • 二进制安全:SDS允许存储任意二进制数据,而C语言中的字符串通常以NULL结尾,因此不适合存储包含NULL字符的二进制数据。

  • 惰性空间释放:SDS采用惰性空间释放策略,即当SDS的内容被截断或缩短时,并不立即释放多余的内存,而是等待下一次需要扩展空间时才释放。这种策略可以减少频繁的内存分配和释放操作,提高性能。而C语言中的字符串在缩短时无法自动释放多余的内存,需要手动管理内存。

  • 长度存储:SDS在内部存储了字符串的长度信息,这样可以在O(1)时间内获取字符串的长度,而C语言中的字符串需要遍历整个字符串才能确定长度。

SDS是一种更加灵活和高效的字符串表示方式,特别适合需要频繁修改和操作字符串的场景,而C语言中的字符串更适合于静态不变的情况。


在这里插入图片描述


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

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

相关文章

Android Studio超级详细讲解下载、安装配置教程(建议收藏)

博主介绍&#xff1a;✌专注于前后端、机器学习、人工智能应用领域开发的优质创作者、秉着互联网精神开源贡献精神&#xff0c;答疑解惑、坚持优质作品共享。本人是掘金/腾讯云/阿里云等平台优质作者、擅长前后端项目开发和毕业项目实战&#xff0c;深受全网粉丝喜爱与支持✌有…

ES是什么?ES的使用场景有哪些?分词器??

一、ES是什么&#xff1f;&#xff1f;&#xff1f; 1、Elasticsearch 是一个基于 Apache Lucene 构建的开源分布式搜索引擎和分析引擎。同时还可以被视为一种特殊的数据库&#xff0c;具体而言&#xff0c;它是一种分布式、面向文档的NoSQL数据库&#xff0c;专为全文搜索和数…

贪吃蛇游戏实现(VS编译环境)

贪吃蛇游戏 &#x1f955;个人主页&#xff1a;开敲&#x1f349; &#x1f525;所属专栏&#xff1a;C语言&#x1f353; &#x1f33c;文章目录&#x1f33c; 0. 前言 1. 游戏背景 2. 实现后游戏画面展示 3. 技术要求 4. Win32 API介绍 4.1 Win32 API 4.2 控制台程序 4.…

Java之类和对象

一面向对象的初步认知 1.什么是面向对象 Java是一门纯面向对象的语言(Object Oriented Program&#xff0c;简称OOP)&#xff0c;在面向对象的世界里&#xff0c;一切皆为对象。面向对象是解决问题的一种思想&#xff0c;主要依靠对象之间的交互完成一件事情。用面向对象的思想…

嵌入式物联网实战开发笔记-乐鑫ESP32开发环境ESP-IDF搭建【doc.yotill.com】

乐鑫ESP32入门到精通项目开发参考百例下载&#xff1a; 链接&#xff1a;百度网盘 请输入提取码 提取码&#xff1a;4e33 3.1 ESP-IDF 简介 ESP-IDF&#xff08;Espressif IoT Development Framework&#xff09;是乐鑫&#xff08;Espressif Systems&#xff09;为 ESP 系列…

如何用JS校验HTTP和HTTPS地址

在日常开发过程中&#xff0c;我们有时候对某些应用功能进行封装&#xff0c;但是在请求接口又不能写死&#xff0c;这个时候我们需要对他进行多方面考虑。 如何验证请求地址是HTTP还是HTTPS 方法一&#xff1a; function getBaseUrl (string) {let url;try {url new URL(s…

大型网站系统架构演化实例_2.使用缓存改善网站性能

1.使用缓存改善网站性能 网站访问的特点和现实世界的财富分配一样遵循二八定律&#xff1a;80%的业务访问集中在20%的数据上。既然大部分业务访问集中在一小部分数据上&#xff0c;那么如果把这一小部分数据缓存在内存中&#xff0c;就可以减少数据库的访问压力&#xf…

【Python】自定义修改pip下载模块默认的安装路径

因为电脑下载了Anaconda提供的默认Python 3.9 以及后期下载的python3.10所以在Pychram进行项目开发时&#xff0c;发现一些库怎么导入都导入不了&#xff0c;手动install也是失败&#xff0c;后期在cmd里面发现python以及pip配置有点儿混乱&#xff0c;导致执行命令时&#xff…

基于SpringCloudAlibaba+Sentinel的分布式限流设计

胡弦&#xff0c;视频号2023年度优秀创作者&#xff0c;互联网大厂P8技术专家&#xff0c;Spring Cloud Alibaba微服务架构实战派(上下册)和RocketMQ消息中间件实战派(上下册)的作者&#xff0c;资深架构师&#xff0c;技术负责人&#xff0c;极客时间训练营讲师&#xff0c;四…

碳循环、人类、遥感之间的关联

1. 碳与碳循环 碳是自然界中很常见的一种元素&#xff0c;它以多种形式广泛存在于大气和地壳之中。碳单质很早就被人认识和利用&#xff0c;碳的一系列化合物——有机物是生命的根本。 1.1 自然界中的碳 地球上最大的两个碳库是岩石圈和化石燃料&#xff0c;含碳量约占…

小米K8s运维-云原生方向(面经分享)

大家好&#xff0c;我是秋意零。今天分享一篇小米运维面经。 小米K8s运维-云原生方向 一面 2024年4月3日 | 10点 | 一面 | 40 min 左右 1&#xff09;自我介绍 2&#xff09;你熟悉Python多一点吗&#xff1f;还熟悉其它语言吗&#xff0c;拿出来写过的&#xff1f; 3&am…

搜索引擎中的倒排索引是什么

在搜索引擎领域&#xff0c;倒排索引是一种核心数据结构&#xff0c;它让搜索引擎能够以极高的效率找到包含用户查询关键词的所有网页。为了理解倒排索引的工作原理&#xff0c;我们可以将其与一种更直观、生活化的例子相比较&#xff1a;书店里的索引卡片系统。 假设你是一位…

在RISC-V64架构的CV1811C开发板上应用perf工具进行多线程程序性能分析及火焰图调试

CV1811C环境编译 SDK目录结构 . ├── build // 编译目录,存放编译脚本以及各board差异化配置 ├── buildroot-2021.05 // buildroot开源工具 ├── freertos // freertos系统 ├── fsbl // fsbl启动固件,prebuilt形式存在…

K8s: 集群内Pod通信机制之环境变量

集群内Pod通信机制之环境变量 Kubernetes 支持两种基本的服务发现模式 —— 环境变量和 DNS 1 &#xff09; 环境变量概述 在Service里面通过label selector选择器去匹配到对应的pod然后把流量导给对应的pod进行这个service的一个服务提供也就是说你只要访问service的IP地址…

Android14 - WindowManagerService之客户端Activity布局

Android14 - WindowManagerService之客户端Activity布局 一、主要角色 WMS作为一个服务端&#xff0c;有多种客户端与其交互的场景。我们以常见的Activity为例&#xff1a; Activity&#xff1a;在ActivityThread构建一个Activity后&#xff0c;会调用其attach方法&#xff0c;…

【PyTorch】2-主要组成模块(数据读入、模型构建、损失函数、评价指标、训练和测试、优化器)

PyTorch&#xff1a;2-主要组成模块 注&#xff1a;所有资料来源且归属于thorough-pytorch(https://datawhalechina.github.io/thorough-pytorch/)&#xff0c;下文仅为学习记录 2.1&#xff1a;深度学习的必要部分 机器学习步骤 【1】数据预处理 【2】划分train、valid、…

人工智能底层自行实现篇3——逻辑回归(上)

3. 逻辑回归 1. 简介 逻辑回归&#xff08;Logistic Regression&#xff09;是一种广泛应用于分类问题的统计方法&#xff0c;尤其是二分类问题。虽然它的名称中包含“回归”&#xff0c;但实际上逻辑回归是一个用于估计概率的分类模型。以下是关于逻辑回归的详细介绍&#x…

[docker] volume 补充 环境变量 参数

[docker] volume 补充 & 环境变量 & 参数 这里补充一下 volume 剩下的内容&#xff0c;以及添加参数(ARG) 和 环境变量 ENV 的内容 read only volumes ❯ docker run-p 3000:80--rm--name feedback-app-v feedback:/app/feedback-v "$(pwd):/app"-v /app/…

gcc头文件默认搜索路径

0. 一些小的注意点 #include <> 是系统搜索头文件 #include "" 是本地搜索路径 gcc -I /dir-to-path -I选项可以指定头文件搜索路径 1. 解决 可以使用cpp查看cpp搜索路径 cpp -v /dev/null -o /dev/null另外一种方法直接使用gcc gcc -print-prog-namecc1p…

【C++初阶】vector使用特性 vector模拟实现

1.vector的介绍及其使用 1.1 vector的介绍 vector文档介绍 1. vector是表示可变大小数组的序列容器。 2. 就像数组一样&#xff0c;vector也采用的连续存储空间来存储元素。也就是意味着可以采用下标对vector的元素进行访问&#xff0c;和数组一样高效。但是又不像数组&#…