1. 程式人生 > >Redis 設計與實現(第六章) -- 整數集合(intset)

Redis 設計與實現(第六章) -- 整數集合(intset)

相同 spa edi redis cnblogs 保存 空間 數值 一個數

概述


1.intset概述

2.intset實現

3.intset升級

intset概述

整數集合是Redis集合鍵的底層實現之一,當值都為整數時,redis就會選擇整數集合作為底層實現。

可以保存int16_t,int32_t,int64_t類型的整數值,並且集合中不會出現重復元素。

intset實現

先看下intset的數據結構:

typedef struct intset {
    uint32_t encoding;  //encoding方式
    uint32_t length;  //長度
    int8_t contents[]; //存儲數組
} intset;

雖然contents[]聲明了int8_t類型的數組,但實際上contents[]並不保存任何int8_t類型的數據,真正的數據類型取決於encoding的類型。

encoding類型有以下三種:

#define INTSET_ENC_INT16 (sizeof(int16_t))
#define INTSET_ENC_INT32 (sizeof(int32_t))
#define INTSET_ENC_INT64 (sizeof(int64_t))

intset升級

如果encoding類型為int_16,但是這時候需要保存個新元素,但是元素無法通過int16_t表示,這時就需要涉及到升級操作:

升級後所有元素會升級到對應升級後的類型,set中不會存在多種類型,而且升級後就無法降級;

升級步驟如下:

1.判斷升級所需要的空間,分配空間大小;

2.將所有元素升級到與新元素相同的類型,並將轉換類型後的元素添加到正確位置上;

3.將新元素添加到底層數組裏面;

升級有什麽好處?

1.提升靈活性

因為C是靜態類型的,為了避免錯誤,通常不會將兩種不同類型保存在同一個數據結構中;但是升級能夠支持保存int16_t,int32_t,int64_t的數據;

2.節約空間

如果保存的數據只有int16_t,那分配一個int64_t的空間是造成空間的浪費,所以最開始值分配int16_t的空間,如果需要添加int32_t,int64_t的數據,再進行升級。

Redis 設計與實現(第六章) -- 整數集合(intset)