您的位置:首页 > 数据库 > Redis

【redis学习笔记-01-基础篇】-02-简单动态字符串

2019-06-07 21:37 316 查看
版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/fengyu6623/article/details/91152786

redis中的字符串不同于C语言的字符串,C语言的字符串是以'\0'空字符作为结束符的字符数组,而redis中的字符串是redis自己构建的一种名为简单动态字符串(SDS)的抽象结构体。

SDS是一个带有长度信息的字节数组。

数据存放在content数组中,capacity是其数组容量,表示当前数组的总长度。len为数组的实际长度,表示当前字符串占用的实际长度。

C语言的字符串本身不记录长度,必须遍历整个字符串才能对其计数,这个操作的复杂度为O(N)。而SDS因为有len,所以其获取字符串长度的时间复杂度为O(1)。

SDS的字符串append的过程,在拼接字符串之前,redis会先检查capacity容量是否足够,如果不够先进行扩容。所以SDS的字符扩容不会发生缓存区溢出的问题。

SDS中的空间预分配是指其字节数组结构会预先多分配一段空间,以此来避免像C字符串中需要频繁内存重分配的缺陷。

redis字符串最大长度不超过512MB,字符串创建时len和capacity一样长,不会分配多余的空间,因为大多数情况下,redis认为我们是不会使用append来操作字符串。

字符串长度小于1MB时,字节数组每次扩容都是采用加倍策略,即对SDS修改后,SDS的长度小于1MB,那此时capacity的容量大小会是修改后len长度的两倍。而当字符串长度超过1MB后,为了避免加倍后造成空间的浪费,从而每次扩容只会最多分配1MB的冗余空间。

SDS采用惰性释放空间策略,用于优化字符串缩短的操作。当SDS的字符串被缩短时,redis并不会立即重分配内存来回收这部分多出来的字节,而是通过len和capacity来记录,并等待将来重复利用。当然并不需要担心惰性释放会造成空间浪费,其依然会在合适的时候对其真正释放。

为了复用C语言库中字符串的一些函数,redis同样会在字节数组后面自动的添加了一个空字符'\0',所以content的总是会多分配一个字节来容纳这个空字符,但是整个字节长度不会记录到len和capacity中。

对比C字符串其只能保存某种字符编码的字符,且除了末尾的空字符外,其余地方不能包含空字符。redis的SDS保存的是任意格式的二进制数组,所以SDS是二进制安全的,其内部都是以处理二进制的方式来处理数组中数据。

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: