Redis采用简单动态字符串(简称SDS)
在了解SDS之前,我们先来了解一下C语言的字符串
C语言使用长度为N+1的字符串来表示长度为N的字符串,第N+1位存储空字符
C语言字符串有一些问题,比如要获取字符串的长度时,程序必须遍历整个字符串,对每个字符进行计数,计算复杂度为O(N),而SDS在len属性中记录了长度,计算复杂度为O(1)
C语言字符串增加时必须要手动分配空间后,才能增加,否则容易导致内存溢出
C语言字符串减少时必须要手动释放空间后,才能减少,否则容易导致内存泄漏
而SDS增加未使用空间,记录在free属性中,实现空间预分配和惰性空间释放策略
SDS结构
SDS的空间预分配:
当SDS增加时,程序先检查未使用空间是否足够,如果足够则直接使用未使用空间
SDS的空间预分配策略:
当SDS大小不超过1M时,程序将分配和len相同长度的未使用空间
当SDS大小超过1M时,程序将分配1M的未使用空间
SDS的惰性空间释放:
当SDS减少时,程序并不立即使用内存重新分配来回收多出的长度,而是将它们记录在free中,以此减少修改字符串长度时所需的内存重分配次数
C语言字符串中的字符必须符合某种编码,并且除了字符串的尾部之外,字符串里面不能包含空字符,否则最先被读取的空字符将被误认为是字符串的结尾,这些限制使得C字符串只能保存文本数据,而不能保存像图片,音频,视频,压缩文件这样的二进制数据。
而SDS都会以处理二进制的方式来处理SDS存放在buf数组里的数据,程序不会对数据有任何限制,过滤或者假设,数据写入是什么样的,读出就是什么样的
总结:SDS优点
-常数复杂度获得字符串长度
-杜绝缓冲区溢出
-减少修改字符串长度时所需的内存重分配次数
-二进制安全