HBASE-13614 - Avoid temp KeyOnlyKeyValue temp objects creations in read

hot path (Ram)
This commit is contained in:
ramkrishna 2015-06-22 12:30:46 +05:30
parent a4bd2b784e
commit f9b17bfd37
4 changed files with 26 additions and 58 deletions

View File

@ -596,6 +596,7 @@ abstract class BufferedDataBlockEncoder implements DataBlockEncoder {
protected STATE current = createSeekerState(); // always valid
protected STATE previous = createSeekerState(); // may not be valid
protected TagCompressionContext tagCompressionContext = null;
protected KeyValue.KeyOnlyKeyValue keyOnlyKV = new KeyValue.KeyOnlyKeyValue();
public BufferedEncodedSeeker(CellComparator comparator,
HFileBlockDecodingContext decodingCtx) {
@ -620,11 +621,8 @@ abstract class BufferedDataBlockEncoder implements DataBlockEncoder {
@Override
public int compareKey(CellComparator comparator, Cell key) {
// TODO BufferedEncodedSeeker, instance will be used by single thread alone. So we can
// have one KeyValue.KeyOnlyKeyValue instance as instance variable and reuse here and in
// seekToKeyInBlock
return comparator.compareKeyIgnoresMvcc(key,
new KeyValue.KeyOnlyKeyValue(current.keyBuffer, 0, current.keyLength));
keyOnlyKV.setKey(current.keyBuffer, 0, current.keyLength);
return comparator.compareKeyIgnoresMvcc(key, keyOnlyKV);
}
@Override
@ -748,10 +746,9 @@ abstract class BufferedDataBlockEncoder implements DataBlockEncoder {
int familyCommonPrefix = 0;
int qualCommonPrefix = 0;
previous.invalidate();
KeyValue.KeyOnlyKeyValue currentCell = new KeyValue.KeyOnlyKeyValue();
do {
int comp;
currentCell.setKey(current.keyBuffer, 0, current.keyLength);
keyOnlyKV.setKey(current.keyBuffer, 0, current.keyLength);
if (current.lastCommonPrefix != 0) {
// The KV format has row key length also in the byte array. The
// common prefix
@ -763,19 +760,19 @@ abstract class BufferedDataBlockEncoder implements DataBlockEncoder {
if (current.lastCommonPrefix <= 2) {
rowCommonPrefix = 0;
}
rowCommonPrefix += findCommonPrefixInRowPart(seekCell, currentCell, rowCommonPrefix);
comp = compareCommonRowPrefix(seekCell, currentCell, rowCommonPrefix);
rowCommonPrefix += findCommonPrefixInRowPart(seekCell, keyOnlyKV, rowCommonPrefix);
comp = compareCommonRowPrefix(seekCell, keyOnlyKV, rowCommonPrefix);
if (comp == 0) {
comp = compareTypeBytes(seekCell, currentCell);
comp = compareTypeBytes(seekCell, keyOnlyKV);
if (comp == 0) {
// Subtract the fixed row key length and the family key fixed length
familyCommonPrefix = Math.max(
0,
Math.min(familyCommonPrefix,
current.lastCommonPrefix - (3 + currentCell.getRowLength())));
familyCommonPrefix += findCommonPrefixInFamilyPart(seekCell, currentCell,
current.lastCommonPrefix - (3 + keyOnlyKV.getRowLength())));
familyCommonPrefix += findCommonPrefixInFamilyPart(seekCell, keyOnlyKV,
familyCommonPrefix);
comp = compareCommonFamilyPrefix(seekCell, currentCell, familyCommonPrefix);
comp = compareCommonFamilyPrefix(seekCell, keyOnlyKV, familyCommonPrefix);
if (comp == 0) {
// subtract the rowkey fixed length and the family key fixed
// length
@ -784,12 +781,12 @@ abstract class BufferedDataBlockEncoder implements DataBlockEncoder {
Math.min(
qualCommonPrefix,
current.lastCommonPrefix
- (3 + currentCell.getRowLength() + currentCell.getFamilyLength())));
qualCommonPrefix += findCommonPrefixInQualifierPart(seekCell, currentCell,
- (3 + keyOnlyKV.getRowLength() + keyOnlyKV.getFamilyLength())));
qualCommonPrefix += findCommonPrefixInQualifierPart(seekCell, keyOnlyKV,
qualCommonPrefix);
comp = compareCommonQualifierPrefix(seekCell, currentCell, qualCommonPrefix);
comp = compareCommonQualifierPrefix(seekCell, keyOnlyKV, qualCommonPrefix);
if (comp == 0) {
comp = CellComparator.compareTimestamps(seekCell, currentCell);
comp = CellComparator.compareTimestamps(seekCell, keyOnlyKV);
if (comp == 0) {
// Compare types. Let the delete types sort ahead of puts;
// i.e. types
@ -799,7 +796,7 @@ abstract class BufferedDataBlockEncoder implements DataBlockEncoder {
// appears ahead of everything, and minimum (0) appears
// after
// everything.
comp = (0xff & currentCell.getTypeByte()) - (0xff & seekCell.getTypeByte());
comp = (0xff & keyOnlyKV.getTypeByte()) - (0xff & seekCell.getTypeByte());
}
}
}

View File

@ -142,19 +142,6 @@ public class PrefixTreeSeeker implements EncodedSeeker {
private static final boolean USE_POSITION_BEFORE = false;
/*
* Support both of these options since the underlying PrefixTree supports both. Possibly
* expand the EncodedSeeker to utilize them both.
*/
protected int seekToOrBeforeUsingPositionAtOrBefore(byte[] keyOnlyBytes, int offset, int length,
boolean seekBefore){
// this does a deep copy of the key byte[] because the CellSearcher interface wants a Cell
KeyValue kv = new KeyValue.KeyOnlyKeyValue(keyOnlyBytes, offset, length);
return seekToOrBeforeUsingPositionAtOrBefore(kv, seekBefore);
}
/*
* Support both of these options since the underlying PrefixTree supports
* both. Possibly expand the EncodedSeeker to utilize them both.
@ -176,14 +163,6 @@ public class PrefixTreeSeeker implements EncodedSeeker {
return 1;
}
protected int seekToOrBeforeUsingPositionAtOrAfter(byte[] keyOnlyBytes, int offset, int length,
boolean seekBefore) {
// this does a deep copy of the key byte[] because the CellSearcher
// interface wants a Cell
KeyValue kv = new KeyValue.KeyOnlyKeyValue(keyOnlyBytes, offset, length);
return seekToOrBeforeUsingPositionAtOrAfter(kv, seekBefore);
}
protected int seekToOrBeforeUsingPositionAtOrAfter(Cell kv, boolean seekBefore) {
// should probably switch this to use the seekForwardToOrBefore method
CellScannerPosition position = ptSearcher.seekForwardToOrAfter(kv);

View File

@ -40,6 +40,7 @@ import org.apache.hadoop.hbase.CellComparator;
import org.apache.hadoop.hbase.CellUtil;
import org.apache.hadoop.hbase.HConstants;
import org.apache.hadoop.hbase.KeyValue;
import org.apache.hadoop.hbase.KeyValue.KeyOnlyKeyValue;
import org.apache.hadoop.hbase.KeyValueUtil;
import org.apache.hadoop.hbase.io.HeapSize;
import org.apache.hadoop.hbase.io.encoding.DataBlockEncoding;
@ -294,6 +295,7 @@ public class HFileBlockIndex {
int index = -1;
HFileBlock block;
KeyOnlyKeyValue tmpNextIndexKV = new KeyValue.KeyOnlyKeyValue();
while (true) {
if (currentBlock != null && currentBlock.getOffset() == currentOffset)
@ -356,9 +358,10 @@ public class HFileBlockIndex {
currentOnDiskSize = buffer.getInt();
// Only update next indexed key if there is a next indexed key in the current level
byte[] tmpNextIndexedKey = getNonRootIndexedKey(buffer, index + 1);
if (tmpNextIndexedKey != null) {
nextIndexedKey = new KeyValue.KeyOnlyKeyValue(tmpNextIndexedKey);
byte[] nonRootIndexedKey = getNonRootIndexedKey(buffer, index + 1);
if (nonRootIndexedKey != null) {
tmpNextIndexKV.setKey(nonRootIndexedKey, 0, nonRootIndexedKey.length);
nextIndexedKey = tmpNextIndexKV;
}
}

View File

@ -447,7 +447,7 @@ public class HFileReaderImpl implements HFile.Reader, Configurable {
protected volatile int blockFetches;
protected final HFile.Reader reader;
private int currTagsLen;
private KeyValue.KeyOnlyKeyValue keyOnlyKv = new KeyValue.KeyOnlyKeyValue();
protected HFileBlock block;
/**
@ -600,7 +600,6 @@ public class HFileReaderImpl implements HFile.Reader, Configurable {
long memstoreTS = 0;
int memstoreTSLen = 0;
int lastKeyValueSize = -1;
KeyValue.KeyOnlyKeyValue keyOnlyKv = new KeyValue.KeyOnlyKeyValue();
do {
blockBuffer.mark();
klen = blockBuffer.getInt();
@ -760,7 +759,7 @@ public class HFileReaderImpl implements HFile.Reader, Configurable {
return false;
}
ByteBuffer firstKey = getFirstKeyInBlock(seekToBlock);
// Will be changed as part of HBASE-13939
if (reader.getComparator()
.compareKeyIgnoresMvcc(
new KeyValue.KeyOnlyKeyValue(firstKey.array(), firstKey.arrayOffset(),
@ -851,16 +850,6 @@ public class HFileReaderImpl implements HFile.Reader, Configurable {
+ KEY_VALUE_LEN_SIZE, currKeyLen).slice();
}
public int compareKey(CellComparator comparator, byte[] key, int offset, int length) {
// TODO HFileScannerImpl, instance will be used by single thread alone. So we can
// have one KeyValue.KeyOnlyKeyValue instance as instance variable and reuse here and in
// compareKey(CellComparator comparator, Cell key), seekBefore(Cell key) and
// blockSeek(Cell key, boolean seekBefore)
KeyValue.KeyOnlyKeyValue keyOnlyKv = new KeyValue.KeyOnlyKeyValue(key, offset, length);
return comparator.compare(keyOnlyKv, blockBuffer.array(), blockBuffer.arrayOffset()
+ blockBuffer.position() + KEY_VALUE_LEN_SIZE, currKeyLen);
}
@Override
public ByteBuffer getValue() {
assertSeeked();
@ -1071,10 +1060,10 @@ public class HFileReaderImpl implements HFile.Reader, Configurable {
}
public int compareKey(CellComparator comparator, Cell key) {
this.keyOnlyKv.setKey(blockBuffer.array(), blockBuffer.arrayOffset()
+ blockBuffer.position() + KEY_VALUE_LEN_SIZE, currKeyLen);
return comparator.compareKeyIgnoresMvcc(
key,
new KeyValue.KeyOnlyKeyValue(blockBuffer.array(), blockBuffer.arrayOffset()
+ blockBuffer.position() + KEY_VALUE_LEN_SIZE, currKeyLen));
key, this.keyOnlyKv);
}
@Override