当前位置: 首页 > article >正文

Starrocks中RoaringBitmap杂谈

背景

最近在阅读Starrocks源码的时候,遇到ColumnRefSetRoaringBitmap使用,所以借此来讨论一下RoaringBitmap这个数据结构,这种思想是很值得借鉴的。
对于的实现可以参考一下

<dependency><groupId>org.roaringbitmap</groupId><artifactId>RoaringBitmap</artifactId><version>1.3.0</version>
</dependency>

的实现

杂谈

RoaringBitmap是高效压缩位图,简称RBM,我们可以通过Github RoaringBitmap了解它的全貌。

实现思路

  • 将 32bit int(无符号的)类型数据 划分为 2^16 个桶,即2^16=65536个桶,每个桶内用container来存放一个数值的低16位
  • 在存储和查询数值时,将数值划分为高16位和低16位,取高 16 位值找到对应的桶,然后在将低 16 位值存放在相应的 Container 中(存储时如果找不到就会新建一个)

举个例子:
以十进制数字131122为例,现在我们要将该数字放入到RBM中。第一步,先将该数字转换为16进制,131122对应的十六进制为0x00020032;其中,高十六位对应0x0002,首先我们找到0x0002所在的桶,再将131122的低16位存入到对应的container中,131122的低16位转换为10进制就是50,没有超过ArrayContainer的容量4096,所以将低16位直接放入到对应的ArrayContainer中。
在这里插入图片描述

如果要插入的数字低16位超过了4096,RBM会将ArrayContainer转换为BitMapContainer

具体的操作

摘抄自Github官网,如下

