diff --git src/java/org/apache/hadoop/hbase/regionserver/StoreScanner.java src/java/org/apache/hadoop/hbase/regionserver/StoreScanner.java index 6d4546f..d13cde0 100644 --- src/java/org/apache/hadoop/hbase/regionserver/StoreScanner.java +++ src/java/org/apache/hadoop/hbase/regionserver/StoreScanner.java @@ -279,6 +279,9 @@ class StoreScanner implements KeyValueScanner, InternalScanner, ChangedReadersOb public synchronized void updateReaders() throws IOException { if (this.closing) return; + // maybe we are already reseeking? + if (this.heap == null) return; + // this could be null. this.lastTop = this.peek(); diff --git src/test/org/apache/hadoop/hbase/regionserver/TestStoreScanner.java src/test/org/apache/hadoop/hbase/regionserver/TestStoreScanner.java index 76ab7b5..2a99a18 100644 --- src/test/org/apache/hadoop/hbase/regionserver/TestStoreScanner.java +++ src/test/org/apache/hadoop/hbase/regionserver/TestStoreScanner.java @@ -49,7 +49,7 @@ public class TestStoreScanner extends TestCase { } return cols; } - + public void testScanTimeRange() throws IOException { String r1 = "R1"; // returns only 1 of these 2 even though same timestamp @@ -101,7 +101,6 @@ public class TestStoreScanner extends TestCase { results = new ArrayList(); assertEquals(true, scan.next(results)); assertEquals(3, results.size()); - } public void testScanSameTimestamp() throws IOException { @@ -288,6 +287,7 @@ public class TestStoreScanner extends TestCase { assertEquals(kvs[0], results.get(0)); assertEquals(kvs[1], results.get(1)); } + public void testWildCardScannerUnderDeletes() throws IOException { KeyValue [] kvs = new KeyValue [] { KeyValueTestUtil.create("R1", "cf", "a", 2, KeyValue.Type.Put, "dont-care"), // inc @@ -322,6 +322,7 @@ public class TestStoreScanner extends TestCase { assertEquals(kvs[6], results.get(3)); assertEquals(kvs[7], results.get(4)); } + public void testDeleteFamily() throws IOException { KeyValue [] kvs = new KeyValue[] { KeyValueTestUtil.create("R1", "cf", "a", 100, KeyValue.Type.DeleteFamily, "dont-care"), @@ -335,7 +336,7 @@ public class TestStoreScanner extends TestCase { KeyValueTestUtil.create("R1", "cf", "g", 11, KeyValue.Type.Delete, "dont-care"), KeyValueTestUtil.create("R1", "cf", "h", 11, KeyValue.Type.Put, "dont-care"), KeyValueTestUtil.create("R1", "cf", "i", 11, KeyValue.Type.Put, "dont-care"), - KeyValueTestUtil.create("R2", "cf", "a", 11, KeyValue.Type.Put, "dont-care"), + KeyValueTestUtil.create("R2", "cf", "a", 11, KeyValue.Type.Put, "dont-care"), }; KeyValueScanner [] scanners = new KeyValueScanner[] { new KeyValueScanFixture(KeyValue.COMPARATOR, kvs) @@ -372,8 +373,7 @@ public class TestStoreScanner extends TestCase { assertEquals(kvs[3], results.get(0)); } - public void testSkipColumn() throws IOException { - KeyValue [] kvs = new KeyValue[] { + private static final KeyValue [] kvs = new KeyValue[] { KeyValueTestUtil.create("R1", "cf", "a", 11, KeyValue.Type.Put, "dont-care"), KeyValueTestUtil.create("R1", "cf", "b", 11, KeyValue.Type.Put, "dont-care"), KeyValueTestUtil.create("R1", "cf", "c", 11, KeyValue.Type.Put, "dont-care"), @@ -385,6 +385,8 @@ public class TestStoreScanner extends TestCase { KeyValueTestUtil.create("R1", "cf", "i", 11, KeyValue.Type.Put, "dont-care"), KeyValueTestUtil.create("R2", "cf", "a", 11, KeyValue.Type.Put, "dont-care"), }; + + public void testSkipColumn() throws IOException { KeyValueScanner [] scanners = new KeyValueScanner[] { new KeyValueScanFixture(KeyValue.COMPARATOR, kvs) }; @@ -406,9 +408,9 @@ public class TestStoreScanner extends TestCase { results.clear(); assertEquals(false, scan.next(results)); } - + /* - * Test expiration of KeyValues in combination with a configured TTL for + * Test expiration of KeyValues in combination with a configured TTL for * a column family (as should be triggered in a major compaction). */ public void testWildCardTtlScan() throws IOException { @@ -438,14 +440,32 @@ public class TestStoreScanner extends TestCase { assertEquals(kvs[1], results.get(0)); assertEquals(kvs[2], results.get(1)); results.clear(); - + assertEquals(true, scanner.next(results)); assertEquals(3, results.size()); assertEquals(kvs[4], results.get(0)); assertEquals(kvs[5], results.get(1)); assertEquals(kvs[6], results.get(2)); results.clear(); - + assertEquals(false, scanner.next(results)); } + + public void testScannerReseek() throws Exception { + KeyValueScanner [] scanners = new KeyValueScanner[] { + new KeyValueScanFixture(KeyValue.COMPARATOR, kvs) + }; + StoreScanner scan = + new StoreScanner(new Scan(), CF, Long.MAX_VALUE, KeyValue.COMPARATOR, + getCols("a", "d"), scanners); + + // TODO mock out scan.store for better testability here. + + scan.updateReaders(); + + // check we can call again w/o going insane + scan.updateReaders(); + + + } }