简单动态字符串

Redis只在一些无需对字符串进行修改的地方使用C字符串,大部分时候使用简单动态字符串simple dynamic string, SDS),字符串的抽象类型。二进制安全,可以存放任意格式的数据。

定义

 源码(部分):
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 sdshdr {
int len;
int free;
char buf[];
}

这里以书中代码为基础,len为使用的字节数,free表示已分配但未使用的字节数。buf就是char型数组保存字符串。

这里需要注意的是SDS保存的字符串沿用C字符串的格式,会在最末尾加一个'\0'表示字符串结束,好处是可以复用C语言的函数库。

举个例子:“hello” len为5,如果free为0,那么这个字符串一共使用6字节,'\0'额外使用一个字节。

由定义我们可以了解到,SDS的长度可以O(1)获得,而且他使用的内存不是长度+1。而且具有二进制安全的性质。

空间分配策略

Redis为了减少内存分配的次数,采用了空间预分配惰性空间释放两种策略。

空间预分配

当需要对SDS进行空间扩展的时候,SDS不仅会分配修改所必须的空间,还会进行预分配。

如果修改后的len值小于1M,那么就会预分配和len同样大小的预留空间。也就是说经过修改和预分配len和free的值是相等的。这时候占有的字节数就是len+free+1。

而如果修改后的len值大于等于1M,那么就只预分配1M空间。

惰性空间释放

当API需要缩短SDS保存的字符串,并不会立即释放多出来的字节,而是使用free记录下来。这样避免了内存重分配的操作,并为将来可能的增长提供了优化。

如果确实需要释放未使用的空间,SDS也提供了相应的API。

优点总结

  • 常数时间复杂度获取字符串长度
  • 杜绝缓冲区溢出
  • 减少在修改字符串长度时内存分配的次数
  • 二进制安全
  • 兼容部分C字符串函数

《Redis设计与实现》阅读笔记(二)--简单动态字符串的更多相关文章

  1. redis 学习笔记二 (简单动态字符串)

    redis的基本数据结构是动态数组 一.c语言动态数组 先看下一般的动态数组结构 struct MyData { int nLen; char data[0]; }; 这是个广泛使用的常见技巧,常用来 ...

  2. redis设计与实现(一)简单动态字符串

    redis是C语言实现的,但redis中的字符串并没有直接用C语言中的字符串表示,而是自己构建了一种简单的动态字符串类型(SDS). 在redis里面,C字符串只用作字面量,用在一些不会修改的地方,e ...

  3. redis 笔记01 简单动态字符串、链表、字典、跳跃表、整数集合、压缩列表

    文中内容摘自<redis设计与实现> 简单动态字符串 1. Redis只会使用C字符串作为字面量,在大多数情况下,Redis使用SDS(Simple Dynamic String,简单动态 ...

  4. Redis底层探秘(一):简单动态字符串(SDS)

    redis是我们使用非常多的一种缓存技术,他的性能极高,读的速度是110000次/s,写的速度是81000次/s.这么高的性能背后,到底是怎么样的实现在支撑,这个系列的文章,我们一起去看看. redi ...

  5. Redis数据类型之SDS简单动态字符串

    一,简单的动态字符串 1,Redis自己构建了一种名为简单动态字符串的抽象类型,并将SDS用作Redis的默认字符串表示, 2,在redis的数据库里面,包含字符串值的键值对在底层都是由SDS实现的 ...

  6. Redis设计与实现读书笔记——简单动态字符串

    前言 项目里用到了redis数据结构,不想只是简单的调用api,这里对我的读书笔记做一下记录.原文地址: http://www.redisbook.com/en/latest/internal-dat ...

  7. [redis读书笔记] 第一部分 数据结构与对象 简单动态字符串

    本读书笔记主要来自于<<redis设计与实现>> -- 黄键宏(huangz) redis主要设计了字符串,链表,字典,跳跃表,整数集合,压缩列表来做为基本的数据结构,实现键值 ...

  8. Html学习笔记(二) 简单标签

    标签的重点 标签的用途 标签在浏览器中的默认样式 <body>标签: 在网页上显示的内容 <p>标签: 添加段落 <hx>标签: 添加标题 标签一共有6个,h1.h ...

  9. Redis5设计与源码分析读后感(二)简单动态字符串SDS

    一.引言 学习之前先了解几个概念: SDS定义:简单动态字符串,Redis的基本数据结构之一,用于储存字符串和整型数据. 二进制安全:C语言中用"\0"表示字符串结束,如果字符串本 ...

随机推荐

  1. debian 7上安装svn

    1.在终端中直接输入  sudo apt-get install subversion,选择安装即可 2.查看版本命令 svnserve --version(更多命令直接键入svnserve --he ...

  2. POJ3977 Subset

    嘟嘟嘟 这个数据范围显然是折半搜索. 把序列分成两半,枚举前一半的子集,存下来.然后再枚举后一半的子集,二分查找. 细节: 1.最优解可能只在一半的子集里,所以枚举的时候也要更新答案. 2.对于当前结 ...

  3. 深入理解C/C++混合编程优秀博文赏析与学习

    1.深入理解C/C++混合编程 2.C/C++ 混合编程 互相调用 3.C代码中如何调用C++ C++中如何调用C 4.C和C++混合编程

  4. idea 如何优雅的添加.ignore 忽略不必要提交的文件

    最近有点时间然后就跑去搜了下idea热门的插件,一不小心发现了一个.ignore插件.有过在idea使用git都知道.gitignore文件,而这个插件就是能优雅的帮我们做这件事. 首先先讲下安装这个 ...

  5. Spring源码分析(二)容器基本用法

    摘要:本文结合<Spring源码深度解析>来分析Spring 5.0.6版本的源代码.若有描述错误之处,欢迎指正. 在正式分析Spring源码之前,我们有必要先来回顾一下Spring中最简 ...

  6. 【敏捷实用工具】JIRA介绍以及使用方法

    敏捷开发并不是由敏捷工具来推动的.但是没有敏捷工具的支持,就很难进行各种软件工程的相关事件,工具的作用是约束和流程,正确使用敏捷工具可以事半功倍,实践敏捷.近几年来敏捷开发催生大量敏捷工具的产生,在敏 ...

  7. Linux学习笔记(第九章)

    压缩概念: gzip和zcat: 先进版bzip2,bzcat bzip -d  已压缩文档名 bzip -z 需压缩文档名 bzcat 解压文档打印到屏幕 tar:打包指令 注意:压缩最好拿掉根目录 ...

  8. MAC mojave版本系统 破解软件

    MAC mojave版本系统 破解软件 1 :Adobe Photoshop CC 2019.0.1 Mac中文破解版 2 :Office 2019 16.19 Mac中文破解版 3 :Paralle ...

  9. mac php项目除了首页全飘not found

    1.httpd.conf配置文件中加载了mod_rewrite.so模块2.AllowOverride None 将None改为 All DocumentRoot "/Library/Web ...

  10. 定心丸!ZipperDown漏洞分析与修复建议

    本文由  网易云发布. 近日,盘古实验室对外披露了ZipperDown漏洞,该漏洞是盘古团队针对不同客户的iOS应用安全审计的过程中发现的,大约有10%的iOS应用会受到此漏洞的影响. 利用此漏洞可以 ...