Redis 數據結構實現(一)字符串
Redis採用SDS(simple dynamic string)來表示字符串,表示一個可以修改的字符串值。用在Redis的key和value中。
注意:Redis所有的key都是這個類型,value有不同的其他類型,SDS還可以用在緩衝區中。
其具體的定義如下:
爲什麼不用C原生字符串?
- 是因爲Redis中有STRLEN命令,該命令可以求一個key對應的value的長度(必須爲string 類型),如果用C字符串每次求長度都必須掃描整個字符串,效率較低。而Redis中的SDS提供了len長度屬性,可以在O(1)的時間內求得長度。
- C中存在字符串拼接時緩衝區溢出的問題,Redis中也有sdscat命令,這個命令用於字符串拼接,拼接前會先檢查是否有足夠的free,沒有則先分配空間再拼接。
- Redis需要保存二進制數據,而C中的字符串以’\0’判斷是否到達末尾,沒辦法存儲二進制數據。
注意:雖然Redis用自己的SDS,但是爲了複用C語言中提供的字符串操作函數,還是遵循了以’\0’結尾的傳統~(len、free中不算這個‘\0’但是實際分配時buff數組是分配了的。
SDS內存重分配策略?
剛纔講到,如果沒有足夠的free會先分配內存,衆所周知,字符串的拼接、裁剪是非常頻繁的操作,內存的分配與回收不當則會降低效率甚至帶來內存泄漏,那是如何優化分配的呢?
- 空間預分配
- 如果修改後的len小於1M的話,會一起預先分配與len長度相等的free空間
- 如果修改後的len大於等於1M的話,會預先分配1M的空間
- 惰性空間釋放
當對字符串進行裁剪時(字符串長度縮小),並不會立即釋放空間,而是保留下次使用。Redis也提供了釋放SDS未使用內存的命令(sdsRemoveFreeSpace命令)
惰性刪除的代碼如下: