探祕 Redis 整數集合
阿新 • • 發佈:2021-02-06
整數集合(intset)是集合的底層實現之一,當 set 集合容納的元素都是整數並且元素個數較小時,Redis 會使用 intset 來儲存集合元素。
intset 是 Redis 用於儲存整數值的集合抽象資料結構,它是一種緊湊的陣列結構,並且可以儲存型別為 int16_t, int32_t 和 int64_t 的整數值,並且集合中不會出現重複的元素。
注意:一旦在集合中加入了字串,集合就會從 intset 變成 hash 結構。
intset 定義
typedef struct intset {
uint32_t encoding;
uint32_t length;
int8_t contents[];
}
contents 即整數陣列,整數集合中的每個元素都是contents 裡面的一個數據項,且這些項在陣列中總是按值從小到大有序排列,並且沒有任何重複項
length 記錄了整數集合中包含的元素個數,即contents陣列的長度
encoding 用於決定整數位寬是 16 位、32 位還是 64 位
大家想一想為什麼 Redis 要使用 encoding 來標識陣列的型別?
其實很簡單,為了儘可能節約記憶體啊。
本來記憶體就是有限的,是寶貴的資源,那你存一個整數,明明16位就能夠儲存了,為什麼要用64位來儲存呢?
升級
升級一般是分三個步驟:
- 根據新元素的型別改變當前 encoding 的型別,擴充套件contents陣列的大小,然後為新元素分配空間。
- 將原來的所有元素的型別都轉化為與新元素相同的型別,然後放置元素在正確的位置上,保持原來的有序性。
- 將新元素新增到數組裡面。
不過整數集合是不支援降級的,一旦對陣列進行了升級,那麼編碼就會一直保持升級後的狀態。