首先对比一下,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。
未完待续。。。