redis数据结构之intset的实例详解
GPT4.0+Midjourney绘画+国内大模型 会员永久免费使用!
【 如果你想靠AI翻身,你先需要一个靠谱的工具! 】
redis数据结构之intset的实例详解
在redis中,intset主要用于保存整数值,由于其底层是使用数组来保存数据的,因而当对集合进行数据添加时需要对集合进行扩容和迁移操作,因而也只有在数据量不大时redis才使用该数据结构来保存整数集合。其具体的底层数据结构如下:
1 2 3 4 5 6 7 8 9 10 11 12 | typedef struct intset { // 编码方式 uint32_t encoding; // 集合包含的元素数量 uint32_t length; // 保存元素的数组 int8_t contents[]; } intset; |
整数集合主要有三个属性:encoding用于保存当前集合的编码,有16位,32位和64位三种;length保存了当前整数集合中保存的数据数量;contents属性则保存了具体的数据,其每个数据占用的位数由encoding属性指定。
这里主要需要进行说明的是redis的intset中数据是采用从小到大的顺序存储的,因而对于数据的查询可以采用二分法进行查询,具体的搜索代码如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 | 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 ; /* The value can never be found when the set is empty */ // 处理 is 为空时的情况 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 比数组中最后一个值都要大 // 那么 value 肯定不存在于集合中, // 并且应该将 value 添加到底层数组的最末端 if (value > _intsetGet(is,intrev32ifbe(is->length)- 1 )) { if (pos) *pos = intrev32ifbe(is->length); return 0 ; // 因为底层数组是有序的,如果 value 比数组中最前一个值都要小 // 那么 value 肯定不存在于集合中, // 并且应该将它添加到底层数组的最前端 } else if (value < _intsetGet(is, 0 )) { if (pos) *pos = 0 ; return 0 ; } } // 在有序数组中进行二分查找 // T = O (log N ) 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 ; } } // 检查是否已经找到了 value if (value == cur) { if (pos) *pos = mid; return 1 ; } else { if (pos) *pos = min; return 0 ; } } |
此外,整数集合中具体还有两个需要说明的操作是升级和降级。升级指的是当向低编码的整数集合中添加位数较高的数值时,就会扩容并将整数集合中的所有元素都转换为高位数的编码格式,然后把新添加的元素插入到指定位置;降级指的是当将整数集合中唯一一个高位的元素删除时会将其余元素转换为低位数的编码格式,但是为了提升速率,redis中并不会为剩余元素重新分配内存并进行编码转换,而只是会将该高位元素给删除,并重新分配内存给剩余的元素,然后迁移数据。如图是inset保存数据的示例:
如有疑问请留言或者到本站社区交流讨论,感谢阅读,希望能帮助到大家,谢谢大家对本站的支持!

微信公众号搜索 “ 脚本之家 ” ,选择关注
程序猿的那些事、送书等活动等着你
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若内容造成侵权/违法违规/事实不符,请将相关资料发送至 reterry123@163.com 进行投诉反馈,一经查实,立即处理!
相关文章
CentOS7.5使用mysql_multi方式安装MySQL5.7.28多实例(详解)
这篇文章主要介绍了CentOS7.5使用mysql_multi方式安装MySQL5.7.28多实例,非常不错,具有一定的参考借鉴价值,需要的朋友可以参考下2020-01-01RedisTemplate 实现基于Value 操作的简易锁机制(示例代码)
本文将介绍如何使用 RedisTemplate 的 opsForValue().setIfAbsent() 方法来实现一种简单的锁机制,并提供一个示例代码,展示如何在 Java 应用中利用这一机制来保护共享资源的访问,感兴趣的朋友跟随小编一起看看吧2024-05-05
最新评论