redis数据结构-SDS

参考:http://redisbook.com/preview/sds/different_between_sds_and_c_string.html

Redis 只会使用 C 字符串作为字面量, 在大多数情况下, Redis 使用 SDS (Simple Dynamic String,简单动态字符串)作为字符串表示。

比起 C 字符串, SDS 具有以下优点:

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

C 字符串和 SDS 之间的区别

C 字符串 SDS
获取字符串长度的复杂度为 O(N) 。 获取字符串长度的复杂度为 O(1) 。
API 是不安全的,可能会造成缓冲区溢出。 API 是安全的,不会造成缓冲区溢出。
修改字符串长度 N 次必然需要执行 N 次内存重分配。 修改字符串长度 N 次最多需要执行 N 次内存重分配。
只能保存文本数据。 可以保存文本或者二进制数据。
可以使用所有 <string.h> 库中的函数。 可以使用一部分 <string.h> 库中的函数。

1、为啥可以使用部分string.h里面的函数?

遵循 C 字符串以空字符结尾的惯例, SDS 可以在有需要时重用 <string.h> 函数库, 从而避免了不必要的代码重复。

2、SDS获取字符串长度为啥O(1)?

通过len字段存储buf的长度,更新sds的时候自动更新记录,获取长度直接读取len的大小

3、为什么API 是安全的,不会造成缓冲区溢出?

比如strcat拼接字符串的时候,通过SDS->free长度记录剩余空间,如果不够会分配空间,再写入

4、修改字符串长度 N 次最多需要执行 N 次内存重分配。空间分配策略是什么样的?

空间预分配:长度小于1m,比如13k,直接预分配free=13k的空间,时间空间=len+buf+1bytes;长度大于1m,预分配free=1m,实际空间=len+1m+1bytes;

惰性空间释放:减少字符串后,不会立马释放空间,记录到free字段,并等待将来使用。等定时器定时检测和释放空间?

5、为什么是二进制安全?

以len的长度作为结尾,不是空字符串\0作为结尾,所以可以存储二进制数据

猜你喜欢

转载自www.cnblogs.com/albert32/p/13372734.html