程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 數據庫知識 >> DB2數據庫 >> DB2教程 >> Redis數據結構(一)簡單動態字符串

Redis數據結構(一)簡單動態字符串

編輯:DB2教程

Redis數據結構(一)簡單動態字符串


Redis的字符串采用的是自定義的struct,名字叫做簡單動態字符串(simple dynamic string,SDS)。
結構如下:

struct sdshdr{
int len;
int free;
char buf[];
};

采用如此結構的好處是:
【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】

   struct sdshdr{
   int len=5;
   int free=4;
   char buf[]={'h','e','l','l','o','\0','','','',''};
   }; 

狀態【1】:

   struct sdshdr{
   int len=10;
   int free=10;
   char buf[]={'h','e','l','l','o','r','e','d','i','s','\0',...};
   }; 

狀態【2】:

   struct sdshdr{
   int len=15;
   int free=5;
   char buf[]={'h','e','l','l','o','r','e','d','i','s','r','e','d','i','s','\0',...};
   }; 

2)惰性空間釋放;現在假設從狀態【2】執行命令【sdstrim(s,”re”)】,移除sds中所有的’r’,’e’,將轉換為狀態【3】; 此時並沒有釋放空間,len+free依然等於20;這樣做的目的是避免了縮短字符串時的內存重分配操作,並且未將來的字符串擴充預留了空間 ; 當然也可以使用【sdsfree】真正釋放sds;
狀態【3】:

   struct sdshdr{
   int len=11;
   int free=9;
   char buf[]={'h','e','l','l','o','d','i','s','d','i','s','\0',...};
   }; 

關於第三點,SDS的buf屬性稱為字節數組,保存的是二進制數據;同時由於使用len字段來判斷字符串是否結束,所以是安全的,不會出現c字符串中以空格作為結尾判斷,導致字符串被截斷的問題。

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved