整數(shù)集合

intset(整數(shù)集合)是集合鍵的底層實現(xiàn)之一,當(dāng)一個集合只包含整數(shù),并且數(shù)量不多的時候,Redis就會使用整數(shù)集合作為集合鍵的底層實現(xiàn)

整數(shù)集合的實現(xiàn)

intset是Redis中用來保存整數(shù)值的集合抽象數(shù)據(jù)結(jié)構(gòu),可以保存int16_t,int32_t,int64_t的整數(shù)值,并且保證集合中不會出現(xiàn)重復(fù)的,從小到大有序排序

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

contents數(shù)組的真正類型取決于encoding屬性的值:

encoding:INTSET_ENC_INT16,那么contents就是一個int16_t類型的數(shù)組(-32768到32767)

encoding:INTSET_ENC_INT32,那么contents就是一個int32_t類型的數(shù)組(-2147483648到2147483647)

encoding:INTSET_ENC_INT64,那么contents就是一個int64_t類型的數(shù)組(-9223372036854775808到9223372036854775807)

包含int16_t類型整數(shù)值的整數(shù)集合

contents數(shù)組的大小等于sizeof(int16_t)*5=16*5=80位

升級

當(dāng)我們要將一個新元素添加到整數(shù)集合中,并且新元素的類型比整數(shù)集合現(xiàn)有的所有元素類型都要長的時候,整數(shù)集合需要先進(jìn)行升級,然后才能將新元素添加到整數(shù)集合中

升級步驟:

  1. 根據(jù)新元素的類型,擴(kuò)展整數(shù)集合底層數(shù)組的空間大小,并為新元素分配空間

  2. 把底層數(shù)組現(xiàn)有的所有元素都轉(zhuǎn)換為與新元素相同的類型,并將類型轉(zhuǎn)換后的元素放到正確的位上,而且在防止元素的過程中,需要維持底層數(shù)組的有序性不變

  3. 將新元素添加到底層數(shù)組中

舉例:


包含3個int16_t類型的整數(shù)

contents底層數(shù)組大小3*16=48,下面是3個元素在48位中的位置

0-15位 16到31位 32到47位
元素 1 2 3

將65535添加進(jìn)去,這個是int32_t類型的,所以要對contents進(jìn)行升級

對底層數(shù)組做空間重分配,32*4=128位

0-15位 16到31位 32到47位 48到127位
元素 1 2 3 新分配空間
0-15位 16到31位 32到47位 48到63位 64到95位 96到127位
元素 1 2 3 新分配空間 3 新分配空間
0-15位 16到31位 32到63位 64到95位 96到127位
元素 1 2 2 3 新分配空間
0-31位 32到63位 64到95位 96到127位
元素 1 2 3 新分配空間
0-31位 32到63位 64到95位 96到127位
元素 1 2 3 65535

升級的好處

  1. 提升整數(shù)集合的靈活性

c語言是靜態(tài)類型語言,為了避免類型錯誤,通常不會將兩種不同類型的值放到一個數(shù)據(jù)結(jié)構(gòu)中,但是通過自動升級底層數(shù)組來適應(yīng)新元素,可以隨意將int16_t,int32_t,int64_t類型的整數(shù)添加到集合中,不必?fù)?dān)心類型錯誤

  1. 盡可能的節(jié)約內(nèi)存

如果直接使用int64_t作為底層數(shù)組的實現(xiàn),當(dāng)然可以同時保持所有了,但是如果存的都是int16_t,或者都是int32_t類型的值,就會浪費(fèi)內(nèi)存了,而升級只會讓他在需要的時候進(jìn)行升級,這樣可以盡量節(jié)省內(nèi)存

降級

intset不支持降級操作,一旦對數(shù)組做了升級,編碼就會一直保持升級后的狀態(tài),即使將int64_t類型的數(shù)刪除了,編碼仍然是int64_t

整數(shù)集合API

函數(shù) 作用 時間復(fù)雜度
intsetNew 創(chuàng)建一個新的壓縮列表 O(1)
intsetAdd 將給定元素添加到整數(shù)集合中 O(N)
intsetRemove 從整數(shù)集合中移除給定元素 O(N)
intsetFind 檢查給定值是否存在于集合中 有序,可以通過二分查找O(logN)
intsetRandom 從整數(shù)集合中隨機(jī)返回一個元素 O(1)
intsetGet 取出底層數(shù)組在給定索引上的元素 O(1)
intestLen 返回整數(shù)集合中包含元素的個數(shù) O(1)
intsetBlobLen 返回整數(shù)集合占用的內(nèi)存字節(jié)數(shù) O(1)
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容