hbase源码系列(十一)Put、Delete在服务端是如何处理?

List<Cell>> e : familyMap.entrySet()) { byte[] family = e.getKey(); List<Cell> cells = e.getValue(); //列和count的映射 Map<byte[], Integer> kvCount = new TreeMap<byte[], Integer>(Bytes.BYTES_COMPARATOR); for (Cell cell: cells) { KeyValue kv = KeyValueUtil.ensureKeyValue(cell); // 如果是时间戳是最新的话就执行下面这些操作
if (kv.isLatestTimestamp() && kv.isDeleteType()) { //new一个Get从Store里面去搜索
} else { kv.updateLatestStamp(byteNow); } } } }

看来一下代码,这里是上来先判断是否是最新的时间戳,我就回去看来一下Delete的构造函数,尼玛。。。
public Delete(byte [] row) {
this(row, HConstants.LATEST_TIMESTAMP);
}

public Delete(byte [] row, long timestamp) {
this(row, 0, row.length, timestamp);
}


只传了rowkey进去的,它就是最新的。。然后看了一下注释,凡是在这个时间点之前的所有版本的所有列,我们都要删除。
好吧,我们很无奈的宣布,我们只能走kv.isLatestTimestamp() && kv.isDeleteType(),下面是没放出来的代码。
byte[] qual = kv.getQualifier();
if (qual == null) qual = HConstants.EMPTY_BYTE_ARRAY;
//想到相同列的每次+1
Integer count = kvCount.get(qual);
if (count == null) {
kvCount.put(qual, 1);
} else {
kvCount.put(qual, count + 1);
}
//更新之后把最新的count数量
count = kvCount.get(qual);

Get get = new Get(kv.getRow());
get.setMaxVersions(count);
get.addColumn(family, qual);
//从store当中取出相应的result来
List<Cell> result = get(get, false);

if (result.size() < count) {
// Nothing to delete 数量不够。。 更新最新的时间戳为现在的时间
kv.updateLatestStamp(byteNow);
continue;
}
//数量超过了也不行
if (result.size() > count) {
throw new RuntimeException("Unexpected size: " + result.size());
}
//取最后一个的时间戳
KeyValue getkv = KeyValueUtil.ensureKeyValue(result.get(count - 1));
//更新kv的时间戳为getkv的时间戳
Bytes.putBytes(kv.getBuffer(), kv.getTimestampOffset(),
getkv.getBuffer(), getkv.getTimestampOffset(), Bytes.SIZEOF_LONG);


 
这里又干了一个Get操作,把列族的多个版本的内容取出来,如果数量不符合预期也会有问题,但是这后面操作的中心思想就是:
(a)按照预期来说,取出来的少了,就设置删除的时间戳为现在;
(b)取出来的多了,就报错;
(c)刚好的,就把Delete的时间戳设置为最大的那个的时间戳,但即便是这样也没有删除数据。
回到这里我又想起来,只有在Compaction之后,hbase的文件才会变小,难道是在那个时候删除的?那在删除之前,我们进行Get或者Scan操作的时候,会不会读到这些没有被删除的数据呢?
好,让我们拭目以待。
 
 

0 个评论

要回复文章请先登录注册