HBase 0.96及更高版本的RPC使用protocol buffer进行序列化和反序列化,那么如果查询时使用SingleColumnValueFilter,并且想要使用自定义的Comparator,该如何去做呢?

假设要求Comparator执行操作是判断从HBase表查询的每个结果的指定column的值是否是某一String的substring,如果是,则返回,否则,弃之。

以上述假设为例,执行如下步骤可实现上述需求:

##第一步,编写proto文件###

如何编写proto文件,此处给出小示例,更为详细的内容,请查阅protocol buffer相关资料。

新建文件CustomProtos.proto,文件内容:

//option java_package = "com.xxx.yyy";
//option java_outer_classname = ""; 
message MyComparator { 
	required string MyString = 1; 
} 

注释掉的是一些可选设置。

##第二步,编译proto文件###

使用protoc编译器(需要下载),可以把proto文件编译成java、c++等目标语言,在bash中运行命令编译proto文件,命令格式如下:

protoc --proto\_path=IMPORT\_PATH --cpp\_out=DST\_DIR --java\_out=DST\_DIR --python\_out=DST\_DIR path/to/file.proto 

根据上述命令格式使用如下命令编译CustomProtos.proto,会生成CustomProtos.java文件(如果之前没有设置java package,可能会报错,添加一下包名就可以了)

protoc --proto_path=/Users/jzhou/documents/workspace/Test/src/main/java/test --java_out=/Users/jzhou/documents/workspace/Test/src/main/java/test /Users/jzhou/documents/workspace/Test/src/main/java/test/CustomProtos.proto

##第三步,编写自定义Comparator###

创建MyComparator.java,使用生成的CustomProtos.java实现序列化方法toByteArray()和反序列化方法parseFrom():

public class MyComparator extends ByteArrayComparable { 

	private String MyString; 
	
	public MatcherComparator(String qrStr) { 
		super(Bytes.toBytes(qrStr)); this.MyString = qrStr; 
	} 
	
	@Override 
	public int compareTo(byte[] value, int offset, int length) { 
		//some codes to compare
		return MyString.contains(Bytes.toString(Bytes.copy(value, offset, length))) ? 0 : 1;
	} 
	
	public static MyComparator parseFrom(final byte [] pbBytes) throws DeserializationException { 
		CustomProtos.MyComparator proto; 
		try { 
			proto = CustomProtos.MyComparator.parseFrom(pbBytes); 
		} catch (InvalidProtocolBufferException e){ 
			throw new DeserializationException(e); 
		} 
		
		return new MyComparator(proto.getMyString()); 
	} 
	
	@Override 
	public byte[] toByteArray() { 
		CustomProtos.MyComparator.Builder builder = CustomProtos.MyComparator.newBuilder();
		builder.setMyString(this.MyString); return builder.build().toByteArray(); 
	} 
	
}