Redis數(shù)據(jù)結(jié)構(gòu)之String

Redis使用自己的簡單動態(tài)字符串(simple dynamic string, SDS)的抽象類型。Redis中豫缨,默認(rèn)以SDS作為自己的字符串表示缩举。

struct sdshdr {    
  // 用于記錄buf數(shù)組中使用的字節(jié)的數(shù)目
  // 和SDS存儲的字符串的長度相等  
    int len;    
  // 用于記錄buf數(shù)組中沒有使用的字節(jié)的數(shù)目   
    int free;    
  // 字節(jié)數(shù)組洁奈,用于儲存字符串
    char buf[];   //buf的大小等于len+free+1串慰,其中多余的1個字節(jié)是用來存儲’\0’的。
};

image.png

SDS除了用來保存數(shù)據(jù)庫中的字符串之外笙各,SDS還被用作緩沖區(qū)(buffer)钉答,如AOF模塊中的AOF緩沖區(qū),以及客戶端狀態(tài)中的輸入緩沖區(qū)

使用SDS而不使用c語言的string的好處:

1杈抢、常數(shù)復(fù)雜度獲取字符串長度

C語言中:字符串只是簡單的字符的數(shù)組数尿,當(dāng)使用strlen獲取字符串長度的時候,內(nèi)部其實是直接順序遍歷數(shù)組的內(nèi)容惶楼,找到對應(yīng)的’\0’對應(yīng)的字符右蹦,從而計算出字符串的長度。即O(N)鲫懒。

SDS:只需要訪問SDS的len屬性就能得到字符串的長度嫩实,復(fù)雜度為O(1)。

2窥岩、杜絕緩沖區(qū)溢出

Redis是C語言編寫的,并沒有方便的數(shù)據(jù)類型來進(jìn)行內(nèi)存的分配和釋放(C++ STL String)宰缤,必須手動進(jìn)行內(nèi)存分配和釋放颂翼。

對于字符串的拼接、復(fù)制等操作慨灭,C語言開發(fā)者必須確保目標(biāo)字符串的空間足夠大朦乏,不然就會出現(xiàn)溢出的情況。

當(dāng)使用SDS的API對字符串進(jìn)行修改的時候氧骤,

API內(nèi)部第一步會檢測字符串的大小是否滿足呻疹。
如果空間已經(jīng)滿足要求,那么就像C語言一樣操作即可筹陵。如果不滿足刽锤,則拓展buf的空間
之后再進(jìn)行操作镊尺。每次操作之后,len和free的值會做相應(yīng)的修改并思。
擴(kuò)展buf空間策略:
修改之后總長度len<1MB: 總空間為2*len+1;
修改之后總長度len>=1MB: 總空間為len+1MB+1庐氮。
換句話說,預(yù)分配的空間上限是1MB宋彼,盡量為len弄砍。

3、減少修改字符串時帶來的內(nèi)存重分配次數(shù)

Redis主要通過以下兩種策略來處理內(nèi)存問題输涕。

字符串長度增加操作時音婶,進(jìn)行空間預(yù)分配
字符串長度減少操作時,惰性空間釋放

當(dāng)執(zhí)行字符串長度縮短的操作的時候莱坎,SDS并不直接重新分配多出來的字節(jié)衣式,而是修改len和free的值(len相應(yīng)減小,free相應(yīng)增大型奥,buf的空間大小不變化)瞳收,避免內(nèi)存重分配。

SDS也提供直接釋放未使用空間的API厢汹,在需要的時候螟深,也能真正的釋放掉多余的空間。

4烫葬、二進(jìn)制安全

C字符串除了末尾之外不能出現(xiàn)空字符界弧,否則會被程序認(rèn)為是字符串的結(jié)尾。這就使得C字符串只能存儲文本數(shù)據(jù)搭综,而不能保存圖像垢箕,音頻等二進(jìn)制數(shù)據(jù)。

使用SDS就不需要依賴控制符兑巾,而是用len來指定存儲數(shù)據(jù)的大小条获,所有的SDS API都會以處理二進(jìn)制的方式來處理SDS的buf的數(shù)據(jù)。程序不會對buf的數(shù)據(jù)做任何限制蒋歌、過濾或假設(shè)帅掘,數(shù)據(jù)寫入的時候是什么,讀取的時候依然不變堂油。

