BitMap实现数据压缩存储

相比于将数据的值直接进行存储,BitMap算法使用的是基于位的映射。

如果一组数据互相之间不重复,就可以将其映射到一个数组中,数组的长度即为(最大的数据的值-最小的数据的值),每一个元素用来存储对应位置是否存在数据,只有两种状态,0表示该位置的数值不存在,1表示存在。只要通过这一个数组就可以表示所有的数据。

如何实现压缩?

由上可知,使用BitMap算法,使用的空间大小是由数据的范围确定的,与数据量无关。即空间复杂度不随元素的个数增加而增加,而是随集合内最大元素的值的增加而增加。因为在最大最小值之间,不管是否存在数据,都要占用一个bit来表示状态。这样一来,就存在一个临界点,数据量大于这个范围,这样存储数据就会节省空间。

如果数据的类型为int型,即占用32个bit,数据个数为N,直接存储的数据大小为 4×N Byte。

如果使用BitMap,在最恶劣的情况下,这N个数据的最大值最小值正好是int型可以表示的最大最小值,则数组长度为2^{^{32}}-1

需要的空间为(2^{^{32}}-1)/8 Byte。

如果希望通过BitMap算法实现压缩,则:

(2^{^{32}}-1)/8 < 4*N

N = 134217727.96875,大概为1.34亿。也就是说数据个数超过1.34亿,使用BitMap一定会节省存储空间。可见在海量数据处理时可以应用到。

但是实际上,这N个数据的分布可能没有那么分散,相应的BitMap算法使用的空间就会减少,在数据量较小的情况下可能也能实现压缩。

一道面试题

给一台配置是2G内存,要处理一个包含40亿个不重复并且没有排过序的整数。那么问题在于,给出一个整数,怎么快速这个整数是否在这40亿数据中呢?

通过上面的分析,使用BitMap存储比较合适。

实际上,使用int型存储这40亿个整数,需要大概15GB空间,使用BitMap只需要476.83MB空间。如果不使用外部排序的话,使用普通的存储方法,内存空间甚至都不够用。

实际实现上,可以自己创建数据结构,比如利用byte数组,结合索引值存储;也可以使用java和c++中的bitset数据结构。

工作中的实际问题

在nand flash芯片中,有一块区域专门用来存储坏块(bad block)地址信息,在芯片测试过程中,有时需要将这些信息读取出来存储到log中,以便进行分析。但是在log传输的过程中,数据量很大(因为有一次测试就会有很多芯片),由于某些特殊原因,不能使用zip等方法压缩,所以就需要使用特殊方式重新组织信息,实现压缩。

因为原本的log只是用于打印查看,很多数据类型都使用int型,所以根据实际使用的空间,一些被优化为了byte类型,实现了一定程度的压缩。

由于坏块的地址信息肯定是唯一的,也就是数据不会重复出现,现在考虑是否可以使用BitMap实现进一步压缩。一块芯片上大概有2560个block,地址用两个Byte就足够存储。现假设bad block数量为N。

如果用普通方法,数据量为2×N Byte。

如果使用BitMap,因为每个block都可能是坏块,所以数组长度必须为2560,则数据量为320Byte。

所以只要芯片的坏块数量大于160,就能实现压缩。一个log中包含有很多的芯片信息,所以只要平均意义上的单芯片坏块数量超过这个值,就能实现压缩。

More

如果坏块的分布比较集中,还可以通过pair存储坏块信息,以(起始地址,结束地址)或(起始地址,长度)的方式存储。具体怎么存储更节约空间还要看坏块的分布情况。

参考

算法基础:生动理解BitMap算法

经典算法系列之(一) - BitMap [数据的压缩存储]

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值