import org.roaringbitmap.RoaringBitmap;public class Basic {public static void main(String[] args) {RoaringBitmap rr = RoaringBitmap.bitmapOf(1,2,3,1000);RoaringBitmap rr2 = new RoaringBitmap();rr2.add(4000L,4255L);rr.select(3); // would return the third value or 1000rr.rank(2); // would return the rank of 2, which is index 1rr.contains(1000); // will return truerr.contains(7); // will return falseRoaringBitmap rror = RoaringBitmap.or(rr, rr2);// new bitmaprr.or(rr2); //in-place computationboolean equals = rror.equals(rr);// trueif(!equals) throw new RuntimeException("bug");// number of values stored?long cardinality = rr.getLongCardinality();System.out.println(cardinality);// a "forEach" is faster than this loop, but a loop is possible:for(int i : rr) {System.out.println(i);}}
}

container的类型

小桶的实现目前有三种:ArrayContainer,BitmapContainer,RunContainer。默认采用 ArrayContainer

  • ArrayContainer
    这个是 RoaringBitmap 默认小桶的实现,在初始化的时候,会初始化长度为4的ArrayContainer
    其内部实现是用 Char数组实现的

    public ArrayContainer(int capacity) {this.cardinality = 0;this.content = new char[capacity];
    }
    

    其中每个Char占用两个字节。
    从Add方法来看:

    @Override
    public Container add(final char x) {if (cardinality == 0 || (cardinality > 0&& (x) > (content[cardinality - 1]))) {if (cardinality >= DEFAULT_MAX_SIZE) {return toBitmapContainer().add(x);}if (cardinality >= this.content.length) {increaseCapacity();}content[cardinality++] = x;} else {int loc = Util.unsignedBinarySearch(content, 0, cardinality, x);if (loc < 0) {// Transform the ArrayContainer to a BitmapContainer// when cardinality = DEFAULT_MAX_SIZE // DEFAULT_MAX_SIZE值为4096if (cardinality >= DEFAULT_MAX_SIZE) {return toBitmapContainer().add(x);}if (cardinality >= this.content.length) {increaseCapacity();}// insertion : shift the elements > x by one position to// the right// and put x in it's appropriate placeSystem.arraycopy(content, -loc - 1, content, -loc, cardinality + loc + 1);content[-loc - 1] = x;++cardinality;}}return this;
    }
    
    • ArrayContainer内部的数据是排序的
    • 容量超过4096(这个是代码写死的)后,会转换为BitmapContainer
    • ArrayContainer占用的内存空间为 4096*2B ,即 8KB
  • BitmapContainer
    这个就是一个位图,这里的位图的长度为 2^16 ,也就是占用 2^16 bit,所有占用存储为8KB

  • RunContainer
    这是一种利用步长来压缩空间的方法,
    比如连续的整数序列 11, 12, 13, 14, 15, 27, 28, 29 会被 压缩为两个二元组 11, 4, 27, 2 表示:11后面紧跟着4个连续递增的值,27后面跟着2个连续递增的值,那么原先16个字节的空间,现在只需要8个字节,这种用的比较少

可以看到 ArrayContainer 占用的内存的最大空间为 8KB,和BitMapContainer占用的空间内存一样,但是ArrayContainer存储的数据最大为4096,超过这个以后,内存空间的占用就会超过8KB,所以从内存占用考虑的话,ArrayContainer适合存储稀疏数据,适合存储稠密数据,这样策略下,能够最大程度的避免内存浪费

查询的性能

和BitMap相比
  • Roaringbitmap本质上是将大块分为了各个小块,并且只有小块有数据的时候才会存在,所以Roaringbitmap在前16位的时候,就可以将部分数据过滤掉,而不像 BitMap一样,所有的位都需要进行计算

其他

除了 32位的RoaringBitmap外,还有64位的Roaring64Bitmap,如下:

    import org.roaringbitmap.longlong.*;// first Roaring64NavigableMapLongBitmapDataProvider r = Roaring64NavigableMap.bitmapOf(1,2,100,1000);r.addLong(1234);System.out.println(r.contains(1)); // trueSystem.out.println(r.contains(3)); // falseLongIterator i = r.getLongIterator();while(i.hasNext()) System.out.println(i.next());// second Roaring64Bitmapbitmap1 = new Roaring64Bitmap();bitmap2 = new Roaring64Bitmap();int k = 1 << 16;long i = Long.MAX_VALUE / 2;long base = i;for (; i < base + 10000; ++i) {bitmap1.add(i * k);bitmap2.add(i * k);}b1.and(bitmap2);

相关文章:

Starrocks中RoaringBitmap杂谈

背景 最近在阅读Starrocks源码的时候&#xff0c;遇到ColumnRefSet的RoaringBitmap使用&#xff0c;所以借此来讨论一下RoaringBitmap这个数据结构,这种思想是很值得借鉴的。 对于的实现可以参考一下 <dependency><groupId>org.roaringbitmap</groupId><…...

通过ca证书的方式设置允许远程访问Docker服务

设置允许远程访问Docker服务 使用场景 环境 系统&#xff1a;anolis7.9 修改Docker服务配置&#xff0c;配置安全证书 生成ca证书到/etc/docker目录中&#xff0c;后续会要用到 #该步骤需要设置密码&#xff0c;后面步骤会要用到&#xff0c;此处设置密码为123456 openss…...

涂胶协作机器人解决方案 | Kinova Link 6 Cobot在涂胶工业的方案应用与价值

涂胶工业现状背景&#xff1a; 涂胶工艺在汽车制造、电子组装、航空航天等工业领域极为关键&#xff0c;关乎产品密封、防水、绝缘性能及外观质量。 然而&#xff0c;传统涂胶作业问题频发。人工操作重复性强易疲劳&#xff0c;涂胶质量波动大&#xff1b;大型涂胶器使用增加工…...

理解继承与组合的本质:Qt 项目中的设计选择指南

文章目录 理解继承与组合的本质&#xff1a;Qt 项目中的设计选择指南一、继承与组合的本质区别1. 继承&#xff08;Inheritance&#xff09;2. 组合&#xff08;Composition&#xff09; 二、继承的适用场景三、组合的适用场景四、错误使用继承的后果五、判断继承或组合的三问法…...

新手小白使用VMware创建虚拟机安装Linux

新手小白想要练习linux&#xff0c;找不到合适的地方&#xff0c;可以先创建一个虚拟机&#xff0c;在自己创建的虚拟机里面进行练习&#xff0c;接下来我给大家接受一下创建虚拟机的步骤。 VMware选择创建新的虚拟机 选择自定义 硬件兼容性选择第一个&#xff0c;不同的版本&a…...

使用 PHP 和 Guzzle 对接印度股票数据源API

对接 StockTV API 可能涉及获取实时或历史的金融市场数据&#xff0c;如股票价格、交易量、市场新闻等。为了帮助你更好地理解如何使用 PHP 对接 StockTV API&#xff0c;下面我将提供一个通用指南和示例代码。 前提条件 注册并获取API密钥&#xff1a;首先你需要在 StockTV …...

EscapeX:去中心化游戏,开启极限娱乐新体验

VEX 平台推出全新去中心化游戏 EscapeX&#xff08;数字逃脫&#xff09;&#xff0c;创新性地将大逃杀玩法与区块链技术相融合。用户不仅能畅享紧张刺激的解谜过程&#xff0c;更能在去中心化、公正透明的环境中参与游戏。EscapeX 的上线&#xff0c;为 VEX 生态注入全新活力&…...

使用PyQt5的图形用户界面(GUI)开发教程

文章目录 写在前面一、PyQt5的安装1.1 使用Conda管理环境1.1.1 新建环境1.1.2 conda list和pip list的区别1.1.3 conda install和pip install的区别 1.2 安装PyQt5和Qt Designer1.3 VsCode中配置Qt Designer 二、PyQt5的UI设计2.1 .ui文件设计2.2 .qrc文件建立2.3 qss设计 三、…...

STM32实战:智能环境监测站设计方案

下面是一个基于STM32的智能环境监测站设计方案&#xff0c;使用Keil MDK-ARM开发环境。这个系统集成了多种传感器&#xff0c;并通过OLED显示数据&#xff0c;同时具备数据存储和报警功能。 [STM32F4系列MCU] ├── I2C总线 │ ├── SHT30温湿度传感器 │ ├──…...

猎板硬金镀层厚度:新能源汽车高压系统的可靠性基石

在新能源汽车的电池管理系统&#xff08;BMS&#xff09;和电机控制器中&#xff0c;硬金镀层厚度直接关系到高压环境下的电气稳定性与使用寿命。猎板针对车载场景开发的耐电迁移方案&#xff08;金层 2.5μm&#xff0c;镍层 8μm&#xff09;&#xff0c;经 150℃/85% RH 高压…...

KEYSIGHT是德科技 E5063A 18G ENA系列网络分析仪

KEYSIGHT是德科技 E5063A 18G ENA系列网络分析仪 E5063A ENA 矢量网络分析仪 18GHz 2端口 降低无源射频元器件的测试成本 Keysight E5063A ENA 是一款经济适用的台式矢量网络分析仪&#xff0c;可用于测试简单的无源元器件&#xff0c;例如频率最高达到 18 GHz 的天线、滤…...

VR 虚拟仿真工器具:开启医学新视界的智慧钥匙​

VR 虚拟仿真工器具在医疗领域的应用&#xff0c;为医疗行业的发展带来了新的机遇。在手术模拟训练中&#xff0c;它让医生提前熟悉手术流程和操作技巧。对于一些复杂的手术&#xff0c;如心脏搭桥手术、神经外科手术等&#xff0c;手术难度大、风险高&#xff0c;对医生的操作技…...

webshell管理工具、C2远控服务器流量分析

文章目录 一、Webshell管理工具流量分析1. 蚁剑&#xff08;AntSword&#xff09;2. 冰蝎&#xff08;Behinder&#xff09;3. 哥斯拉&#xff08;Godzilla&#xff09;二、常见C2远控服务器流量分析1. Metasploit2. CobaltStrike 三、防御对抗策略总结 一、Webshell管理工具流…...

JavaWeb:前端工程化-TS(TypeScript)

概述 快速入门 常用类型 基础类型 联合类型 函数类型 对象类型 接口Interface Interface和type区别 典型推论...

unity+ spine切换武器不换皮肤解决方案

1.在spine编辑中获取到角色武器插槽名称 这里的武器插槽名称为“zj_22”。角色的spine正常导出到unity中。 2.将需要替换的武器图片单独放在一个spine项目里面&#xff0c;并为每个武器单独建立一个插槽。 而且全部放在根骨骼Root下。 3.将武器的spine动画导出&#xff0c;会…...

[java八股文][MySQL面试篇]SQL基础

NOSQL和SQL的区别&#xff1f; SQL数据库&#xff0c;指关系型数据库 - 主要代表&#xff1a;SQL Server&#xff0c;Oracle&#xff0c;MySQL(开源)&#xff0c;PostgreSQL(开源)。 关系型数据库存储结构化数据。这些数据逻辑上以行列二维表的形式存在&#xff0c;每一列代表…...

Ubuntu中SSH服务器安装使用

SSH服务安装 1. 安装 OpenSSH 安装 SSH 服务端&#xff08;允许远程登录&#xff09; sudo apt update sudo apt install openssh-server安装 SSH 客户端&#xff08;用于连接其他服务器&#xff09; sudo apt install openssh-client2. 检查 SSH 服务状态 sudo systemctl…...

【AI论文】SWE-rebench:一个用于软件工程代理的任务收集和净化评估的自动化管道

摘要&#xff1a;基于LLM的代理在越来越多的软件工程&#xff08;SWE&#xff09;任务中显示出有前景的能力。 然而&#xff0c;推进这一领域面临着两个关键挑战。 首先&#xff0c;高质量的训练数据稀缺&#xff0c;尤其是反映现实世界软件工程场景的数据&#xff0c;在这些场…...

Flask文件处理全攻略:安全上传下载与异常处理实战

&#x1f49d;&#x1f49d;&#x1f49d;欢迎莅临我的博客&#xff0c;很高兴能够在这里和您见面&#xff01;希望您在这里可以感受到一份轻松愉快的氛围&#xff0c;不仅可以获得有趣的内容和知识&#xff0c;也可以畅所欲言、分享您的想法和见解。 推荐&#xff1a;「storms…...

【算法深练】分组循环:“分”出条理,化繁为简

目录 引言 分组循环 2760. 最长奇偶子数组 1446. 连续字符 1869. 哪种连续子字符串更长 2414. 最长的字母序连续子字符串的长度 3456. 找出长度为 K 的特殊子字符串 1957. 删除字符使字符串变好 674. 最长连续递增序列 978. 最长湍流子数组 2110. 股票平滑下跌阶段的…...

焊缝缺陷焊接缺陷识别分割数据集labelme格式5543张4类别

数据集中有超过一半为增强图片&#xff0c;请认真观察图片预览 数据集格式&#xff1a;labelme格式(不包含mask文件&#xff0c;仅仅包含jpg图片和对应的json文件) 图片数量(jpg文件个数)&#xff1a;5543 标注数量(json文件个数)&#xff1a;5543 标注类别数&#xff1a;4…...

关于scrapy在pycharm中run可以运行,但是debug不行的问题

关于scrapy在pycharm中run模式可以运行&#xff0c;但是debug模式不行的问题 文章目录 关于scrapy在pycharm中run模式可以运行&#xff0c;但是debug模式不行的问题查了下原因 点击run就可以运行&#xff0c;但是debug就是运行不了 一点击debug就报这个错&#xff0c;也不知道啥…...

Java高级 | 【实验四】Springboot 获取前端数据与返回Json数据

隶属文章&#xff1a; Java高级 | &#xff08;二十二&#xff09;Java常用类库-CSDN博客 系列文章&#xff1a; Java高级 | 【实验一】Spring Boot安装及测试 最新-CSDN博客 Java高级 | 【实验二】Springboot 控制器类相关注解知识-CSDN博客 Java高级 | 【实验三】Springboot …...

云数据库选型指南:关系型 vs NoSQL vs NewSQL的企业决策

在云时代&#xff0c;数据库选型直接关系到企业应用性能和成本效益。本文深入分析三大数据库类型&#xff0c;助您做出明智决策。 目录概览 关系型数据库&#xff1a;经典之选NoSQL数据库&#xff1a;灵活应对非结构化数据NewSQL数据库&#xff1a;融合的优势三大数据库对比分…...

Prj08--8088单板机C语言8255读取按键码

1.验证结果 2.代码片 key_codeinp(PORT_8255_C)&0x0f;tiny_sprintf(buffer,"Key_code 0X%x \r\n",key_code);uart_str_send(buffer); 3.完整代码 #include "tiny_stdarg.h" // 使用自定义可变参数实现#define ADR_273 0x0200 #define ADR_244 0x…...

蜜獾算法(HBA,Honey Badger Algorithm)

2021年由Hashim等人提出&#xff08;论文&#xff1a;Honey Badger Algorithm: A New Metaheuristic Algorithm for Solving Optimization Problems&#xff09;。模拟蜜獾在自然界中的智能捕食行为&#xff0c;属于群体智能优化算法&#xff08;与粒子群PSO、遗传算法GA同属一…...

Modbus转Ethernet IP网关助力罗克韦尔PLC数据交互

在工业自动化领域&#xff0c;Modbus协议是一种广泛应用的串行通信协议&#xff0c;它定义了主站和从站之间的通信规则和数据格式。罗克韦尔PLC是一种可编程的逻辑控制器&#xff0c;通过Modbus协议实现与其他设备之间的数据交互。然而&#xff0c;随着以太网技术的普及和发展&…...

飞算JavaAI 炫技赛重磅回归!用智能编码攻克老项目重构难题

深夜还在排查十年前Hibernate框架埋下的N1查询隐患&#xff1f;跨语言迁移时发现SpringMVC控制器里的业务逻辑像一团乱麻&#xff1f;当企业数字化进入深水区&#xff0c;百万行代码的老系统就像一座随时可能崩塌的"技术债冰山"。近日&#xff0c;飞算科技发布JavaAI…...

青少年编程与数学 02-020 C#程序设计基础 15课题、异常处理

青少年编程与数学 02-020 C#程序设计基础 15课题、异常处理 一、异常1. 异常的分类2. 异常的作用小结 二、异常处理1. 异常处理的定义2. 异常处理的主要组成部分3. 异常处理的作用小结 三、C#异常处理1. 异常的基本概念2. 异常处理的关键字3. 异常处理的流程4. 自定义异常5. 异…...

Electron打包前端和后端为exe

文章目录 什么是Electron&#xff1f; 安装electron过程 其他git项目地址比较好的文章electron的替代品安装报错 npm ERR! request to https://registry.npm.taobao.org/electron failed, reason: certificate has expired安装提示 npm WARN deprecated boolean3.2.0: Package …...