HBASE-12767 Fix a StoreFileScanner NPE in reverse scan flow

This commit is contained in:
xieliang 2014-12-30 11:52:33 +08:00
parent 8ff62d9cee
commit 619f94f113
2 changed files with 112 additions and 2 deletions

View File

@ -304,10 +304,18 @@ public class HalfStoreFileReader extends StoreFile.Reader {
// The equals sign isn't strictly necessary just here to be consistent
// with seekTo
if (getComparator().compareOnlyKeyPortion(key, splitCell) >= 0) {
return this.delegate.seekBefore(splitCell);
boolean ret = this.delegate.seekBefore(splitCell);
if (ret) {
atEnd = false;
}
return ret;
}
}
return this.delegate.seekBefore(key);
boolean ret = this.delegate.seekBefore(key);
if (ret) {
atEnd = false;
}
return ret;
}
};
}

View File

@ -5008,6 +5008,7 @@ public class TestHRegion {
Bytes.toString(CellUtil.cloneValue(kv)));
}
@Test (timeout=60000)
public void testReverseScanner_FromMemStore_SingleCF_Normal()
throws IOException {
byte[] rowC = Bytes.toBytes("rowC");
@ -5063,6 +5064,7 @@ public class TestHRegion {
}
}
@Test (timeout=60000)
public void testReverseScanner_FromMemStore_SingleCF_LargerKey()
throws IOException {
byte[] rowC = Bytes.toBytes("rowC");
@ -5119,6 +5121,7 @@ public class TestHRegion {
}
}
@Test (timeout=60000)
public void testReverseScanner_FromMemStore_SingleCF_FullScan()
throws IOException {
byte[] rowC = Bytes.toBytes("rowC");
@ -5172,6 +5175,7 @@ public class TestHRegion {
}
}
@Test (timeout=60000)
public void testReverseScanner_moreRowsMayExistAfter() throws IOException {
// case for "INCLUDE_AND_SEEK_NEXT_ROW & SEEK_NEXT_ROW" endless loop
byte[] rowA = Bytes.toBytes("rowA");
@ -5249,6 +5253,7 @@ public class TestHRegion {
}
}
@Test (timeout=60000)
public void testReverseScanner_smaller_blocksize() throws IOException {
// case to ensure no conflict with HFile index optimization
byte[] rowA = Bytes.toBytes("rowA");
@ -5328,6 +5333,7 @@ public class TestHRegion {
}
}
@Test (timeout=60000)
public void testReverseScanner_FromMemStoreAndHFiles_MultiCFs1()
throws IOException {
byte[] row0 = Bytes.toBytes("row0"); // 1 kv
@ -5488,6 +5494,7 @@ public class TestHRegion {
}
}
@Test (timeout=60000)
public void testReverseScanner_FromMemStoreAndHFiles_MultiCFs2()
throws IOException {
byte[] row1 = Bytes.toBytes("row1");
@ -5561,6 +5568,101 @@ public class TestHRegion {
}
}
@Test (timeout=60000)
public void testSplitRegionWithReverseScan() throws IOException {
byte [] tableName = Bytes.toBytes("testSplitRegionWithReverseScan");
byte [] qualifier = Bytes.toBytes("qualifier");
Configuration hc = initSplit();
int numRows = 3;
byte [][] families = {fam1};
//Setting up region
String method = this.getName();
this.region = initHRegion(tableName, method, hc, families);
//Put data in region
int startRow = 100;
putData(startRow, numRows, qualifier, families);
int splitRow = startRow + numRows;
putData(splitRow, numRows, qualifier, families);
int endRow = splitRow + numRows;
region.flushcache();
HRegion [] regions = null;
try {
regions = splitRegion(region, Bytes.toBytes("" + splitRow));
//Opening the regions returned.
for (int i = 0; i < regions.length; i++) {
regions[i] = HRegion.openHRegion(regions[i], null);
}
//Verifying that the region has been split
assertEquals(2, regions.length);
//Verifying that all data is still there and that data is in the right
//place
verifyData(regions[0], startRow, numRows, qualifier, families);
verifyData(regions[1], splitRow, numRows, qualifier, families);
//fire the reverse scan1: top range, and larger than the last row
Scan scan = new Scan(Bytes.toBytes(String.valueOf(startRow + 10 * numRows)));
scan.setReversed(true);
InternalScanner scanner = regions[1].getScanner(scan);
List<Cell> currRow = new ArrayList<Cell>();
boolean more = false;
int verify = startRow + 2 * numRows - 1;
do {
more = scanner.next(currRow);
assertEquals(Bytes.toString(currRow.get(0).getRow()), verify + "");
verify--;
currRow.clear();
} while(more);
assertEquals(verify, startRow + numRows - 1);
scanner.close();
//fire the reverse scan2: top range, and equals to the last row
scan = new Scan(Bytes.toBytes(String.valueOf(startRow + 2 * numRows - 1)));
scan.setReversed(true);
scanner = regions[1].getScanner(scan);
verify = startRow + 2 * numRows - 1;
do {
more = scanner.next(currRow);
assertEquals(Bytes.toString(currRow.get(0).getRow()), verify + "");
verify--;
currRow.clear();
} while(more);
assertEquals(verify, startRow + numRows - 1);
scanner.close();
//fire the reverse scan3: bottom range, and larger than the last row
scan = new Scan(Bytes.toBytes(String.valueOf(startRow + numRows)));
scan.setReversed(true);
scanner = regions[0].getScanner(scan);
verify = startRow + numRows - 1;
do {
more = scanner.next(currRow);
assertEquals(Bytes.toString(currRow.get(0).getRow()), verify + "");
verify--;
currRow.clear();
} while(more);
assertEquals(verify, 99);
scanner.close();
//fire the reverse scan4: bottom range, and equals to the last row
scan = new Scan(Bytes.toBytes(String.valueOf(startRow + numRows - 1)));
scan.setReversed(true);
scanner = regions[0].getScanner(scan);
verify = startRow + numRows - 1;
do {
more = scanner.next(currRow);
assertEquals(Bytes.toString(currRow.get(0).getRow()), verify + "");
verify--;
currRow.clear();
} while(more);
assertEquals(verify, startRow - 1);
scanner.close();
} finally {
HRegion.closeHRegion(this.region);
this.region = null;
}
}
@Test
public void testWriteRequestsCounter() throws IOException {
byte[] fam = Bytes.toBytes("info");