Bitmap、BitSet持久化存储
关于Bitmap的算法我在这里就不写了,这里主要提供一个持久化存储的思想。BitSet实现了Bitmap,BitSet还有很多方法可以查阅API。
// 创建BitSet对象
BitSet bitSet = new BitSet(10000000);
// 将BitSet对象转换为long或byte类型的数组
//就可以将数组存储在HBase、MongoDB等数据库,
long[] longs = bitSet.toLongArray();
byte[] bytes = bitSet.toByteArray();
//用的时候再将数据读出来转换为BitSet对象
BitSet bitSet1 = BitSet.valueOf(longs);
BitSet bitSet2 = BitSet.valueOf(bytes);
RoaringBitmap
RoaringBitmap适合存储稀疏的数据,是对BitMap算法的优化,RoaringBitmap持久化存储思想一样,代码如下:
RoaringBitmap rbm = new RoaringBitmap();
// 序列化为byte数组,就可以保存到数据库了
byte[] array = new byte[rbm.serializedSizeInBytes()];
rbm.serialize(ByteBuffer.wrap(array));
// 使用的时候在反序列化
RoaringBitmap rbm2= new RoaringBitmap();
rbm2.deserialize(ByteBuffer.wrap(array));
注意:
如果要将序列化的byte数组转换为字符串,需要指定编码,否则结果会出现问题(反序列化结果会出现问题)。
org.roaringbitmap.InvalidRoaringFormat: I failed to find one of the right cookies.
这个错误,也可以使用以下方法解决。
RoaringBitmap rbm = new RoaringBitmap();
// 序列化为byte数组,就可以保存到数据库了
byte[] array = new byte[rbm.serializedSizeInBytes()];
rbm.serialize(ByteBuffer.wrap(array));
//将byte数组转换为字符串 ,字符串就可以通过网络传输了
String str = new String(array,StandardCharsets.ISO_8859_1);
//将字符串转换为byte数组
byte[] array1 = str.getBytes(StandardCharsets.ISO_8859_1);
// 使用的时候在反序列化
RoaringBitmap rbm2= new RoaringBitmap();
rbm2.deserialize(ByteBuffer.wrap(array1));
EWAHCompressedBitmap
如果对连续的数据进行排序或存储连续的数据可以使用EWAHCompressedBitmap,这是Google开发的,只要是连续的数据特别特别节省空间。如存1~20亿应该还不到1M。
**注意:**数据小编是存在HBase上,大家可以根据数据量选择存储系统。使用HBase存单个较大的BitMap还有一个坑,可以参考博客:
解决HBase一个cell存储超10M的异常:https://blog.csdn.net/z1987865446/article/details/118771268