redis数据结构之intset的实例详解

发布时间 - 2026-01-11 03:22:48    点击率:

redis数据结构之intset的实例详解

 在redis中,intset主要用于保存整数值,由于其底层是使用数组来保存数据的,因而当对集合进行数据添加时需要对集合进行扩容和迁移操作,因而也只有在数据量不大时redis才使用该数据结构来保存整数集合。其具体的底层数据结构如下:

typedef struct intset {
  
  // 编码方式
  uint32_t encoding;

  // 集合包含的元素数量
  uint32_t length;

  // 保存元素的数组
  int8_t contents[];

} intset;

      整数集合主要有三个属性:encoding用于保存当前集合的编码,有16位,32位和64位三种;length保存了当前整数集合中保存的数据数量;contents属性则保存了具体的数据,其每个数据占用的位数由encoding属性指定。

      这里主要需要进行说明的是redis的intset中数据是采用从小到大的顺序存储的,因而对于数据的查询可以采用二分法进行查询,具体的搜索代码如下:

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保存数据的示例:

如有疑问请留言或者到本站社区交流讨论,感谢阅读,希望能帮助到大家,谢谢大家对本站的支持!


# redis  # intset  # 数据结构之intset的使用方法  # Redis的六种底层数据结构(小结)  # 多维度深入分析Redis的5种基本数据结构  # 详解redis数据结构之压缩列表  # Redis中5种数据结构的使用场景介绍  # redis中跳表zset的具体使用  # redis使用skiplist跳表的原因解析  # 为何Redis使用跳表而非红黑树实现SortedSet  # Redis中的数据结构跳表详解  # 数据结构  # 都要  # 组中  # 不存在  # 指的是  # 转换为  # 的是  # 存了  # 就会  # 如有  # 较高  # 希望能  # 并将  # 三种  # 要对  # 如图  # 将它  # 谢谢大家  # 会为  # 唯一一 


相关栏目: 【 网站优化151355 】 【 网络推广146373 】 【 网络技术251813 】 【 AI营销90571


相关推荐: 香港服务器WordPress建站指南:SEO优化与高效部署策略  如何用AI一键生成爆款短视频文案?小红书AI文案写作指令【教程】  Win11怎么恢复误删照片_Win11数据恢复工具使用【推荐】  Laravel如何获取当前登录用户信息_Laravel Auth门面使用与Session用户读取【技巧】  如何用花生壳三步快速搭建专属网站?  JavaScript如何实现继承_有哪些常用方法  如何快速辨别茅台真假?关键步骤解析  Claude怎样写结构化提示词_Claude结构化提示词写法【教程】  如何在阿里云部署织梦网站?  Laravel如何记录自定义日志?(Log频道配置)  Laravel如何安装使用Debugbar工具栏_Laravel性能调试与SQL监控插件【步骤】  网站制作怎么样才能赚钱,用自己的电脑做服务器架设网站有什么利弊,能赚钱吗?  Edge浏览器提示“由你的组织管理”怎么解决_去除浏览器托管提示【修复】  HTML 中动态设置元素 name 属性的正确语法详解  如何构建满足综合性能需求的优质建站方案?  Win11任务栏卡死怎么办 Windows11任务栏无反应解决方法【教程】  Laravel如何发送邮件_Laravel Mailables构建与发送邮件的简明教程  Win11怎么关闭透明效果_Windows11辅助功能视觉效果设置  高性价比服务器租赁——企业级配置与24小时运维服务  javascript如何操作浏览器历史记录_怎样实现无刷新导航  什么是javascript作用域_全局和局部作用域有什么区别?  Laravel观察者模式如何使用_Laravel Model Observer配置  LinuxShell函数封装方法_脚本复用设计思路【教程】  手机怎么制作网站教程步骤,手机怎么做自己的网页链接?  如何快速上传建站程序避免常见错误?  Laravel怎么导出Excel文件_Laravel Excel插件使用教程  长沙做网站要多少钱,长沙国安网络怎么样?  网站制作企业,网站的banner和导航栏是指什么?  阿里云网站搭建费用解析:服务器价格与建站成本优化指南  Zeus浏览器网页版官网入口 宙斯浏览器官网在线通道  Laravel distinct去重查询_Laravel Eloquent去重方法  如何在IIS7上新建站点并设置安全权限?  如何在阿里云ECS服务器部署织梦CMS网站?  Laravel怎么做缓存_Laravel Cache系统提升应用速度的策略与技巧  桂林网站制作公司有哪些,桂林马拉松怎么报名?  Laravel如何设置定时任务(Cron Job)_Laravel调度器与任务计划配置  EditPlus中的正则表达式 实战(2)  Laravel怎么生成URL_Laravel路由命名与URL生成函数详解  香港服务器租用每月最低只需15元?  iOS正则表达式验证手机号、邮箱、身份证号等  手机网站制作平台,手机靓号代理商怎么制作属于自己的手机靓号网站?  Laravel Eloquent性能优化技巧_Laravel N+1查询问题解决  Laravel Eloquent:优雅地将关联模型字段扁平化到主模型中  Android实现代码画虚线边框背景效果  JS中使用new Date(str)创建时间对象不兼容firefox和ie的解决方法(两种)  制作网站软件推荐手机版,如何制作属于自己的手机网站app应用?  零基础网站服务器架设实战:轻量应用与域名解析配置指南  邀请函制作网站有哪些,有没有做年会邀请函的网站啊?在线制作,模板很多的那种?  独立制作一个网站多少钱,建立网站需要花多少钱?  Laravel API资源(Resource)怎么用_格式化Laravel API响应的最佳实践