commit 4f7a331b50d894dedd09037c91b3b5a7e3350bb3 Author: Todd Lipcon Date: Fri May 14 11:00:28 2010 -0700 HBASE-2545. Fix an infinite loop in ExplicitColumnTracker diff --git src/java/org/apache/hadoop/hbase/regionserver/ExplicitColumnTracker.java src/java/org/apache/hadoop/hbase/regionserver/ExplicitColumnTracker.java index 7f6ade4..e0770ba 100644 --- src/java/org/apache/hadoop/hbase/regionserver/ExplicitColumnTracker.java +++ src/java/org/apache/hadoop/hbase/regionserver/ExplicitColumnTracker.java @@ -83,8 +83,10 @@ public class ExplicitColumnTracker implements ColumnTracker { * @return MatchCode telling QueryMatcher what action to take */ public MatchCode checkColumn(byte [] bytes, int offset, int length) { - boolean recursive = false; + 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 diff --git src/test/org/apache/hadoop/hbase/regionserver/TestExplicitColumnTracker.java src/test/org/apache/hadoop/hbase/regionserver/TestExplicitColumnTracker.java index 427a625..c287876 100644 --- src/test/org/apache/hadoop/hbase/regionserver/TestExplicitColumnTracker.java +++ src/test/org/apache/hadoop/hbase/regionserver/TestExplicitColumnTracker.java @@ -23,6 +23,7 @@ package org.apache.hadoop.hbase.regionserver; 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; @@ -39,7 +40,33 @@ implements HConstants { private final byte [] col3 = Bytes.toBytes("col3"); 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"); @@ -57,8 +84,6 @@ implements HConstants { expected.add(MatchCode.INCLUDE); expected.add(MatchCode.DONE); int maxVersions = 1; - - ColumnTracker exp = new ExplicitColumnTracker(columns, maxVersions); //Create "Scanner" List scanner = new ArrayList(); @@ -67,23 +92,8 @@ implements HConstants { scanner.add(col3); 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(){ @@ -119,8 +129,6 @@ implements HConstants { expected.add(MatchCode.DONE); int maxVersions = 2; - ColumnTracker exp = new ExplicitColumnTracker(columns, maxVersions); - //Create "Scanner" List scanner = new ArrayList(); scanner.add(col1); @@ -140,21 +148,7 @@ implements HConstants { 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); } /** @@ -179,5 +173,21 @@ implements HConstants { explicit.checkColumn(col, 0, col.length); } } + + /** + * 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); + } }