0. 前言
這裡對redis底層字串的實現分析,但是看完其實現還沒有完整的乙個概念,即不太清楚作者為什麼要這樣子設計,只能窺知一點,需要看完redis如何使用再回頭來體會,有不足之處還望告知。
涉及檔案:sds.h/sds.c
1. 資料結構:
1 typedef char *sds;23這裡向外提供的api所返回的型別都是sds型別(字串),這樣的話也能夠復用一部分的c字串函式。struct
sdshdr ;
這裡採用sdshdr結構,存放了字串長度資訊,保證了二進位制資料安全,即不僅可以存放字串,也可用於存放其它二進位制資料
2. api實現:
只提取幾個api,該檔案完整的注釋在githud上(使用者名稱:jabnih)
a. sdsnewlen
建立乙個sds字串,其它幾個建立api都是基於這個api。
建立時採用一次性分配其所需要的空間,即對於buf不進行再次分配,減少了malloc等的呼叫,同時在釋放的時候也減少free次數
1b. sdsmakeroomfor//建立乙個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 }
該api的記憶體分配策略為:在小於sds_max_prealloc(即1m)時,會預分配出多一倍的空間,在大於該閾值時,每次只預分配多sds_max_prealloc記憶體。
1c. sdsremovefreespace//保證sds字串有足夠的剩餘未使用空間(大於或等於addlen)
2sds sdsmakeroomfor(sds s, size_t addlen)
1d. sdsclear//去除sds字串中未使用的空間,一般在記憶體緊張的時候使用
2sds sdsremovefreespace(sds s)
13. 總結://清空sds字串,但是不釋放空間
2void
sdsclear(sds s)
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 這也是用空間換效率的有效方法,因為暫用的空間非常小且現在我們電腦...