Redis壓縮列表節約內存的示例:
1.壓縮列表的構成,代碼:
//返回整個壓縮列表的總字節#define ZIPLIST_BYTES(zl) (*((uint32_t*)(zl)))
//返回壓縮列表的tail_offset變量,方便獲取最后一個節點的位置
#define ZIPLIST_TAIL_OFFSET(zl) (*((uint32_t*)((zl)+sizeof(uint32_t))))
//返回壓縮列表的節點數量
#define ZIPLIST_LENGTH(zl) (*((uint16_t*)((zl)+sizeof(uint32_t)*2)))
//返回壓縮列表的表頭的字節數
//(內存字節數zlbytes,最后一個節點地址ztail_offset,節點總數量zllength)
#define ZIPLIST_HEADER_SIZE (sizeof(uint32_t)*2+sizeof(uint16_t))
//返回壓縮列表最后結尾的字節數
#define ZIPLIST_END_SIZE (sizeof(uint8_t))
//返回壓縮列表首節點地址
#define ZIPLIST_ENTRY_HEAD(zl) ((zl)+ZIPLIST_HEADER_SIZE)
//返回壓縮列表尾節點地址
#define ZIPLIST_ENTRY_TAIL(zl) ((zl)+intrev32ifbe(ZIPLIST_TAIL_OFFSET(zl)))
//返回壓縮列表最后結尾的地址
#define ZIPLIST_ENTRY_END(zl) ((zl)+intrev32ifbe(ZIPLIST_BYTES(zl))-1)
2.壓縮列表節點的構成,代碼:
/* We use this function to receive information about a ziplist entry.* Note that this is not how the data is actually encoded, is just what we
* get filled by a function in order to operate more easily. */
typedef struct zlentry {
unsigned int prevrawlensize; //記錄prevrawlen需要的字節數
unsigned int prevrawlen; //記錄上個節點的長度
unsigned int lensize; //記錄len需要的字節數
unsigned int len; //記錄節點長度
unsigned int headersize; //prevrawlensize+lensize
unsigned char encoding; //編碼格式
unsigned char *p; //具體的數據指針
} zlentry;