Redis底層數據結構

一、簡單動態字符串SDS

1、結構

struct sdshdr {
    int len;       // 記錄數組中已使用的字節數
    int free;      // 記錄數組中未使用的字節數
    char buf[];    // 用於保存字符串
}

2、特點

(1)獲取字符串長度複雜度O(1)

(2)防止緩衝區溢出

(3)減少修改字符串長度時所需的內存重分配次數

(4)二進制安全

(5)兼容部分C字符串函數 

 

二、鏈表

1、結構

// 鏈表節點
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;

2、特點

(1)雙端無環鏈表

(2)快速獲取表頭、表尾指針

(3)快速獲取鏈表長度

(4)多態,可存儲各種類型數據

 

三、字典

1、結構

// 哈希表節點
typedef struct dictEntry {
    void *key;                 // 鍵
    union {                    // 值
        void *val;
        uint64_t u64;
        int64_t s64;
    } v;
    struct dictEntry *next;    // 指向下一個節點
} dictEntry;

// 哈希表
typedef struct dictht {
    dictEntry **table;         // 哈希表數組
    unsigned long size;        // 哈希表大小
    unsigned long sizemask;    // 哈希表大小掩碼,總是等於size-1
    unsigned long used;        // 已有節點數量
} dictht;

// 字典
typedef struct dict {
    dictType *type;    // 類型特定函數
    void *privdata;    // 私有數據
    dictht ht[2];      // 哈希表,ht[1]用於rehash過程
    int trehashidx;    // rehash索引,當rehash不再進行時爲-1
} dict;

2、特點

(1)兩個哈希表用於快速rehash過程

(2)鏈地址表法解決hash衝突

(3)漸進式rehash 

 

四、跳躍表

1、結構

// 跳躍表節點
typedef struct zskiplistNode {
    struct zskiplistNode *backward;       // 後退節點
    double score;                         // 分值
    robj *obj;                            // 成員對象
    struct zskiplistLevel {
        struct zskiplistNode *forward;    // 前驅節點
        unsigned int span;                // 跨度
    } level[];
} zskiplistNode;

// 跳躍表
typedef struct zskiplist {
    struct skiplistNode *header, *tail;    // 表頭和表尾節點
    unsigned long length;                  // 跳躍表長度
    int level;                             // 最大層數
}

 2、特點

(1)層高爲1-32之間的隨機數

(2)分值允許相同,當分值相同時,按照成員對象的大小進行排序

 

五、整數集合

1、結構

// 整數集合
typedef struct intset {
    uint32_t encoding;    // 編碼方式
    uint32_t length;      // 集合包含的元素數量
    int8_t contents[];    // 元素數組
} intset;

 2、特點

(1)升級策略,提升整數集合的靈活性,儘可能節約內存。

(2)整數集合有序、無重複

 

六、壓縮列表

1、結構

typedef struct zlentry {
    unsigned int prevrawlensize;    // 前驅節點的編碼長度
    unsigned int prevrawlen;        // 前驅節點類型
    unsigned int lensize;           // 節點類型/長度
    unsigned int len;               // 節點試集長度
    unsigned int headersize;        // prevrawlensize + lensize
    unsigned char encoding;         // 節點類型
    unsigned char *p;               // 節點開頭
} zlentry;

2、特點

(1)順序性數據結構,底層由char數組構成

(2)可包含多個節點,每個節點可以保存一個字節數組或整數值

(3)添加或刪除節點可能會引發連鎖更新操作 

 

七、對象

1、結構

typedef struct redisObject {
    unsigned type:4;          // 類型
    unsigned encoding:4;      // 編碼
    unsigned lru:LRU_BITS;    // LRU時間或LFU數據
    int refcount;
    void *ptr;                // 只想底層數據結構的指針
} robj;

2、對象類型和編碼

類型 編碼 對象 條件
REDIS_STRING REDIS_ENCODING_INT 字符串對象(整數值) 保存整數值,且可以用long來表示
REDIS_STRING REDIS_ENCODING_EMBSTR 字符串對象(embstr編碼的SDS) 保存字符串值,且長度小於等於39字節
REDIS_STRING REDIS_ENCODING_RAW 字符串對象(SDS) 其它
REDIS_LIST REDIS_ENCODING_ZIPLIST 列表對象(壓縮列表) 保存的所有字符串元素長度都小於64字節,且元素數量小於512個
REDIS_LIST REDIS_ENCODING_LINKEDLIST 列表對象(雙端鏈表) 其它
REDIS_HASH REDIS_ENCODING_ZIPLIST 哈希對象(壓縮列表) 保存的所有鍵值對的鍵和值的字符串長度都小於64字節,且鍵值對數量小於512個
REDIS_HASH REDIS_ENCODING_HT 哈希對象(字典) 其它
REDIS_SET REDIS_ENCODING_INTSET 集合對象(整數集合) 保存的所有元素都是整數值,且元素數量小於512個
REDIS_SET REDIS_ENCODING_HT 集合對象(字典) 其它
REDIS_ZSET REDIS_ENCODING_ZIPLIST 有序集合對象(壓縮列表) 保存的元素數量小於128個,且成員長度都小於64字節
REDIS_ZSET REDIS_ENCODING_SKIPLIST 有序集合對象(跳躍表) 其它

 

 

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