sds (****** dynamic string,簡單動態字串)是 redis 底層所使用的字串表示。
sds 在 redis 中的主要作用有以下兩個:
實現字串物件(stringobject);
在 redis 程式內部用作char*
型別的替代品;
redis 是乙個鍵值對資料庫(key-value db), 資料庫的值可以是字串、集合、列表等多種型別的物件, 而資料庫的鍵則總是字串物件。
對於那些包含字串值的字串物件來說, 每個字串物件都包含乙個 sds 值。(在 redis 中, 乙個字串物件除了可以儲存字串值之外, 還可以儲存long
型別的值, 所以為了嚴謹起見, 這裡需要強調一下:
當字串物件儲存的是字串時, 它包含的才是 sds 值, 否則的話, 它就是乙個long
型別的值。)
在前面的內容中, 我們一直將 sds 作為一種抽象資料結構來說明, 實際上, 它的實現由以下兩部分組成:
typedefchar
*sds
;struct
sdshdr
;
其中,型別sds
是char
*的別名(alias),而結構sdshdr
則儲存了len
、free
和buf
三個屬性。
作為例子,以下是新建立的,同樣儲存hello
world字串的sdshdr
結構:
structsdshdr
;
被更新,字串"
again!"會被追加到原來的"hello
world"之後:
structsdshdr
sds.c/sdsmakeroomfor
函式描述了sdshdr
的這種記憶體預分配優化策略, 以下是這個函式的偽**版本:
defsdsmakeroomfor
(sdshdr
,required_len
):# 預分配空間足夠,無須再進行空間分配if(
sdshdr
.free
>=
required_len
):return
sdshdr
# 計算新字串的總長度
newlen
=sdshdr
.len
+required_len
# 如果新字串的總長度小於 sds_max_prealloc
# 那麼為字串分配 2 倍於所需長度的空間
# 否則就分配所需長度加上 sds_max_prealloc 數量的空間
ifnewlen
<
sds_max_prealloc
:newlen*=2
else
:newlen
+=sds_max_prealloc
# 分配記憶體
newsh
=zrelloc
(sdshdr
,sizeof
(struct
sdshdr)+
newlen+1
)# 更新 free 屬性
newsh
.free
=newlen
-sdshdr
.len
# 返回
return
newsh
在目前版本的 redis 中,sds_max_prealloc
的值為1024
*1024, 也就是說, 當大小小於1mb
的字串執行追加操作時,sdsmakeroomfor
就為它們分配多於所需大小一倍的空間; 當字串的大小大於1mb
, 那麼sdsmakeroomfor
就為它們額外多分配1mb
的空間。
sds
會為追加操作進行優化:加快追加操作的速度,並降低記憶體分配的次數,代價是多占用了一些記憶體,而且這些記憶體不會被主動釋放。
摘抄:
簡單動態字串 SDS
1 介紹 redis沒有使用c語言本身的字串,而使用簡單動態字串sds dynamic string 這種抽象型別。2 實現 struct3 為什麼要使用sds?為什麼不適用c語言本身的字串?如何擴容?因為c語言本身的字串進行length計算的時候複雜度為o n sds本身具有len屬性,使用sds...
Redis之簡單動態字串 SDS
簡單動態字串sds dynamic string sds資料結構如下 struct sdshdr基於sds資料結構的定義和一些api規則,sds相比於c字串有如下優勢 1.獲取字串長度的複雜度為o 1 c字串的複雜度為o n 2.杜絕緩衝區溢位 3.減少修改字串時帶來的記憶體重分配次數 4.二進位制...
Redis之簡單動態字串(SDS)
redis沒有直接使用c語言傳統的字串表示,而是自己構建一種名為簡單動態字串 sds 的抽象型別,並將sds用作redis的預設字串表示。在redis的資料庫中,包含字串值得鍵值對在底層都是又sds實現的。比如reids set msg hello world ok在客戶端中執行這樣的命令,redi...