迭代器和序列化和反序列化
serialize:都很简单。
ArrayContainer
@Override
public void serialize(DataOutput out) throws IOException {
out.writeShort(Short.reverseBytes((short) this.cardinality));
// little endian
for (int k = 0; k < this.cardinality; ++k) {
out.writeShort(Short.reverseBytes(this.content[k]));
}
}
反序列,也很简单
@Override
public void deserialize(DataInput in) throws IOException {
this.cardinality = 0xFFFF & Short.reverseBytes(in.readShort());
if (this.content.length < this.cardinality) {
this.content = new short[this.cardinality];
}
for (int k = 0; k < this.cardinality; ++k) {
this.content[k] = Short.reverseBytes(in.readShort());;
}
}
迭代器:Array的迭代很简单,下一个就行
这里主要讨论bitmap迭代器:
peeknext:
@Override
public short peekNext() {
long t = w & -w;
return (short) (x * 64 + Long.bitCount(t - 1));
}
}
next:获取系一个answer之后把数据移动到后面一个位置。
@Override
public short next() {
long t = w & -w;
short answer = (short) (x * 64 + Long.bitCount(t - 1));
w ^= t;
while (w == 0) {
++x;
if (x == bitmap.length) {
break;
}
w = bitmap[x];
}
return answer;
}
结束语:
最近的项目底层数据压缩就是采用roaringbitmap。如果数据量一般都很大的时候,比如tag信息。tag信息以人为单位,比如一个
省份的人口。基本都是上亿的数据。如果单独用一个roaringbitmap 表示这个标签。基本需要12M的数据。当然高位不可能是饱和的。所以可以减少到10%。所以一般都是1M的文件。但是如果tag个数达到10万,数据将会是100G。如果需要计算and等操作,数据数据需要加载到内存。
如果标签数达到100万。(很正常,枚举型太对就有可能)。单机的内存就太多。所以采用分布式存储。。
方案。*将tag先经过切割。分成很多段,每一段的数据量的数据量就不是忒别大了。因为某一段的人,比如id从100-400 只能发送到一台机器。而且这台机器不受其他影响。数据需要汇总的时候能全部查询,也能单独查询,而这样的天生产品HBASE。
hbase定义表的时候能分区数据。所以元数据能单独维护。
hbase能用协处理,而且开发协处理很简单,每个协处理其相当于私有的处理。
hbase能和mapreduce结合 指定reduce与region个数相同。而且数据分区相同。map时也能对应一个region数数据。这样使得数据分离。*
同时,数据在查询的时候。能够发布一个查询,自动在region里做各自的查询,然后汇总。
支持功能:
全量批量导入:
增量批量导入:采用mapreduce导入。一个reduce对应一个region分区。
查询。解析解析引擎。
获取感兴趣的小圈子。
增删改查。
roaringbitmap基本结束,下个任务。HBASE。