簡單動態字串 SDS

2021-08-20 07:41:47 字數 2218 閱讀 8275

sds (****** dynamic string,簡單動態字串)是 redis 底層所使用的字串表示。

sds 在 redis 中的主要作用有以下兩個:

實現字串物件(stringobject);

在 redis 程式內部用作char*型別的替代品;

redis 是乙個鍵值對資料庫(key-value db), 資料庫的值可以是字串、集合、列表等多種型別的物件, 而資料庫的鍵則總是字串物件。

對於那些包含字串值的字串物件來說, 每個字串物件都包含乙個 sds 值。(在 redis 中, 乙個字串物件除了可以儲存字串值之外, 還可以儲存long型別的值, 所以為了嚴謹起見, 這裡需要強調一下:

當字串物件儲存的是字串時, 它包含的才是 sds 值, 否則的話, 它就是乙個long型別的值。)

在前面的內容中, 我們一直將 sds 作為一種抽象資料結構來說明, 實際上, 它的實現由以下兩部分組成:

typedef

char

*sds

;struct

sdshdr

;

其中,型別sdschar

*的別名(alias),而結構sdshdr則儲存了lenfreebuf三個屬性。

作為例子,以下是新建立的,同樣儲存hello

world字串的sdshdr結構:

struct

sdshdr

;

被更新,字串"

again!"會被追加到原來的"hello

world"之後:

struct

sdshdr

sds.c/sdsmakeroomfor函式描述了sdshdr的這種記憶體預分配優化策略, 以下是這個函式的偽**版本:

def

sdsmakeroomfor

(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...