5修档、兼容部分C字符串函數(shù)

SDS的buf的定義(字符串末尾為’\0’)和C字符串完全相同,因此很多的C字符串的操作都是適用于SDS->buf的府框。比如當(dāng)buf里面存的是文本字符串的時候吱窝,大多數(shù)通過調(diào)用C語言的函數(shù)就可以。

二、總結(jié)

C字符串    SDS
獲取字符串長度的復(fù)雜度為O(N)    獲取字符串長度的復(fù)雜度為O(1)
API是不安全的院峡,可能會造成緩沖區(qū)溢出 API是安全的兴使,不會造成緩沖區(qū)溢出
修改字符串長度N次必然需要執(zhí)行N次內(nèi)存重分配  修改字符串長度N次最多需要執(zhí)行N次內(nèi)存重分配
只能保存文本數(shù)據(jù)    可以保存文本或者二進(jìn)制數(shù)據(jù)
可以使用所有庫中的函數(shù) 可以使用一部分庫的函數(shù)
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市撕予,隨后出現(xiàn)的幾起案子鲫惶,更是在濱河造成了極大的恐慌,老刑警劉巖实抡,帶你破解...
    沈念sama閱讀 212,816評論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件欠母,死亡現(xiàn)場離奇詭異,居然都是意外死亡吆寨,警方通過查閱死者的電腦和手機(jī)赏淌,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,729評論 3 385
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來啄清,“玉大人六水,你說我怎么就攤上這事±弊洌” “怎么了掷贾?”我有些...
    開封第一講書人閱讀 158,300評論 0 348
  • 文/不壞的土叔 我叫張陵,是天一觀的道長荣茫。 經(jīng)常有香客問我想帅,道長,這世上最難降的妖魔是什么啡莉? 我笑而不...
    開封第一講書人閱讀 56,780評論 1 285
  • 正文 為了忘掉前任港准,我火速辦了婚禮,結(jié)果婚禮上咧欣,老公的妹妹穿的比我還像新娘浅缸。我一直安慰自己,他們只是感情好魄咕,可當(dāng)我...
    茶點故事閱讀 65,890評論 6 385
  • 文/花漫 我一把揭開白布衩椒。 她就那樣靜靜地躺著,像睡著了一般哮兰。 火紅的嫁衣襯著肌膚如雪烟具。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 50,084評論 1 291
  • 那天奠蹬,我揣著相機(jī)與錄音,去河邊找鬼嗡午。 笑死囤躁,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播狸演,決...
    沈念sama閱讀 39,151評論 3 410
  • 文/蒼蘭香墨 我猛地睜開眼言蛇,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了宵距?” 一聲冷哼從身側(cè)響起腊尚,我...
    開封第一講書人閱讀 37,912評論 0 268
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎满哪,沒想到半個月后婿斥,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,355評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡哨鸭,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,666評論 2 327
  • 正文 我和宋清朗相戀三年民宿,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片像鸡。...
    茶點故事閱讀 38,809評論 1 341
  • 序言:一個原本活蹦亂跳的男人離奇死亡活鹰,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出只估,到底是詐尸還是另有隱情志群,我是刑警寧澤,帶...
    沈念sama閱讀 34,504評論 4 334
  • 正文 年R本政府宣布蛔钙,位于F島的核電站锌云,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏夸楣。R本人自食惡果不足惜宾抓,卻給世界環(huán)境...
    茶點故事閱讀 40,150評論 3 317
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望豫喧。 院中可真熱鬧石洗,春花似錦、人聲如沸紧显。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,882評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽孵班。三九已至涉兽,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間篙程,已是汗流浹背枷畏。 一陣腳步聲響...
    開封第一講書人閱讀 32,121評論 1 267
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點兒被人妖公主榨干…… 1. 我叫王不留虱饿,地道東北人拥诡。 一個月前我還...
    沈念sama閱讀 46,628評論 2 362
  • 正文 我出身青樓触趴,卻偏偏與公主長得像,于是被迫代替她去往敵國和親渴肉。 傳聞我的和親對象是個殘疾皇子冗懦,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 43,724評論 2 351