redis數據結構實現--簡單動態字符串

redis數據結構實現--簡單動態字符串

1. SDS簡單動態字符串詳解

sds是redis本身實現的一種數據結構,用來做爲redis底層默認字符串,與c語言的字符串區別開來。
在redis中c字符串通常用於不須要改變的字符串值,叫作字符串字面量,如:打印日誌。
redis中每對鍵值的鍵都是一個sds對象。redis

傳統c字符串與sds比較:算法

  • sds數據結構中也是用字符數組存儲字符串,可是帶有兩個額外參數:len(記錄字符串長度)和free(未使用空間)
  • 想要得到傳統c字符串的長度不得不遍歷整個字符串,然而sds則可直接讀取len值。下降了時間複雜度
  • 二者的字符數組都是以空字符'/0'結尾,在sds中此空字符不計入len中可是也一樣分配一個字節空間,空字符的相關操做都是由sds的API自動完成的,因此對於開發者來講此空字符是透明的。sds保持和c字符串一致以空字符做爲結尾是爲了可以複用c語言的字符串函數庫裏的函數。
  • 傳統c字符串若是在對字符串操做沒有注意空間剩餘有可能會出現內場溢出的現象,而sds的API中執行拼接操做的函數sdscat,拼接時會先判斷空間是否足夠,若是不夠則會先執行擴容操做,從而杜絕內場溢出.
  • 避免頻繁內存重分配:傳統c字符串的長度爲n+1(空字符),每一次append時須要從新分配內存,不然內存溢出;若是trim字符串,後面不須要的空間也要釋放,不然內存泄露。內存重分配設計複雜算法且可能須要系統調度,不符合redis的速度要求。而sds經過free-未使用空間來解除了底層數組長度與字符串長度間的關聯,sds擁有空間預分配與惰性空間釋放兩鍾優化策略。數組

    1. 空間預分配
      在對sds空間拓展時,先判斷空間是否足夠,若是足夠,則直接使用未使用空間。若是空間不夠則使用空間預分配策略
      若是計算得出的sds修改後的長度小於1MB,那麼預分配的未使用空間將於已使用的空間同樣長。若是sds修改後的長度大於1MB,
      那麼將分配1MB的未使用空間。
      經過這種策略將連續增加N次的sds字符串所需的內存重分配次數從一定是N次改成最多N次。
    2. 惰性空間釋放
      在對sds字符串進行縮短操做時,並不當即回收縮短的長度,而是利用free將縮短的字符串記錄起來,以備之後拓展時使用。
      一樣sdsAPI中也提供了真正回收空間的API,因此惰性空間釋放並不會浪費空間。
    • 二進制安全:c字符串必須得符合某種編碼,且字符串除了尾部中間不能存放空字符,不然被讀取到空字符時忽略後面的字符段。全部c字符串只能存放文本信息不能存放二進制數據。而sds的API都是二進制安全(binary-safe)的,buf中存放的就是一系列二進制數據。
相關文章
相關標籤/搜索