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 ddbd4a7..74736db 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 @@ -22,12 +22,15 @@ import java.io.IOException; import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; +import java.util.HashSet; import java.util.List; +import java.util.Set; import org.apache.hadoop.hbase.CellUtil; import org.apache.hadoop.hbase.classification.InterfaceAudience; import org.apache.hadoop.hbase.classification.InterfaceStability; import org.apache.hadoop.hbase.Cell; +import org.apache.hadoop.hbase.CellComparator; import org.apache.hadoop.hbase.KeyValue; import org.apache.hadoop.hbase.KeyValueUtil; import org.apache.hadoop.hbase.exceptions.DeserializationException; @@ -69,7 +72,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<>(); /** * Save previous return code and previous cell for every filter in filter list. For MUST_PASS_ONE, @@ -207,7 +210,7 @@ final public class FilterList extends Filter { prevCellList.set(i, null); } } - seekHintFilter = null; + seekHintFilter.clear(); } @Override @@ -314,6 +317,7 @@ final public class FilterList extends Filter { justification="Intentional") public ReturnCode filterKeyValue(Cell v) throws IOException { this.referenceKV = v; + seekHintFilter.clear(); // Accumulates successive transformation of every filter that includes the Cell: Cell transformed = v; @@ -345,10 +349,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) { Cell prevCell = this.prevCellList.get(i); @@ -398,6 +404,10 @@ final public class FilterList extends Filter { } } + if (!seekHintFilter.isEmpty()) { + return ReturnCode.SEEK_NEXT_USING_HINT; + } + // Save the transformed Cell for transform(): this.transformedKV = transformed; @@ -522,7 +532,17 @@ final public class FilterList extends Filter { public Cell getNextCellHint(Cell currentKV) throws IOException { Cell keyHint = null; if (operator == Operator.MUST_PASS_ALL) { - if (seekHintFilter != null) keyHint = seekHintFilter.getNextCellHint(currentKV); + for (Filter filter : seekHintFilter) { + if (filter.filterAllRemaining()) continue; + Cell curKeyHint = filter.getNextCellHint(currentKV); + if (keyHint == null) { + keyHint = curKeyHint; + continue; + } + if (KeyValue.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 994adff..024785e 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 @@ -485,7 +485,7 @@ public class TestFilterList { Arrays.asList(new Filter [] { filterMinHint, filterMaxHint } )); filterList.filterKeyValue(null); assertEquals(0, KeyValue.COMPARATOR.compare(filterList.getNextKeyHint(null), - minKeyValue)); + maxKeyValue)); filterList = new FilterList(Operator.MUST_PASS_ALL, Arrays.asList(new Filter [] { filterMaxHint, filterMinHint } )); @@ -499,7 +499,7 @@ public class TestFilterList { new Filter [] { filterNoHint, filterMinHint, filterMaxHint } )); filterList.filterKeyValue(null); assertEquals(0, KeyValue.COMPARATOR.compare(filterList.getNextKeyHint(null), - minKeyValue)); + maxKeyValue)); filterList = new FilterList(Operator.MUST_PASS_ALL, Arrays.asList(new Filter [] { filterNoHint, filterMaxHint } )); filterList.filterKeyValue(null);