redis原始碼學習之整數集合

2021-07-26 10:42:18 字數 1407 閱讀 4425

intset的底層實現比較簡單,因為它所有的key都是整型,只是整型分為16bits、32bits和64bits這三種型別,當新插入的元素比當前集合中所有數還要長時,就要進行公升級了,這部分原始碼很簡單,主要就是公升級部分。

/*

* intset 的編碼方式

*/#define intset_enc_int16 (sizeof(int16_t))

#define intset_enc_int32 (sizeof(int32_t))

#define intset_enc_int64 (sizeof(int64_t))

typedef

struct intsetintset;

跟陣列操作類似,由於是有序表,因此底層查詢使用二分查詢,移動陣列的操作使用memmove,另外還需考慮公升級的情況。

intset *intsetadd(intset *is, int64_t value, uint8_t *success)  else //表示元素存在,直接返回

// 執行到這裡,表示 value 不存在於集合中

// 程式需要將 value 新增到整數集合中

// 為 value 在集合中分配空間

is = intsetresize(is,intrev32ifbe(is->length)+1);

// 如果新元素不是被新增到底層陣列的末尾

// 那麼需要對現有元素的資料進行移動,空出 pos 上的位置,用於設定新值

if (pos < intrev32ifbe(is->length)) intsetmovetail(is,pos,pos+1);//底層呼叫memmove

}// 將新值設定到底層陣列的指定位置中

_intsetset(is,pos,value);

// 增一集合元素數量的計數器

is->length = intrev32ifbe(intrev32ifbe(is->length)+1);

// 返回新增新元素後的整數集合

return is;

}

最有意思的地方就在於公升級了,比如現在集合中有1,2,3這三個元素,突然插入乙個65535,那麼就需要對原集合進行公升級了,因為儲存1,2,3只需要16bits整型即可,但65535需要32bits整型。

redis的做法,計算出公升級之後所需要的總空間,對contents進行重新分配,再從後向前拷貝元素。譬如說:

第一步:重新分配空間4*32 = 128bits

第二步:從後向前拷貝元素:先將3放到重新分配後索引2的位置,再將2放到重新分配後索引1的位置…最後將新加入的元素放到索引為3的位置。

static intset *intsetupgradeandadd(intset *is, int64_t value)

redis原始碼 整數集合

redis提供一種叫整數集合的資料結構,當資料中只包含整數,並且資料數量不多時,redis便會採用整數集合儲存 redis保證整數集合有以下幾個特性 所含元素全是整數,且不重複 內部元素有序,通常是會從小到大排序 內部編碼統一,盡可能採用合適的編碼儲存資料 當編碼不合適時,執行公升級操作 接下來會針...

Redis學習筆記 原始碼閱讀 整數集合

整數集合 intset 是乙個有序的 儲存整型資料的結構,當redis集合型別的元素都是整數並且都處在64位有符號整數範圍之內時,使用該結構體儲存。在兩種情況下,底層編碼會發生轉換。整數集合在redis中可以儲存int16 t int32 t int64 t型別的整型資料,並且可以保證集合中不會出現...

Redis原始碼解析 06整數集合

整數集合 intset 是集合鍵的底層實現之一,當乙個集合只包含整數值元素,並且這個集合的元素數量不多時,redis就會使用整數集合作為集合鍵的底層實現。intset可以儲存型別為int16 t,int32 t,int64 t的整數值,並且保證集合中不會出現重複元素。整數集合的結構體定義在intse...