天天看點

Redis資料結構(一)簡單動态字元串

redis的字元串采用的是自定義的struct,名字叫做簡單動态字元串(simple dynamic string,sds)。

結構如下:

采用如此結構的好處是:

【1】擷取length的時候複雜度為o(1),不需要o(n);

【2】動态配置設定空間,避免緩沖區溢出,避免每次修改或者append都重新配置設定;

【3】二進制安全;

關于第一點顯而易見,第二點,為了減少修改字元串帶來的記憶體重配置設定次數,redis采用了2個措施:

1)空間預配置設定;假設如下sds(狀态【0】),執行指令【sdscat(s,”redis”)】往其中append一個字元串“redis”之後将變為狀态【1】,發生了什麼呢?當sds發現目前free長度無法配置設定新添加的字元串時,将發生一次空間配置設定,如果修改之後sds長度小于1mb,則會配置設定總長度為【修改後長度】*2+1,即為(5+5)*2+1,1為結尾符号空間。如果修改後sds總長度大于等于1mb,則會配置設定【修改後總長度】+1mb的長度。假設再次執行指令【sdscat(s,”redis”)】,由于目前狀态【1】free=10,有足夠空間配置設定新加入的字元串,則不會發生空間配置設定操作,變為狀态【2】;

狀态【0】

狀态【1】:

狀态【2】:

2)惰性空間釋放;現在假設從狀态【2】執行指令【sdstrim(s,”re”)】,移除sds中所有的’r’,’e’,将轉換為狀态【3】; 此時并沒有釋放空間,len+free依然等于20;這樣做的目的是避免了縮短字元串時的記憶體重配置設定操作,并且未将來的字元串擴充預留了空間 ; 當然也可以使用【sdsfree】真正釋放sds;

狀态【3】:

關于第三點,sds的buf屬性稱為位元組數組,儲存的是二進制資料;同時由于使用len字段來判斷字元串是否結束,是以是安全的,不會出現c字元串中以空格作為結尾判斷,導緻字元串被截斷的問題。

繼續閱讀