05-Redis的內存對象及內部編碼_List

列表(list)用來存儲多個有序的元素; 一個列表可以存儲2^32-1個元素。
Redis中的列表支持兩端插入和彈出,並可以獲得指定位置(或範圍)的元素,可以充當數組、隊列、棧等。

1 內部編碼
列表的內部編碼可以是壓縮列表(ziplist)或雙端鏈表(linkedlist)

  • 雙端鏈表
    與雙鏈表定義一致,引入了鏈表節點,並在此基礎上增加頭尾節點構建雙端鏈表
    鏈表節點listNode如下定義:
/* Node, List, and Iterator are the only data structures used currently. */  
/* 
 * 鏈表節點 
 */  
typedef struct listNode {  
    // 前驅節點  
    struct listNode *prev;  
    // 後繼節點  
    struct listNode *next;  
    // 值  
    void *value;  
} listNode;  

鏈表如下定義:

/* 
* 鏈表 
*/  
typedef struct list {  
   // 表頭指針  
   listNode *head;  
   // 表尾指針  
   listNode *tail;  
   // 節點數量  
   unsigned long len;  
   // 複製函數  
   void *(*dup)(void *ptr);  
   // 釋放函數  
   void (*free)(void *ptr);  
   // 比對函數  
   int (*match)(void *ptr, void *key);  
} list;  

雙端鏈表結構如下圖所示:
在這裏插入圖片描述

通過圖中可以看出,雙端鏈表同時保存了表頭指針和表尾指針,並且每個節點都有指向前和指向後的指針;鏈表中保存了列表的長度;dup、free和match爲節點值設置類型特定函數,所以鏈表可以用於保存各種不同類型的值。而鏈表中每個節點指向的是type爲字符串的redisObject。

  • 壓縮列表
    壓縮列表是Redis爲了節約內存而開發的,是由一系列特殊編碼的連續內存塊(而不是像雙端鏈表一樣每個節點是指針)組成的順序型數據結構。
    壓縮列表的結構
  • zlbytes記錄整個壓縮列表佔用的內存字節數,在對壓縮列表進行內存重分配或計算
  • zlend的位置時使用
  • zltail記錄壓縮列表尾節點距離壓縮列表的起始地址有多少字節,通過這個偏移量,可以直接確定尾節點的位置
  • zllen記錄壓縮列表包含的節點數量
  • entryX表示各種節點,數量和長度不一定
  • zlend用於標記壓縮列表的末端。

如圖,如果有一個指針p指向該壓縮列表,則尾巴節點的長度就是指針加上偏移量179(十六進制0xb3=16*11+3=179),列表的長度zllen爲5,表示壓縮列表包含5個節點。zlbytes爲0xd2表示壓縮列表的總長爲210字節。

在這裏插入圖片描述
由上可知,每個壓縮列表的節點可以保存一個字節數組或者一個整數值,那麼每個節點肯定也有自己的結構。

與雙端鏈表相比,壓縮列表可以節省內存空間,但是進行修改或增刪操作時,複雜度較高
因此當節點數量較少時,可以使用壓縮列表;但是節點數量多時,還是使用雙端鏈表划算

壓縮列表不僅用於實現列表,也用於實現哈希、有序列表;使用非常廣泛。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章