- 1、原创力文档(book118)网站文档一经付费(服务费),不意味着购买了该文档的版权,仅供个人/单位学习、研究之用,不得用于商业用途,未经授权,严禁复制、发行、汇编、翻译或者网络传播等,侵权必究。。
- 2、本站所有内容均由合作方或网友上传,本站不对文档的完整性、权威性及其观点立场正确性做任何保证或承诺!文档内容仅供研究参考,付费前请自行鉴别。如您付费,意味着您自己接受本站规则且自行承担风险,本站不退款、不进行额外附加服务;查看《如何避免下载的几个坑》。如果您已付费下载过本站文档,您可以点击 这里二次下载。
- 3、如文档侵犯商业秘密、侵犯著作权、侵犯人身权等,请点击“版权申诉”(推荐),也可以打举报电话:400-050-0827(电话支持时间:9:00-18:30)。
- 4、该文档为VIP文档,如果想要下载,成为VIP会员后,下载免费。
- 5、成为VIP后,下载本文档将扣除1次下载权益。下载后,不支持退款、换文档。如有疑问请联系我们。
- 6、成为VIP后,您将拥有八大权益,权益包括:VIP文档下载权益、阅读免打扰、文档格式转换、高级专利检索、专属身份标志、高级客服、多端互通、版权登记。
- 7、VIP文档为合作方或网友上传,每下载1次, 网站将根据用户上传文档的质量评分、类型等,对文档贡献者给予高额补贴、流量扶持。如果你也想贡献VIP文档。上传文档
查看更多
Bitmap - 功能和原理争辩
从最原始的Bitmap到RoaringBitmap(可能是目前大多数场景的最佳选择?),虽然认真争辩Roaring的原理并不简单,但也是经过了十几年的变化和迭代。
WAH(Word Aligned Hybrid)
这个算法只压缩全0或者全1的group。将全部bits依据连续的31bit进行分组,然后对每一组进行编码,编码后的长度为32bit。具体结构如下图所示:
EWAH(Enhanced Word Aligned Hybrid)
基于WAH加了一个Header,作为元信息的存储。我理解这其实并没有在存储上做到太多挂念的优化,反而是在查询或者插入中,会愈加便捷。Header结构如下所示。
CONCISE(Compressed N Composble Integer Set)
这也是基于WAH做的一个优化。在WAH算法中,只需有一个bit被置1,那么整个group都无法被压缩,这一算法在这种odd bit上做了优化。记录了这个单一odd bit的位置。
VALWAH(Variable-Aligned Length WAH)
基于参数的优化,缓解了WAH的每个group固定32bit的限制(由于32bit最多能表示2^31 - 1个压缩group,但是实际上不会那么多)。接受了参数去调控,没有固定的规章,对于不同的bitmap自动接受不同的参数,很影响查询的效率。
Roaring
以65535bit分bucket,每个bucket里的integer共享高16bit(为bucket的编号),例如第一个bucket为[0 ~ 65535],高16bit为0,其次个bucket为[65536 ~ 65536*2 - 1],高16bit为1。其中,65536中以short integer(16bit)为单位表示integer的低16bit。所以当这个bucket中integer 个数 4096时,不存在压缩。
RoaringBitmap源码解读
RoaringBitmap的基本构成如下:HighLowContainer中存储了每个Integer的高16bit的公共索引keys以及具体存储数字的Container。由于Container是最终的载体,所以优化基本都在Container里。下面直接分析源码中的Add方法,通过这个方法基本上可以看出Container的内部结构。
先看一个代码里比较常消灭的binarySearch方法,这里比较机警的一点是,假如找到则前往对应的index,假如没找到则前往对应位置的负数,这样既可以传递位相信息,又可以传递能否存在的信息。
protected static int hybridUnsignedBinarySearch(final short[] array, final int begin, final int end, final short k) { int ikey = toIntUnsigned(k); // next line accelerates the possibly common case where the value would // be inserted at the end if ((end 0) (toIntUnsigned(array[end - 1]) ikey)) { return -end - 1; } int low = begin; int high = end - 1; // 32 in the next line matches the size of a cache line while (low + 32 = high) { final int middleIndex = (low + high) 1; final int middleValue = toIntUnsigned(array[middleIndex]); if (middleValue ikey) { low = middleIndex + 1; } else if (middleValue ikey) { high = middleIndex - 1; } else { return middleIndex; } } // we finish the job with a sequential search int x = low; for (; x = high; ++x) {
文档评论(0)