整数集合inset是当一个集合中只包含整数值元素,并且这个集合元素不多时,redis就只用inset来保存
这个集合,inset支持升级操作,所谓升级是值将数据类型有int16升级为int32的动作,但是目前
不支持降级操作。inset中的元素是按照从小到大排列的。
redis中的inset用如下结构体表示
typedef struct intset {
uint32_t encoding;
//集合中的总的个数,应该等于contents 数组的长度
uint32_t length;
// inset中的元素都是保存在这个数组中
int8_t contents[];
} intset;
intsetNew 函数用于新建一个新的inset。其实现如下:
intset *intsetNew(void) {
// 为整数集合结构分配空间
intset *is = zmalloc(sizeof(intset));
// 设置编码方式,原来encoding 表示保存在inset中的数据类型啊,且默认类型是INT16
is->encoding = intrev32ifbe(INTSET_ENC_INT16);
is->length = 0;
// 返回指针
return is;
}
inset的查找函数实现如下:
tatic 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;
/* The value can never be found when the set is empty */
// 如果inset 为null ,则返回零
if (intrev32ifbe(is->length) == 0) {
if (pos) *pos = 0;
return 0;
} else {
/* Check for the case where we know we cannot find the value,
* but do know the insert position. */
// 检查形参value是否比inset最后一个元素还大
if (value > _intsetGet(is,intrev32ifbe(is->length)-1)) {
if (pos) *pos = intrev32ifbe(is->length);
return 0;
// 检查形参value是否比inset的第一个元素还小
} else if (value < _intsetGet(is,0)) {
if (pos) *pos = 0;
return 0;
}
}
// 在从小到大排列的inset 这个有序表中进行二分法查找,可以知道在一个有序表中
// 二分法的查找效率最高
while(max >= min) {
mid = (min+max)/2;
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;
}
}
redis中的intset
最新推荐文章于 2025-06-22 23:02:58 发布