Index: core/src/test/java/org/apache/hadoop/hbase/regionserver/TestExplicitColumnTracker.java =================================================================== --- core/src/test/java/org/apache/hadoop/hbase/regionserver/TestExplicitColumnTracker.java (revision 944368) +++ core/src/test/java/org/apache/hadoop/hbase/regionserver/TestExplicitColumnTracker.java (working copy) @@ -23,6 +23,7 @@ import java.util.ArrayList; import java.util.List; import java.util.TreeSet; +import java.util.Arrays; import org.apache.hadoop.hbase.HBaseTestCase; import org.apache.hadoop.hbase.HConstants; @@ -40,7 +41,32 @@ private final byte [] col4 = Bytes.toBytes("col4"); private final byte [] col5 = Bytes.toBytes("col5"); + private void runTest(int maxVersions, + TreeSet trackColumns, + List scannerColumns, + List expected) { + ColumnTracker exp = new ExplicitColumnTracker( + trackColumns, maxVersions); + + //Initialize result + List result = new ArrayList(); + + //"Match" + for(byte [] col : scannerColumns){ + result.add(exp.checkColumn(col, 0, col.length)); + } + + assertEquals(expected.size(), result.size()); + for(int i=0; i< expected.size(); i++){ + assertEquals(expected.get(i), result.get(i)); + if(PRINT){ + System.out.println("Expected " +expected.get(i) + ", actual " + + result.get(i)); + } + } + } + public void testGet_SingleVersion(){ if(PRINT){ System.out.println("SingleVersion"); @@ -59,8 +85,6 @@ expected.add(MatchCode.DONE); int maxVersions = 1; - ColumnTracker exp = new ExplicitColumnTracker(columns, maxVersions); - //Create "Scanner" List scanner = new ArrayList(); scanner.add(col1); @@ -69,22 +93,7 @@ scanner.add(col4); scanner.add(col5); - //Initialize result - List result = new ArrayList(); - - //"Match" - for(byte [] col : scanner){ - result.add(exp.checkColumn(col, 0, col.length)); - } - - assertEquals(expected.size(), result.size()); - for(int i=0; i< expected.size(); i++){ - assertEquals(expected.get(i), result.get(i)); - if(PRINT){ - System.out.println("Expected " +expected.get(i) + ", actual " + - result.get(i)); - } - } + runTest(maxVersions, columns, scanner, expected); } public void testGet_MultiVersion(){ @@ -120,8 +129,6 @@ expected.add(MatchCode.DONE); int maxVersions = 2; - ColumnTracker exp = new ExplicitColumnTracker(columns, maxVersions); - //Create "Scanner" List scanner = new ArrayList(); scanner.add(col1); @@ -141,21 +148,7 @@ scanner.add(col5); //Initialize result - List result = new ArrayList(); - - //"Match" - for(byte [] col : scanner){ - result.add(exp.checkColumn(col, 0, col.length)); - } - - assertEquals(expected.size(), result.size()); - for(int i=0; i< expected.size(); i++){ - assertEquals(expected.get(i), result.get(i)); - if(PRINT){ - System.out.println("Expected " +expected.get(i) + ", actual " + - result.get(i)); - } - } + runTest(maxVersions, columns, scanner, expected); } @@ -182,5 +175,19 @@ } } - + /** + * Regression test for HBASE-2545 + */ + public void testInfiniteLoop() { + TreeSet columns = new TreeSet(Bytes.BYTES_COMPARATOR); + columns.addAll(Arrays.asList(new byte[][] { + col2, col3, col5 })); + List scanner = Arrays.asList( + new byte[][] { col1, col4 }); + List expected = Arrays.asList( + new MatchCode[] { + MatchCode.SKIP, + MatchCode.SKIP }); + runTest(1, columns, scanner, expected); + } } Index: core/src/main/java/org/apache/hadoop/hbase/regionserver/ExplicitColumnTracker.java =================================================================== --- core/src/main/java/org/apache/hadoop/hbase/regionserver/ExplicitColumnTracker.java (revision 944368) +++ core/src/main/java/org/apache/hadoop/hbase/regionserver/ExplicitColumnTracker.java (working copy) @@ -87,7 +87,9 @@ * @return MatchCode telling QueryMatcher what action to take */ public MatchCode checkColumn(byte [] bytes, int offset, int length) { + boolean recursive; do { + recursive = false; // No more columns left, we are done with this query if(this.columns.size() == 0) { return MatchCode.DONE; // done_row @@ -133,7 +135,8 @@ // This is the recursive case. this.column = this.columns.get(this.index); } - } while(true); + } while(recursive); + return MatchCode.SKIP; // skip to next column, with hint? } /**