【RoaringBitmap】详解

RoaringBitmap

参考:原作者

介绍

以一个“40亿个数据是4个字节的unsigned int 型的数据”为例。

1.直接存储。(40 * 10^8) * 4byte = 14.9GB (1GB=210Mb=220kb=2^30byte);

2.采用位图(bitmap)存储。40亿个数据都是位于[0, 2^32 - 1],每一位指的是一个bit位,而1byte(1字节)是8个bit,2^32bit = 2^29byte = 219kbyte=29Mb=512Mb;

如果数据很稀疏,例如:统计某个应用的用户数,用户id范围为[0, 2^32 - 1],如果只有几个用户在线时,还需要开辟512M的存储空间,那么浪费就大了。

于是出现了“位图压缩的方式”,roaringBitMap就是其中一种。
roaringbitmap属于是位图的一个进化,即压缩位图。在roaringbitmap中不只包含bitmap这一种数据结构,而是包涵了多种存储的方式,以此来达到压缩位图的目的。

roaringbitmap是高效压缩位图,简称RBM

官网对其的介绍:Roaring bitmaps are compressed bitmaps. They can be hundreds of times faster.

RBM的历史并不长,它于2016年由S. Chambi、D. Lemire、O. Kaser等人在论文《Better bitmap performance with Roaring bitmaps》与《Consistently faster and smaller compressed bitmaps with Roaring》中提出.

原理

  1. 将 32bit int(无符号的)类型数据 划分为 2^16 个桶,即最多可能有216=65536个桶,论文内称为container。用container来存放一个数值的低16位
  2. 在存储和查询数值时,将数值 k 划分为高 16 位和低 16 位,取高 16 位值找到对应的桶,然后在将低 16 位值·存放在相应的 Container 中(存储时如果找不到就会新建一个)

注意:大家需要注意大桶里面的各个小桶(container)是在需要的时候才会申请开辟

比如要将31这个数放进roarigbitmap中,它的16进制为:0000001F,前16位为0000,后16为001F。
所以先需要根据前16位的值:0,找到它对应的通的编号为0,然后根据后16位的值:31,确定这个值应该放到桶中的哪一个位置,如下图所示。
在这里插入图片描述

roaringBigMap有四种小桶container类型:

1.arraycontainer(数组容器)
container默认使用arraycontainer(元素都是按从大到小的顺序排列的),由于container只有16位bit位,最大[0-65535),则用short int类型(占两个字节)即可。当ArrayContainer的容量超过4096(这里是指4096个short int即8k Byte)后,切换为bitmapcontainer(这个所占空间始终都是8k Byte,也就是16位bit)。即ArrayContainer存储稀疏数据,BitmapContainer存储稠密数据,可以最大限度地避免内存浪费。如下内存使用图:
在这里插入图片描述

2.bitmapcontainer(位图容器)
和前面的位图一样,只不过这里位图的位数为216(65536)个,也就是216个bit,计算下来起所占内存就是8kb。
3.runcontainer(行程步长容器)
一种利用步长来压缩空间的方法。
比如连续的整数序列 11, 12, 13, 14, 15, 27, 28, 29 会被 压缩为两个二元组 (11, 4),(27, 2) :11后面紧跟着4个连续递增的值,27后面跟着2个连续递增的值,那么原先16个字节的空间,现在只需要8个字节,是不是节省了很多空间呢。不过这种容器不常用。
4.sharedcontainer(共享容器)
它本身是不存储数据的,只是用它来指向arraycontainer,bitmapcontainer或runcontainer,就好比指针的作用一样。这个指针(sharedcontainer)可以被多个对象拥有,但是指针所指针的实质东西是被这多个对象所共享的。
使用:进行roaringbitmap之间的拷贝的时候,有时并不需要将一个container拷贝多份。那么我们就可以使用sharedcontainer来指向实际的container,然后把sharedcontainer赋给多个roaringbitmap对象持有,这个roaringbitmap对象就可以根据sharedcontainer找到真正存储数据的container,这可以省去不必要的空间浪费。
在这里插入图片描述

与bitmap性能的对比

  1. 空间节省:bitmap比较适用于数据分布比较稠密的存储场景中;roarringBitMap在稀疏存储上空间更省,稠密和bitMap一致;
  2. 更高效的做交、并操作。
    a、逻辑结构节省计算量:将大块的bitmap分成各个小块,其中每个小块在需要存储数据的时候才会存在。所以当进行交集或并集运算的时候,只需要去计算存在的一些块,而不需要像bitmap那样对整个大的块进行计算。这里既不是用空间换时间,也没有用时间换空间,而是用逻辑的复杂度同时换取了空间和时间。
    b、逻辑结构优化程序:roaringbitmap维护了排好序的一级索引,以及有序的arraycontainer当进行交集操作的时候;计算时,根据需要在一级索引中找需要的内容。
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值