数据结构

typedef struct intset {uint32_t encoding;uint32_t length;int8_t contents[];//一个字节} intset;int main() {struct intset *set = malloc(sizeof(struct intset));set->encoding = 1;set->length = 2;set->contents[0] = 1;set->contents[1] = 22;printf("内存地址0:%p\n", *&set);printf("内存地址1:%p\n", &set->encoding);printf("内存地址2:%p\n", &set->length);printf("内存地址3:%p\n", &set->contents[0]);printf("内存地址4:%p\n", &set->contents[1]);free(set);}//output如下//内存地址0:0x7fd8b0c05a20//内存地址1:0x7fd8b0c05a20//内存地址2:0x7fd8b0c05a24//内存地址3:0x7fd8b0c05a28//内存地址4:0x7fd8b0c05a29
在Redis的整数集合中, contents 数组的大小取决于 encoding的编码
#define INTSET_ENC_INT16 (sizeof(int16_t))#define INTSET_ENC_INT32 (sizeof(int32_t))#define INTSET_ENC_INT64 (sizeof(int64_t))//这里还涉及到字节顺
整数集合操作
创建
创建一个结构体(malloc),初始化
encodinglengthintset *intsetNew(void) {intset *is = zmalloc(sizeof(intset));is->encoding = intrev32ifbe(INTSET_ENC_INT16);is->length = 0;return is;}
插入
查找(数据是否存在)
intset没有数据,返回
- value大于最大 || value小于最小 , 返回
二分查找找到value (二分查找),算法无处不在
- 数据存在,返回1
数据不存在反问2
static uint8_t intsetSearch(intset *is, int64_t value, uint32_t *pos) {//数组长度int min = 0, max = intrev32ifbe(is->length)-1, mid = -1;int64_t cur = -1;//整数集合没有数据if (intrev32ifbe(is->length) == 0) {if (pos) *pos = 0;return 0;} else {//value大于最大 || value小于最小 , 返回if (value > _intsetGet(is,max)) {if (pos) *pos = intrev32ifbe(is->length);return 0;} else if (value < _intsetGet(is,0)) {if (pos) *pos = 0;return 0;}}//二分while(max >= min) {mid = ((unsigned int)min + (unsigned int)max) >> 1;cur = _intsetGet(is,mid);if (value > cur) {min = mid+1;} else if (value < cur) {max = mid-1;} else {break;}}//是否找到数据if (value == cur) {if (pos) *pos = mid;return 1;} else {if (pos) *pos = min;return 0;}}
删除
字节序
大端字节序和小端字节序
https://blog.erratasec.com/2016/11/how-to-teach-endian.html#.YjKhpxBByAl
encoding如何进行判定/* Return the required encoding for the provided value. */static uint8_t _intsetValueEncoding(int64_t v) {//超过32位最大的和小于32位最小的,使用64位if (v < INT32_MIN || v > INT32_MAX)return INTSET_ENC_INT64;else if (v < INT16_MIN || v > INT16_MAX)//超过16位最大的和小于16位最小的,使用32位return INTSET_ENC_INT32;else//剩下的全部使用16位return INTSET_ENC_INT16;}
