HBASE-14099 StoreFile.passesKeyRangeFilter need not create Cells from the

Scan's start and stop Row (Ram)
This commit is contained in:
ramkrishna 2015-07-20 22:10:10 +05:30
parent 88038cf473
commit 7e4cd59820
5 changed files with 66 additions and 36 deletions

View File

@ -1287,6 +1287,19 @@ public final class CellUtil {
cell.getQualifierArray(), cell.getQualifierOffset(), cell.getQualifierLength());
}
/**
* Create a Delete Family Cell for the specified row and family that would
* be smaller than all other possible Delete Family KeyValues that have the
* same row and family.
* Used for seeking.
* @param row - row key (arbitrary byte array)
* @param fam - family name
* @return First Delete Family possible key on passed <code>row</code>.
*/
public static Cell createFirstDeleteFamilyCellOnRow(final byte[] row, final byte[] fam) {
return new FirstOnRowDeleteFamilyCell(row, fam);
}
@InterfaceAudience.Private
private static abstract class FakeCell implements Cell {
@ -1565,4 +1578,45 @@ public final class CellUtil {
return this.qlength;
}
}
@InterfaceAudience.Private
private static class FirstOnRowDeleteFamilyCell extends FakeCell {
private final byte[] row;
private final byte[] fam;
public FirstOnRowDeleteFamilyCell(byte[] row, byte[] fam) {
this.row = row;
this.fam = fam;
}
@Override
public byte[] getRowArray() {
return this.row;
}
@Override
public short getRowLength() {
return (short) this.row.length;
}
@Override
public byte[] getFamilyArray() {
return this.fam;
}
@Override
public byte getFamilyLength() {
return (byte) this.fam.length;
}
@Override
public long getTimestamp() {
return HConstants.LATEST_TIMESTAMP;
}
@Override
public byte getTypeByte() {
return Type.DeleteFamily.getCode();
}
}
}

View File

@ -327,21 +327,6 @@ public class KeyValueUtil {
return new KeyValue(row, family, qualifier, HConstants.LATEST_TIMESTAMP, Type.Maximum);
}
/**
* Create a Delete Family KeyValue for the specified row and family that would
* be smaller than all other possible Delete Family KeyValues that have the
* same row and family.
* Used for seeking.
* @param row - row key (arbitrary byte array)
* @param family - family name
* @return First Delete Family possible key on passed <code>row</code>.
*/
public static KeyValue createFirstDeleteFamilyOnRow(final byte [] row,
final byte [] family) {
return new KeyValue(row, family, null, HConstants.LATEST_TIMESTAMP,
Type.DeleteFamily);
}
/**
* @param row - row key (arbitrary byte array)
* @param f - family name

View File

@ -165,7 +165,7 @@ public class ScanQueryMatcher {
this.regionCoprocessorHost = regionCoprocessorHost;
this.deletes = instantiateDeleteTracker();
this.stopRow = scan.getStopRow();
this.startKey = KeyValueUtil.createFirstDeleteFamilyOnRow(scan.getStartRow(),
this.startKey = CellUtil.createFirstDeleteFamilyCellOnRow(scan.getStartRow(),
scanInfo.getFamily());
this.filter = scan.getFilter();
this.earliestPutTs = earliestPutTs;

View File

@ -1362,19 +1362,16 @@ public class StoreFile {
&& Bytes.equals(scan.getStopRow(), HConstants.EMPTY_END_ROW)) {
return true;
}
KeyValue smallestScanKeyValue = scan.isReversed() ? KeyValueUtil
.createFirstOnRow(scan.getStopRow()) : KeyValueUtil.createFirstOnRow(scan
.getStartRow());
KeyValue largestScanKeyValue = scan.isReversed() ? KeyValueUtil
.createLastOnRow(scan.getStartRow()) : KeyValueUtil.createLastOnRow(scan
.getStopRow());
byte[] smallestScanRow = scan.isReversed() ? scan.getStopRow() : scan.getStartRow();
byte[] largestScanRow = scan.isReversed() ? scan.getStartRow() : scan.getStopRow();
Cell firstKeyKV = this.getFirstKey();
Cell lastKeyKV = this.getLastKey();
boolean nonOverLapping = ((getComparator().compare(firstKeyKV, largestScanKeyValue)) > 0
boolean nonOverLapping = (getComparator().compareRows(firstKeyKV,
largestScanRow, 0, largestScanRow.length) > 0
&& !Bytes
.equals(scan.isReversed() ? scan.getStartRow() : scan.getStopRow(),
HConstants.EMPTY_END_ROW))
|| (getComparator().compare(lastKeyKV, smallestScanKeyValue)) < 0;
|| getComparator().compareRows(lastKeyKV, smallestScanRow, 0, smallestScanRow.length) < 0;
return !nonOverLapping;
}

View File

@ -120,27 +120,21 @@ public class TestPrefixTreeEncoding {
seeker.setCurrentBuffer(readBuffer);
// Seek before the first keyvalue;
KeyValue seekKey = KeyValueUtil.createFirstDeleteFamilyOnRow(getRowKey(batchId, 0), CF_BYTES);
seeker.seekToKeyInBlock(
new KeyValue.KeyOnlyKeyValue(seekKey.getBuffer(), seekKey.getKeyOffset(), seekKey
.getKeyLength()), true);
Cell seekKey = CellUtil.createFirstDeleteFamilyCellOnRow(getRowKey(batchId, 0), CF_BYTES);
seeker.seekToKeyInBlock(seekKey, true);
assertEquals(null, seeker.getKeyValue());
// Seek before the middle keyvalue;
seekKey = KeyValueUtil.createFirstDeleteFamilyOnRow(getRowKey(batchId, NUM_ROWS_PER_BATCH / 3),
seekKey = CellUtil.createFirstDeleteFamilyCellOnRow(getRowKey(batchId, NUM_ROWS_PER_BATCH / 3),
CF_BYTES);
seeker.seekToKeyInBlock(
new KeyValue.KeyOnlyKeyValue(seekKey.getBuffer(), seekKey.getKeyOffset(), seekKey
.getKeyLength()), true);
seeker.seekToKeyInBlock(seekKey, true);
assertNotNull(seeker.getKeyValue());
assertArrayEquals(getRowKey(batchId, NUM_ROWS_PER_BATCH / 3 - 1),
CellUtil.cloneRow(seeker.getKeyValue()));
// Seek before the last keyvalue;
seekKey = KeyValueUtil.createFirstDeleteFamilyOnRow(Bytes.toBytes("zzzz"), CF_BYTES);
seeker.seekToKeyInBlock(
new KeyValue.KeyOnlyKeyValue(seekKey.getBuffer(), seekKey.getKeyOffset(), seekKey
.getKeyLength()), true);
seekKey = CellUtil.createFirstDeleteFamilyCellOnRow(Bytes.toBytes("zzzz"), CF_BYTES);
seeker.seekToKeyInBlock(seekKey, true);
assertNotNull(seeker.getKeyValue());
assertArrayEquals(getRowKey(batchId, NUM_ROWS_PER_BATCH - 1),
CellUtil.cloneRow(seeker.getKeyValue()));