.../java/org/apache/hadoop/hbase/KeyValue.java | 11 ++++++++ .../io/encoding/BufferedDataBlockEncoder.java | 30 +++++++++++----------- .../hbase/codec/prefixtree/PrefixTreeSeeker.java | 21 --------------- .../hadoop/hbase/io/hfile/HFileBlockIndex.java | 9 ++++--- .../hadoop/hbase/io/hfile/HFileReaderImpl.java | 21 ++++----------- 5 files changed, 37 insertions(+), 55 deletions(-) diff --git a/hbase-common/src/main/java/org/apache/hadoop/hbase/KeyValue.java b/hbase-common/src/main/java/org/apache/hadoop/hbase/KeyValue.java index cd17bef..12b36c2 100644 --- a/hbase-common/src/main/java/org/apache/hadoop/hbase/KeyValue.java +++ b/hbase-common/src/main/java/org/apache/hadoop/hbase/KeyValue.java @@ -2726,6 +2726,17 @@ public class KeyValue implements Cell, HeapSize, Cloneable, SettableSequenceId, this.length = length; } + /** + * A setter that helps to avoid object creation every time and whenever + * there is a need to create new KeyOnlyKeyValue. + * @param key + */ + public void setKey(byte[] key) { + this.bytes = key; + this.offset = 0; + this.length = key.length; + } + @Override public byte[] getKey() { int keylength = getKeyLength(); diff --git a/hbase-common/src/main/java/org/apache/hadoop/hbase/io/encoding/BufferedDataBlockEncoder.java b/hbase-common/src/main/java/org/apache/hadoop/hbase/io/encoding/BufferedDataBlockEncoder.java index 8406a1c..c35d676 100644 --- a/hbase-common/src/main/java/org/apache/hadoop/hbase/io/encoding/BufferedDataBlockEncoder.java +++ b/hbase-common/src/main/java/org/apache/hadoop/hbase/io/encoding/BufferedDataBlockEncoder.java @@ -594,6 +594,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) { @@ -621,8 +622,8 @@ abstract class BufferedDataBlockEncoder implements DataBlockEncoder { // 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 @@ -746,10 +747,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 @@ -761,19 +761,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 @@ -782,12 +782,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 @@ -797,7 +797,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()); } } } diff --git a/hbase-prefix-tree/src/main/java/org/apache/hadoop/hbase/codec/prefixtree/PrefixTreeSeeker.java b/hbase-prefix-tree/src/main/java/org/apache/hadoop/hbase/codec/prefixtree/PrefixTreeSeeker.java index a4b4c353..d812f67 100644 --- a/hbase-prefix-tree/src/main/java/org/apache/hadoop/hbase/codec/prefixtree/PrefixTreeSeeker.java +++ b/hbase-prefix-tree/src/main/java/org/apache/hadoop/hbase/codec/prefixtree/PrefixTreeSeeker.java @@ -143,19 +143,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); diff --git a/hbase-server/src/main/java/org/apache/hadoop/hbase/io/hfile/HFileBlockIndex.java b/hbase-server/src/main/java/org/apache/hadoop/hbase/io/hfile/HFileBlockIndex.java index 067d639..2abc909 100644 --- a/hbase-server/src/main/java/org/apache/hadoop/hbase/io/hfile/HFileBlockIndex.java +++ b/hbase-server/src/main/java/org/apache/hadoop/hbase/io/hfile/HFileBlockIndex.java @@ -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); + nextIndexedKey = tmpNextIndexKV; } } diff --git a/hbase-server/src/main/java/org/apache/hadoop/hbase/io/hfile/HFileReaderImpl.java b/hbase-server/src/main/java/org/apache/hadoop/hbase/io/hfile/HFileReaderImpl.java index c6655c1..5a484a7 100644 --- a/hbase-server/src/main/java/org/apache/hadoop/hbase/io/hfile/HFileReaderImpl.java +++ b/hbase-server/src/main/java/org/apache/hadoop/hbase/io/hfile/HFileReaderImpl.java @@ -446,7 +446,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; /** @@ -599,7 +599,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(); @@ -759,7 +758,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(), @@ -853,16 +852,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(); @@ -1073,10 +1062,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