roaringbitmap 源码解析(2) 底层三种容器containner对比

来源:互联网 发布:淘宝网抹胸连衣裙 编辑:程序博客网 时间:2024/06/04 01:17

首先对比一下,roaringbitMap里的三种container

原文地址:http://blog.csdn.net/chenfenggang/article/details/74781791

> /**  * Simple bitset-like container.  */

bitmapcontainer 定义了1024个long型,每个long占用64位。这样可以表达1024×64 =short 长度 16位
比如:12, 将第0个long置为1L<<12位。一个long 最多表示63.
如果需要表示64就需要用[64/64] =1 用第1个long。的第一位表示。
所以任何一个short表示为 [x/64]=1L<

> /**  * Simple container made of an array of 16-bit integers  */

当数据量小于4096时采用 short数组所占用的空间还小一些。所以定义了第二种容器,ArrayContainer。
ArrayContainer 用short数组来存储数据。并且按需扩展空间。而且数据按照有序排列。
比如存储12: 定义一个short [0] =12;
再添加15 ,找的末尾位置, short[1] = 15;
再添加14 ,找的中间位置。 将先移动数字 short【2】=15,然后放入 short【1】=14
系统默认生成4个单位的长度short,当长度小于1024的时候空间成倍数扩展,当大于1024时 ,按25%扩展。
这中数据存储方式对小量数据比较优化。

第三种方式runContainer.也就是采用run-length算法。
代码中说明了原理

// that if you have the values 11,12,13,14,15, you store that as 11,4 where 4 means that beyond 11// itself, there are// 4 contiguous values that follows.// Other example: e.g., 1, 10, 20,0, 31,2 would be a concise representation of 1, 2, ..., 11, 20,// 31, 32, 33

如果是连续的数据。采用RunContainer是最好不过了。比如存储1到100,200到300. 只需要存储。1,99,200,99就可以了。
前面位置表示起始位置,后面表示连续出现次数。
所以在定义range的时候一般用runbitmap ,比较稀疏的数据也可以用种方式。

public static Container rangeOfOnes(final int start, final int last) {  final int sizeAsArrayContainer = ArrayContainer.serializedSizeInBytes(last - start);  final int sizeAsRunContainer = RunContainer.serializedSizeInBytes(1);  Container answer =      sizeAsRunContainer < sizeAsArrayContainer ? new RunContainer() : new ArrayContainer();  answer = answer.iadd(start, last);  return answer;}

总之:roaringbitmap 在存储连续的时候用RunContainer()。否则会用ArrayContainer。当ArrayContainer数据满了,即大于4096时。转为BitmapContainer。

未完待续。。。

原创粉丝点击