简单动态字符串(SDS)
SDS
前提:在redis中,C字符串只会作为字符串字面量用在一些无须对字符串进行修改的地方,比如打印日志:
redisLog(REDIS_WARNING, “Redis is ready to exit”)
因此,redis构建了一种简单动态字符串(simple dynamic string, SDS)的抽象类型,并将SDS用作redis的默认字符串表示。
比如:
redis> SET msg “Hello World”
OK
其中键值对的键是一个字符串对象,对象底层是一个保存着字符串 ”msg” 的SDS。
键值对的值也是一个字符串对象,对象底层是一个保存着字符串 “Hello World” 的SDS。
SDS的用途总结:
- 保存数据库中的字符串值
- 用作缓冲区(buffer)
- AOF模块中的AOF缓冲区
- 客户端状态中的输入缓冲区
下面给出SDS的结构:
struct SDS {
int len; // buf数组中已使用字节数,并未算上’\0’字符
int free; // buf数组中未使用字节数
char buf[]; // 用于保存字符串
};
SDS与C字符串的区别
1. O(1)复杂度获取字符串的长度。这个就不需要解释了。
2. 杜绝缓冲区溢出。比如在使用strcat函数时,在这有个扩充知识要讲,即变量在内存中是如何存储的。
C++将进程内存分为(地址由高到低):栈、堆、BSS(Block Start of Symbol)段,数据段,代码段。其中栈是用来存储局部变量、函数参数和返回地址的,在VS中,栈是由高到低分配内存的(很重要!因为它最特殊0.0);堆是存储动态分配内存的变量的地方,如new和malloc函数就是在这分配内存的;BSS段是用来分配未初始化或初始化为0的全局变量和静态变量;数据段是用来存储初始化值不为0的全局变量和静态变量。代码段则是用来存储代码、静态只读数据的地方。
Ok,有了上面的基础后,让我们来做个实验巩固一下上面的内容。
char s1[] = "Hello";
printf("%p %p\n", s1, &s1[1]);
char *s2 = new char[6];
s2 = "World";
printf("%p %p\n", s2, &s2[1]);

可以明显地看到,局部变量s1和s2的地址区别,由于s2的内存是动态分配的,故其地址值小于s1。此外,我们可以看到,s1字符串在栈中是怎么放置的,起始地址为低地址,说明(低地址->高地址)H->e->l->l->o。
ok,这很明显了,如果我们将s2拼接到s1后面,会发生什么?
由于s1的最后一个字符是在栈顶,那么在拼接后,会返回栈越界错误!这也是strcat函数不安全的地方!而SDS在拼接字符串时,会考虑有没有足够的空间(free字段的用处出现了),具体细节后面再讲,先填坑先orz…
// 这里是全局变量
int a;
int aa = 0;
int b = 1;
const int con = 0; // 常量
// 到这为止
printf("%p %p\n", &a, &aa);
printf("%p\n", &b);
printf("%p\n", &con);

