用户可能需要按各自的需求实现自定义过滤器。用户可以实现 Filter接口或者直接继承 FilterBase类,后者已经为接口中所有成员方法提供了默认实现。
Filter接口的结构如下:
public abstract class Filter
extends Object
Interface for row and column filters directly applied within the regionserver. A filter can expect the following call sequence:
reset()
: reset the filter state before filtering a new row.filterAllRemaining()
: true means row scan is over; false means keep going.filterRowKey(Cell)
: true means drop this row; false means include.filterCell(Cell)
: decides whether to include or exclude this Cell. SeeFilter.ReturnCode
.transformCell(Cell)
: if the Cell is included, let the filter transform the Cell.filterRowCells(List)
: allows direct modification of the final list to be submittedfilterRow()
: last chance to drop entire row based on the sequence of filter calls. Eg: filter a row if it doesn't contain a specified column.
Filter instances are created one per region/scan. This abstract class replaces the old RowFilterInterface. When implementing your own filters, consider inheriting FilterBase
to help you reduce boilerplate.
接口中有一个公有的枚举类型,叫做 ReturnCode,它被 filterKeyValue)方法用于通知执行框架,进而决定如何进行下一步的工作。过滤器可以跳过一个值、一列的剩余部分或一行的剩余部分,而不用遍历所有数据。因此获取数据的效率会大大提升。
服务器端可能还是需要遍历整行数据来查找匹配数据,不过使用filterKeyValue()提供的返回值优化后还是可以减少许多工作量
下表展示了所有的取值以及每个值对应的含义。
返回值 | 描述 |
INCLUDE | 在结果中包括这个 KeyValue实例 |
SKIP | 跳过这个 Keyvalue实例并继续处理接下来的工作 |
NEXT_COL | 跳过当前列并继续处理后面的列。例如, TimestampsFilter使用了这个返回值 |
NEXT_ROW | 与上面的行为相似,跳过当前行并继续处理下一行。例如, RowFilter使用了这个返回值 |
SEEK_NEXT_USING_HINT | 一些过滤器需要跳过一系列的值,此时需要使用这个返回值通知执行框架使用 getNextKeyHint()来决定跳到什么位置。例如,Column PrefixFilter使用了这个功能 |
上面的大多数方法都在客户端获取检索操作(如扫描操作)的不同阶段时被调用。调整调用次序,用户可以以如下的预期顺序执行。