簡單動態字符串數組
struct sdshdr { unsigned int len; //記錄buf數組中已使用字節的數量 等於SDS所保存字符串的長度 unsigned int free; // 記錄buf數組中未使用字節的數量 char buf[]; //字節數組,用於保存字符串 };
SDS在len屬性中記錄了SDS自己的長度,因此獲取一個SDS長度的複雜度僅爲O(1)。安全
SDS的空間分配策略徹底杜絕了發生緩衝區溢出的可能性。當SDS API須要對SDS進行修改時,API會先檢查SDS的空間是否知足修改所須要的要求,若是不知足的話,API會自動將SDS的空間擴展至執行修改所需的大小,而後才執行實際的修改操做,因此函數
SDS 既不須要手動修改SDS的空間大小,也不會出現緩衝區溢出問題。優化
SDS經過free 未使用空間解除了字符串長度和底層數組長度之間的關聯;在SDS中,buf數組的長度不必定就是字符串數量加1,數組中可包含未使用的字節,而這些字節的數組就有SDS的free屬性記錄。指針
使用未使用空間,SDS實現了空間預分配和惰性空間釋放兩種優化策略。code
Redis 只會使用C字符串做爲字面量,在大多數狀況下,Redis 使用SDS(Simple Dynamic String, 簡單動態字符串)做爲字符串表示。內存
比起C字符串,SDS具備如下優勢:字符串
常數複雜度獲取字符串長度。
io
杜絕緩衝區溢出。class
減小修改字符串長度使所需的內存重分配次數。
二進制安全
兼容部分C字符串函數
鏈表
typedef struct listNode { struct listNode *prev; //前置節點 struct listNode *next; //後置節點 void *value; //節點的值 } listNode; typedef struct listIter { listNode *next; int direction; } listIter; typedef struct list { listNode *head; //表頭節點 listNode *tail; //表尾節點 void *(*dup)(void *ptr); //節點值複製函數 void (*free)(void *ptr); //節點值釋放函數 int (*match)(void *ptr, void *key); //節點值對比函數 unsigned long len; //鏈表所包含的節點數量 } list;
Redis的鏈表實現的特性能夠總結以下:
雙端:鏈表節點帶有prev和next指針,獲取某個節點的前置節點和後置節點的複雜度都是O(1)
無環: 表頭節點的prev指針和表尾節點的next指針都指向NULL, 對鏈表的訪問以NULL爲終點。
帶表頭指針和表尾指針:經過list結構的head指針和tail指針,程序獲取鏈表的表頭節點和表尾節點的複雜度爲O(1).
帶鏈表長度計數器:程序使用list結構的len屬性來對list持有的鏈表節點進行計數,程序獲取鏈表中節點數量的複雜度爲O(1)。
多態: 鏈表節點使用void *指針來保存節點值,而且能夠經過list結構的dup,free,match三個屬性爲節點值設置類型特定函數,因此鏈表能夠用於保存各類不一樣類型的值。