簡單動態字符串
SDS的定義
struct sdshdr{
int len; //記錄buf中已經使用字節的數量 不包括'\0'
int free; //記錄buf中未使用字節的數量
char buf[]; //字節數組,用於保存字符串,會設置數據的末尾爲‘\0' 這樣可以兼容部分c標準庫函數
};
![在這裏插入圖片描述](https://img-blog.csdnimg.cn/20190603233257284.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L20wXzM3MjMyMjI4,size_16,color_FFFFFF,t_70)
SDS較C字符串的優勢 例:struct sdshdr *s
1.計算長度
可以o(1)時間複雜度獲取長度 s->len
2.緩衝區溢出:
c的strcat(char *dest,const char*src)拼接函數在拼接時可能會覆蓋相鄰字符串,當src+dest長度大於dest分配空間,將會產生緩衝區溢出;
對於sds,它在拼接的時候會校驗所需空間是否大於s->free的空間,如果大於纔會進行空間的分配,這樣可以減少內存分配;
3.二進制安全:
SDS的API都是二進制安全的,它的API都是以二進制的方式進行出行SDS的buf數組的數據的;
4.兼容部分c字符串函數:
SDS總會在數據的末尾(中間可以有n個'\0')設置爲空字符,與C字符串以空字符串結尾的相似,所以可以沿用部分c的字符串函數;
空間分配策略
它的空間預分配規則可以減少內存分配次數:
當拼接增加sds之後,s->len大小小於1MB,那麼將會分配給s->free相同的字節,例如拼接之後s->len長度爲150,則s->free也爲150;
當拼接之後的s->len長度大於1MB,則爲s->free分配1MB的大小 ;
它的惰性空間釋放:
惰性空間釋放用於優化 SDS 的字符串縮短操作: 當 SDS 的 API 需要縮短 SDS 保存的字符串時, 程序並不立即使用內存重分配來回收縮短後多出來的字節, 而是使用 free 屬性將這些字節的數量記錄起來, 並等待將來使用。redis提供API在有需要的時候,真正釋放未使用空間,所以不用擔心內存泄漏;
API:sdstrim(s, "XY"); // 移除 SDS 字符串中的所有 'X' 和 'Y'
![在這裏插入圖片描述](https://img-blog.csdnimg.cn/20190603232321382.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L20wXzM3MjMyMjI4,size_16,color_FFFFFF,t_70)
![在這裏插入圖片描述](https://img-blog.csdnimg.cn/20190603232415368.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L20wXzM3MjMyMjI4,size_16,color_FFFFFF,t_70)