Roaring Bitmap

Roaring Bitmap 是一种专门为大规模整数集合设计的高性能压缩位图数据结构。它的核心目标是同时解决传统位图和压缩位图的两个致命痛点:

  • 传统位图(Fixed Bitset) :查询快(O(1)),但空间浪费严重。例如要存储文档 ID {1, 1000000},仍需分配 100万位的内存。
  • 简单压缩位图(如 RLE / Elias-Fano):空间省,但随机访问慢。查找第 N 个元素或判断某个 ID 是否存在往往需要 O(N) 的线性扫描解压。

Roaring Bitmap 通过分块 + 自适应编码 完美兼顾了两者:既支持 O(1) 级别的随机访问,又能根据数据密度自动选择最优压缩策略 。这正是 Lucene IndexedDISI 直接借鉴它的原因。

🔑 核心原理:65536 分块 + 三种容器

容器类型 触发条件 存储方式 特点
Array Container 基数 < 4096 排序的 short[] 数组 稀疏时比位图更省空间;二分查找 O(log n)
Bitmap Container 基数 ≥ 4096 固定 8KB 位图 (65536 bits) 稠密时 O(1) 随机访问;交集/并集可用 SIMD 加速
Run Container 存在长连续区间 (start, length) 对的数组 对连续段极其高效;适合有序递增数据

🗺️ 全局索引结构

除了桶内容器,Roaring Bitmap 还维护一个顶层目录:

  • 一个排序的高 16 位键数组(short[] keys)
  • 对应的容器指针/偏移数组

这使得定位任意整数的过程为:

  1. 在 keys 中二分查找高 16 位 → 找到对应容器
  2. 在容器内用低 16 位做 O(1) 或 O(log n) 查找

整体查找复杂度为 O(log n + container_op),远优于线性扫描。

🔗 为什么 Lucene IndexedDISI 要借鉴它?

回到你引用的那段注释,IndexedDISI 的需求是:

  • 在磁盘上存储稀疏文档 ID 列表
  • 支持 advance(target) 快速跳转
  • 支持 index() 返回当前文档的 ordinal(即"这是第几个匹配文档")
  • 空间开销可控

这与 Roaring Bitmap 的设计目标高度吻合:

Roaring Bitmap 特性 IndexedDISI 对应实现
65536 分块 相同的 block size
Array / Bitmap / Run 三态 SPARSE / DENSE / ALL 三态(去掉了 Run,因为 DocID 通常不够连续)
顶层 keys 目录 块查找表(int-pair 数组,存累计 index + 字节 offset)
Bitmap Container 内的 rank/select DENSE 块的 Rank 结构(byte-pair 子块计数)
容器按需加载 MMap + 只读取目标 block,避免全量加载

IndexedDISI 本质上是 Roaring Bitmap 的磁盘化、只读化、ordinal-aware 特化版本。它去掉了写入和修改能力,换来了更极致的磁盘布局优化(比如把 Rank 结构放在 DENSE 块头部保证局部性,把查找表放在文件尾部便于一次性读入内存)。

🌍 超越 Lucene 的影响

Roaring Bitmap 已成为现代数据基础设施的事实标准:

  • 数据库:Apache Druid、ClickHouse、StarRocks 用它做倒排索引和物化视图
  • OLAP:Apache Spark、Flink 用它做 Shuffle 阶段的 ID 传递
  • 搜索引擎:Elasticsearch、Solr、Vespa 底层都依赖它
  • Java 生态 :官方库 org.roaringbitmap:RoaringBitmap 被广泛使用

理解 Roaring Bitmap,就理解了现代系统中"如何在有限内存/磁盘中高效表达和操作大规模离散集合 "这一通用范式。而 IndexedDISI 正是这一范式在搜索场景下最精致的工程实现之一。

相关推荐
非优秀程序员2 小时前
第04章 邮箱大战,163 与 QQ 的暗战|《互联网产品恩仇录》
java·vue.js·架构
知已难寻2 小时前
Docker 入门:容器技术与 Docker 基础
java·运维·服务器·docker·云原生·容器
沐晓时光3 小时前
C语言入门,内存函数知识讲解
c语言·开发语言
文丑颜不良啊4 小时前
LeetCode2481~2500题目解析
java·leetcode
Flynn Liang6 小时前
同一需求三套写法:用 Spring AI、LangChain4j、AgentScope Java 各实现一个带工具调用的 RAG 助手(实战对比)
java·人工智能·大模型·架构设计·spring ai·langchain4j·agentscope
聪明的笨猪猪6 小时前
实际工程问题:AI 生成 Spring Cache(@Cacheable / @CachePut / @CacheEvict)缓存注解踩坑
java·经验分享·面试·ai编程
愿有所息6 小时前
记一次 ARM64 + JDK8 上 fastjson2 的诡异数据错乱
java
秋饼7 小时前
MCP 2026-07-28 无状态协议大改版:Spring AI 2.1 多轮往返请求与网关路由落地
java·ai·技术分享·后端开发
SL_staff8 小时前
JVS-BI 实战:业务人员如何用零代码 ELT + 可视化配置构建实时经营分析闭环
java·spring·全栈
SL_staff8 小时前
企业AI落地难?JVS-AI渐进式实践:安全可控、小切口验证、标准化沉淀与规模化复制
java·开源·aigc