可以看出,全局变量a,aa,b之间的区别,是不是和我们上面说的一毛一样!当然,常量也是!
到这就可以C++的内存就介绍完了。让我们继续介绍SDS和C字符串的区别吧(汗)
3. 减少修改字符串时带来的内存重新分配次数。SDS通过未使用空间解除了字符串长度和底层数组长度的关联。(因为SDS的buf数组长度是len+free+1(别忘了’\0’哦)。比如说在剪切字符串时,SDS并不会释放剪切的内存空间,而是增大free。
简单动态字符串(SDS)的更多相关文章
- 图解Redis之数据结构篇——简单动态字符串SDS
图解Redis之数据结构篇--简单动态字符串SDS 前言 相信用过Redis的人都知道,Redis提供了一个逻辑上的对象系统构建了一个键值对数据库以供客户端用户使用.这个对象系统包括字符串对象 ...
- Redis底层探秘(一):简单动态字符串(SDS)
redis是我们使用非常多的一种缓存技术,他的性能极高,读的速度是110000次/s,写的速度是81000次/s.这么高的性能背后,到底是怎么样的实现在支撑,这个系列的文章,我们一起去看看. redi ...
- Redis数据结构之简单动态字符串SDS
Redis的底层数据结构非常多,其中包括SDS.ZipList.SkipList.LinkedList.HashTable.Intset等.如果你对Redis的理解还只停留在get.set的水平的话, ...
- redis 系列3 数据结构之简单动态字符串 SDS
一. SDS概述 Redis 没有直接使用C语言传统的字符串表示,而是自己构建了一种名为简单动态字符串(simple dynamic string, SDS)的抽象类型,并将SDS用作Redis的默 ...
- Redis源码解析:01简单动态字符串SDS
Redis没有直接使用C字符串(以'\0'结尾的字符数组),而是构建了一种名为简单动态字符串( simple dynamic string, SDS)的抽象类型,并将SDS用作Redis的默认字符 ...
- Redis5设计与源码分析读后感(二)简单动态字符串SDS
一.引言 学习之前先了解几个概念: SDS定义:简单动态字符串,Redis的基本数据结构之一,用于储存字符串和整型数据. 二进制安全:C语言中用"\0"表示字符串结束,如果字符串本 ...
- Redis核心原理-简单动态字符串SDS
SDS简介 Redis是C语言编写的,但没有使用c语言的字符串结构,而是自己实现了一套简单动态字符串 simple dynamic string 简称SDS,SDS兼容C语言的字符串类型,原理类似Ja ...
- 深入理解Redis 数据结构—简单动态字符串sds
Redis是用ANSI C语言编写的,它是一个高性能的key-value数据库,它可以作用在数据库.缓存和消息中间件.其中 Redis 键值对中的键都是 string 类型,而键值对中的值也是有 st ...
- 【Redis】简单动态字符串SDS
C语言字符串 char *str = "redis"; // 可以不显式的添加\0,由编译器添加 char *str = "redis\0"; // 也可以添加 ...
- Redis 数据结构之简单动态字符串SDS
几个概念1:key对象 数据库存储键值对的键,总是一个字符串对象.2:value对象 数据库存储键值对的值,可以是字符串对象,list对象,hash对象,set对象,sorted set对象. ...
随机推荐
- 【故障公告】阿里云 RDS 数据库服务器 CPU 100% 造成全站故障
非常非常抱歉,今晚 19:34 ~ 21:16 园子所使用的阿里云 RDS 数据库服务器突然出现 CPU 100% 问题,造成全站无法正常访问,由此您带来了很大的麻烦,请您谅解. 故障经过是这样的.1 ...
- odoo 恢复数据库前端报错
Could not get content for…… jQuery is not defined 原因:数据库缓存 解决方法: select id, create_date, store_fname ...
- codeforces 879 D. Teams Formation(思维)
题目链接:http://codeforces.com/contest/879/problem/D 题意:这题题意我反正是看了很久,可能是我的理解能力有点差,就是将一个数组倍增m倍然后将连续的相同的k个 ...
- Codeforces Round #483 (Div. 2) B. Minesweeper
题目地址:http://codeforces.com/contest/984/problem/B 题目大意:扫雷游戏,给你一个n*m的地图,如果有炸弹,旁边的八个位置都会+1,问这幅图是不是正确的. ...
- 让docker中的mysql启动时自动执行sql
在用docker创建mysql容器的时,有时候我们期望容器启动后数据库和表已经自动建好,初始化数据也已自动录入,也就是说容器启动后我们就能直接连上容器中的数据库,使用其中的数据了. 其实mysql的官 ...
- win10 解决端口被占用
查看端口 netstat -aon|findstr "端口" 通过PID查找应用程序 tasklist|findstr "PID" 关闭进程 taskkill ...
- String字符串关于==的详解
String详解 字符创建方式 字符串创建有两种方式 String s = new String("myString"); String string2 = "myStr ...
- android- 对话框中弹出edittext 不能调出输入法
最近项目中用到 dialog弹出对话框功能, 弹出后输入 密码, 本以为这是一个很简单问题,但是做好发现Edittext 无法调出输入法. 解决方法,我也是百度找到的 . 记录一下,便于下次使用: f ...
- android中fragment与activity之间通信原理以及例子
参考文章 http://blog.csdn.net/guozh/article/details/25327685#comments Activity和fragment通信方式一般有3种方法 1.在fr ...
- StateListDrawable资源的使用
StateListDrawable用于组织多个Drawable对象,当使用StateListDrawable作为目标组件的 背景和前景图片时,StateListDrawable对象所显示的Drawab ...