diff --git a/hbase-client/src/main/java/org/apache/hadoop/hbase/filter/FilterList.java b/hbase-client/src/main/java/org/apache/hadoop/hbase/filter/FilterList.java index 8ba1ccb..f8c16ad 100644 --- a/hbase-client/src/main/java/org/apache/hadoop/hbase/filter/FilterList.java +++ b/hbase-client/src/main/java/org/apache/hadoop/hbase/filter/FilterList.java @@ -21,7 +21,9 @@ package org.apache.hadoop.hbase.filter; import java.io.IOException; import java.util.ArrayList; import java.util.Arrays; +import java.util.HashSet; import java.util.List; +import java.util.Set; import org.apache.hadoop.hbase.Cell; import org.apache.hadoop.hbase.CellComparator; @@ -67,7 +69,7 @@ final public class FilterList extends Filter { private static final int MAX_LOG_FILTERS = 5; private Operator operator = Operator.MUST_PASS_ALL; private List filters = new ArrayList(); - private Filter seekHintFilter = null; + private Set seekHintFilter = new HashSet<>(); /** Reference Cell used by {@link #transformCell(Cell)} for validation purpose. */ private Cell referenceCell = null; @@ -173,7 +175,7 @@ final public class FilterList extends Filter { for (int i = 0; i < listize; i++) { filters.get(i).reset(); } - seekHintFilter = null; + seekHintFilter.clear(); } @Override @@ -269,10 +271,12 @@ final public class FilterList extends Filter { transformed = filter.transformCell(transformed); continue; case SEEK_NEXT_USING_HINT: - seekHintFilter = filter; - return code; + seekHintFilter.add(filter); + continue; default: - return code; + if (seekHintFilter.isEmpty()) { + return code; + } } } else if (operator == Operator.MUST_PASS_ONE) { if (filter.filterAllRemaining()) { @@ -305,6 +309,10 @@ final public class FilterList extends Filter { } } + if (!seekHintFilter.isEmpty()) { + return ReturnCode.SEEK_NEXT_USING_HINT; + } + // Save the transformed Cell for transform(): this.transformedCell = transformed; @@ -416,7 +424,17 @@ final public class FilterList extends Filter { public Cell getNextCellHint(Cell currentCell) throws IOException { Cell keyHint = null; if (operator == Operator.MUST_PASS_ALL) { - keyHint = seekHintFilter.getNextCellHint(currentCell); + for (Filter filter : seekHintFilter) { + if (filter.filterAllRemaining()) continue; + Cell curKeyHint = filter.getNextCellHint(currentCell); + if (keyHint == null) { + keyHint = curKeyHint; + continue; + } + if (CellComparator.COMPARATOR.compare(keyHint, curKeyHint) < 0) { + keyHint = curKeyHint; + } + } return keyHint; } diff --git a/hbase-server/src/test/java/org/apache/hadoop/hbase/filter/TestFilterList.java b/hbase-server/src/test/java/org/apache/hadoop/hbase/filter/TestFilterList.java index 440c9f5..3875841 100644 --- a/hbase-server/src/test/java/org/apache/hadoop/hbase/filter/TestFilterList.java +++ b/hbase-server/src/test/java/org/apache/hadoop/hbase/filter/TestFilterList.java @@ -460,7 +460,7 @@ public class TestFilterList { FilterList filterList = new FilterList(Operator.MUST_PASS_ONE, Arrays.asList(new Filter [] { filterMinHint, filterMaxHint } )); assertEquals(0, CellComparator.COMPARATOR.compare(filterList.getNextCellHint(null), - minKeyValue)); + minKeyValue)); // Should have no hint if any filter has no hint filterList = new FilterList(Operator.MUST_PASS_ONE, @@ -484,7 +484,7 @@ public class TestFilterList { Arrays.asList(new Filter [] { filterMinHint, filterMaxHint } )); filterList.filterKeyValue(null); assertEquals(0, CellComparator.COMPARATOR.compare(filterList.getNextCellHint(null), - minKeyValue)); + maxKeyValue)); filterList = new FilterList(Operator.MUST_PASS_ALL, Arrays.asList(new Filter [] { filterMaxHint, filterMinHint } )); @@ -498,7 +498,7 @@ public class TestFilterList { new Filter [] { filterNoHint, filterMinHint, filterMaxHint } )); filterList.filterKeyValue(null); assertEquals(0, CellComparator.COMPARATOR.compare(filterList.getNextCellHint(null), - minKeyValue)); + maxKeyValue)); filterList = new FilterList(Operator.MUST_PASS_ALL, Arrays.asList(new Filter [] { filterNoHint, filterMaxHint } )); filterList.filterKeyValue(null);