SDS字串原始碼分析

2021-07-29 17:40:51 字數 1593 閱讀 4998

0. 前言

這裡對redis底層字串的實現分析,但是看完其實現還沒有完整的乙個概念,即不太清楚作者為什麼要這樣子設計,只能窺知一點,需要看完redis如何使用再回頭來體會,有不足之處還望告知。

涉及檔案:sds.h/sds.c

1.  資料結構:  

1 typedef char *sds;23

struct

sdshdr ;

這裡向外提供的api所返回的型別都是sds型別(字串),這樣的話也能夠復用一部分的c字串函式。

這裡採用sdshdr結構,存放了字串長度資訊,保證了二進位制資料安全,即不僅可以存放字串,也可用於存放其它二進位制資料

2. api實現:

只提取幾個api,該檔案完整的注釋在githud上(使用者名稱:jabnih)

a. sdsnewlen

建立乙個sds字串,其它幾個建立api都是基於這個api。

建立時採用一次性分配其所需要的空間,即對於buf不進行再次分配,減少了malloc等的呼叫,同時在釋放的時候也減少free次數

1

//建立乙個sds字串,初始內容為init所指向的內容,buf空間為initlen大小

2 sds sdsnewlen(const

void *init, size_t initlen) else

1314

if (sh == null) return

null;

1516 sh->len =initlen;

17 sh->free = 0;18

//這裡如果init為null,則該buf的內容均為0

19if (initlen &&init)

20 memcpy(sh->buf, init, initlen);

2122 sh->buf[initlen] = '\0'

;2324return (char*)sh->buf;

25 }

b. sdsmakeroomfor

該api的記憶體分配策略為:在小於sds_max_prealloc(即1m)時,會預分配出多一倍的空間,在大於該閾值時,每次只預分配多sds_max_prealloc記憶體。

1

//保證sds字串有足夠的剩餘未使用空間(大於或等於addlen)

2sds sdsmakeroomfor(sds s, size_t addlen)

c. sdsremovefreespace

1

//去除sds字串中未使用的空間,一般在記憶體緊張的時候使用

2sds sdsremovefreespace(sds s)

d. sdsclear

1

//清空sds字串,但是不釋放空間

2void

sdsclear(sds s)

3. 總結:

1. 二進位制資料安全

2. 預分配空間,可以懶惰釋放,在記憶體緊張的時候也可以縮減不需要的記憶體

3. 使用該api可以實現記憶體動態擴充套件(即不需要考慮記憶體空間是否足夠)

4. 邊界檢查

Redis原始碼閱讀 sds字串實現

從開始工作就開始使用redis,也有一段時間了,但都只是停留在使用階段,沒有往更深的角度探索,每次想讀原始碼都止步在閱讀書籍上,因為看完書很快又忘了,這次逼自己先讀 因為個人覺得寫作需要閱讀文本來增強靈感,那麼寫 的,就閱讀更多 來增強靈感吧。redis的實現原理,在 redis設計與實現 一書中講...

Nginx原始碼分析 字串處理

ngx string.c void ngx strlow u char dst,u char src,size t n 將src的前n個字元轉換成小寫存放在dst字串當中,呼叫者需要保證dst指向的空間大於等於n。操作不會對原字串產生變動。如要更改原字串,可以 ngx str t str ngx s...

redis原始碼分析二 sds實現

1 sds頭部的結構struct attribute packed sdshdr8 2 redis中sds的優勢 1.快速獲取字串長度 這個在於sds的首部中記錄了len表示當前buf的長度,這樣獲取乙個字串的長度的複雜度變成了o 1 這也是用空間換效率的有效方法,因為暫用的空間非常小且現在我們電腦...