Revert "HBASE-23705 Add CellComparator to HFileContext (#1062)"

This reverts commit f817293fb4328922462a1ef25d56cdab425853e1.
This commit is contained in:
stack 2020-01-26 20:49:03 -08:00
parent cbb2c7e00d
commit f4b0ad9f6a
50 changed files with 624 additions and 523 deletions

View File

@ -17,9 +17,8 @@
*/ */
package org.apache.hadoop.hbase; package org.apache.hadoop.hbase;
import java.nio.ByteBuffer;
import java.util.Comparator; import java.util.Comparator;
import org.apache.hadoop.hbase.util.ByteBufferUtils;
import org.apache.yetus.audience.InterfaceAudience; import org.apache.yetus.audience.InterfaceAudience;
import org.apache.yetus.audience.InterfaceStability; import org.apache.yetus.audience.InterfaceStability;
@ -32,12 +31,11 @@ import org.apache.yetus.audience.InterfaceStability;
public interface CellComparator extends Comparator<Cell> { public interface CellComparator extends Comparator<Cell> {
/** /**
* A comparator for ordering cells in user-space tables. Useful when writing cells in sorted * A comparator for ordering cells in user-space tables. Useful when writing cells in sorted
* order as necessary for bulk import (i.e. via MapReduce). * order as necessary for bulk import (i.e. via MapReduce)
* <p> * <p>
* CAUTION: This comparator may provide inaccurate ordering for cells from system tables, * CAUTION: This comparator may provide inaccurate ordering for cells from system tables,
* and should not be relied upon in that case. * and should not be relied upon in that case.
*/ */
// For internal use, see CellComparatorImpl utility methods.
static CellComparator getInstance() { static CellComparator getInstance() {
return CellComparatorImpl.COMPARATOR; return CellComparatorImpl.COMPARATOR;
} }
@ -82,24 +80,6 @@ public interface CellComparator extends Comparator<Cell> {
*/ */
int compareRows(Cell cell, byte[] bytes, int offset, int length); int compareRows(Cell cell, byte[] bytes, int offset, int length);
/**
* @param row ByteBuffer that wraps a row; will read from current position and will reading all
* remaining; will not disturb the ByteBuffer internal state.
* @return greater than 0 if leftCell is bigger, less than 0 if rightCell is bigger, 0 if both
* cells are equal
*/
default int compareRows(ByteBuffer row, Cell cell) {
if (cell instanceof ByteBufferExtendedCell) {
return ByteBufferUtils.compareTo(row, row.position(), row.remaining(),
((ByteBufferExtendedCell) cell).getRowByteBuffer(),
((ByteBufferExtendedCell) cell).getRowPosition(),
cell.getRowLength());
}
return ByteBufferUtils.compareTo(row, row.position(), row.remaining(),
cell.getRowArray(), cell.getRowOffset(),
cell.getRowLength());
}
/** /**
* Lexographically compares the two cells excluding the row part. It compares family, qualifier, * Lexographically compares the two cells excluding the row part. It compares family, qualifier,
* timestamp and the type * timestamp and the type

View File

@ -17,8 +17,8 @@
*/ */
package org.apache.hadoop.hbase; package org.apache.hadoop.hbase;
import java.nio.ByteBuffer;
import java.util.Comparator; import java.util.Comparator;
import org.apache.hadoop.hbase.KeyValue.Type; import org.apache.hadoop.hbase.KeyValue.Type;
import org.apache.hadoop.hbase.util.ByteBufferUtils; import org.apache.hadoop.hbase.util.ByteBufferUtils;
import org.apache.hadoop.hbase.util.Bytes; import org.apache.hadoop.hbase.util.Bytes;
@ -26,6 +26,7 @@ import org.apache.yetus.audience.InterfaceAudience;
import org.apache.yetus.audience.InterfaceStability; import org.apache.yetus.audience.InterfaceStability;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import org.apache.hbase.thirdparty.com.google.common.primitives.Longs; import org.apache.hbase.thirdparty.com.google.common.primitives.Longs;
/** /**
@ -376,26 +377,6 @@ public class CellComparatorImpl implements CellComparator {
return result; return result;
} }
@Override
public int compareRows(ByteBuffer row, Cell cell) {
byte [] array;
int offset;
int len = row.remaining();
if (row.hasArray()) {
array = row.array();
offset = row.position() + row.arrayOffset();
} else {
// We copy the row array if offheap just so we can do a compare. We do this elsewhere too
// in BBUtils when Cell is backed by an offheap ByteBuffer. Needs fixing so no copy. TODO.
array = new byte[len];
offset = 0;
ByteBufferUtils.copyFromBufferToArray(array, row, row.position(),
0, len);
}
// Reverse result since we swap the order of the params we pass below.
return -compareRows(cell, array, offset, len);
}
@Override @Override
public Comparator getSimpleComparator() { public Comparator getSimpleComparator() {
return this; return this;
@ -406,24 +387,4 @@ public class CellComparatorImpl implements CellComparator {
public Comparator getSimpleComparator() { public Comparator getSimpleComparator() {
return new BBKVComparator(this); return new BBKVComparator(this);
} }
/**
* Utility method that makes a guess at comparator to use based off passed tableName.
* Use in extreme when no comparator specified.
* @return CellComparator to use going off the {@code tableName} passed.
*/
public static CellComparator getCellComparator(TableName tableName) {
return getCellComparator(tableName.toBytes());
}
/**
* Utility method that makes a guess at comparator to use based off passed tableName.
* Use in extreme when no comparator specified.
* @return CellComparator to use going off the {@code tableName} passed.
*/
public static CellComparator getCellComparator(byte [] tableName) {
// FYI, TableName.toBytes does not create an array; just returns existing array pointer.
return Bytes.equals(tableName, TableName.META_TABLE_NAME.toBytes())?
CellComparatorImpl.META_COMPARATOR: CellComparatorImpl.COMPARATOR;
}
} }

View File

@ -286,9 +286,6 @@ public final class TableName implements Comparable<TableName> {
return qualifierAsString; return qualifierAsString;
} }
/**
* @return A pointer to TableName as String bytes.
*/
public byte[] toBytes() { public byte[] toBytes() {
return name; return name;
} }

View File

@ -18,8 +18,10 @@ package org.apache.hadoop.hbase.io.encoding;
import java.io.IOException; import java.io.IOException;
import java.nio.ByteBuffer; import java.nio.ByteBuffer;
import org.apache.hadoop.hbase.ByteBufferKeyOnlyKeyValue; import org.apache.hadoop.hbase.ByteBufferKeyOnlyKeyValue;
import org.apache.hadoop.hbase.Cell; import org.apache.hadoop.hbase.Cell;
import org.apache.hadoop.hbase.CellComparator;
import org.apache.hadoop.hbase.KeyValue; import org.apache.hadoop.hbase.KeyValue;
import org.apache.hadoop.hbase.io.hfile.BlockType; import org.apache.hadoop.hbase.io.hfile.BlockType;
import org.apache.hadoop.hbase.io.hfile.HFileContext; import org.apache.hadoop.hbase.io.hfile.HFileContext;
@ -57,13 +59,14 @@ public abstract class AbstractDataBlockEncoder implements DataBlockEncoder {
} }
} }
/** protected abstract static class AbstractEncodedSeeker implements
* Decorates EncodedSeeker with a {@link HFileBlockDecodingContext} EncodedSeeker {
*/
protected abstract static class AbstractEncodedSeeker implements EncodedSeeker {
protected HFileBlockDecodingContext decodingCtx; protected HFileBlockDecodingContext decodingCtx;
protected final CellComparator comparator;
public AbstractEncodedSeeker(HFileBlockDecodingContext decodingCtx) { public AbstractEncodedSeeker(CellComparator comparator,
HFileBlockDecodingContext decodingCtx) {
this.comparator = comparator;
this.decodingCtx = decodingCtx; this.decodingCtx = decodingCtx;
} }
@ -74,5 +77,7 @@ public abstract class AbstractDataBlockEncoder implements DataBlockEncoder {
protected boolean includesTags() { protected boolean includesTags() {
return this.decodingCtx.getHFileContext().isIncludesTags(); return this.decodingCtx.getHFileContext().isIncludesTags();
} }
} }
} }

View File

@ -732,8 +732,9 @@ abstract class BufferedDataBlockEncoder extends AbstractDataBlockEncoder {
protected final ObjectIntPair<ByteBuffer> tmpPair = new ObjectIntPair<>(); protected final ObjectIntPair<ByteBuffer> tmpPair = new ObjectIntPair<>();
protected STATE current, previous; protected STATE current, previous;
public BufferedEncodedSeeker(HFileBlockDecodingContext decodingCtx) { public BufferedEncodedSeeker(CellComparator comparator,
super(decodingCtx); HFileBlockDecodingContext decodingCtx) {
super(comparator, decodingCtx);
if (decodingCtx.getHFileContext().isCompressTags()) { if (decodingCtx.getHFileContext().isCompressTags()) {
try { try {
tagCompressionContext = new TagCompressionContext(LRUDictionary.class, Byte.MAX_VALUE); tagCompressionContext = new TagCompressionContext(LRUDictionary.class, Byte.MAX_VALUE);
@ -1007,7 +1008,11 @@ abstract class BufferedDataBlockEncoder extends AbstractDataBlockEncoder {
} }
/** /**
* @param cell
* @param out
* @param encodingCtx
* @return unencoded size added * @return unencoded size added
* @throws IOException
*/ */
protected final int afterEncodingKeyValue(Cell cell, DataOutputStream out, protected final int afterEncodingKeyValue(Cell cell, DataOutputStream out,
HFileBlockDefaultEncodingContext encodingCtx) throws IOException { HFileBlockDefaultEncodingContext encodingCtx) throws IOException {
@ -1097,7 +1102,7 @@ abstract class BufferedDataBlockEncoder extends AbstractDataBlockEncoder {
public void startBlockEncoding(HFileBlockEncodingContext blkEncodingCtx, DataOutputStream out) public void startBlockEncoding(HFileBlockEncodingContext blkEncodingCtx, DataOutputStream out)
throws IOException { throws IOException {
if (blkEncodingCtx.getClass() != HFileBlockDefaultEncodingContext.class) { if (blkEncodingCtx.getClass() != HFileBlockDefaultEncodingContext.class) {
throw new IOException(this.getClass().getName() + " only accepts " throw new IOException (this.getClass().getName() + " only accepts "
+ HFileBlockDefaultEncodingContext.class.getName() + " as the " + + HFileBlockDefaultEncodingContext.class.getName() + " as the " +
"encoding context."); "encoding context.");
} }
@ -1149,8 +1154,8 @@ abstract class BufferedDataBlockEncoder extends AbstractDataBlockEncoder {
.getEncodingState(); .getEncodingState();
// Write the unencodedDataSizeWritten (with header size) // Write the unencodedDataSizeWritten (with header size)
Bytes.putInt(uncompressedBytesWithHeader, Bytes.putInt(uncompressedBytesWithHeader,
HConstants.HFILEBLOCK_HEADER_SIZE + DataBlockEncoding.ID_SIZE, HConstants.HFILEBLOCK_HEADER_SIZE + DataBlockEncoding.ID_SIZE, state.unencodedDataSizeWritten
state.unencodedDataSizeWritten); );
postEncoding(encodingCtx); postEncoding(encodingCtx);
} }

View File

@ -20,7 +20,9 @@ import java.io.DataInputStream;
import java.io.DataOutputStream; import java.io.DataOutputStream;
import java.io.IOException; import java.io.IOException;
import java.nio.ByteBuffer; import java.nio.ByteBuffer;
import org.apache.hadoop.hbase.Cell; import org.apache.hadoop.hbase.Cell;
import org.apache.hadoop.hbase.CellComparator;
import org.apache.hadoop.hbase.nio.ByteBuff; import org.apache.hadoop.hbase.nio.ByteBuff;
import org.apache.hadoop.hbase.util.ByteBufferUtils; import org.apache.hadoop.hbase.util.ByteBufferUtils;
import org.apache.hadoop.hbase.util.Bytes; import org.apache.hadoop.hbase.util.Bytes;
@ -46,8 +48,7 @@ public class CopyKeyDataBlockEncoder extends BufferedDataBlockEncoder {
+ "encoding context."); + "encoding context.");
} }
HFileBlockDefaultEncodingContext encodingCtx = HFileBlockDefaultEncodingContext encodingCtx = (HFileBlockDefaultEncodingContext) blkEncodingCtx;
(HFileBlockDefaultEncodingContext) blkEncodingCtx;
encodingCtx.prepareEncoding(out); encodingCtx.prepareEncoding(out);
NoneEncoder encoder = new NoneEncoder(out, encodingCtx); NoneEncoder encoder = new NoneEncoder(out, encodingCtx);
@ -80,8 +81,9 @@ public class CopyKeyDataBlockEncoder extends BufferedDataBlockEncoder {
} }
@Override @Override
public EncodedSeeker createSeeker(final HFileBlockDecodingContext decodingCtx) { public EncodedSeeker createSeeker(CellComparator comparator,
return new BufferedEncodedSeeker<SeekerState>(decodingCtx) { final HFileBlockDecodingContext decodingCtx) {
return new BufferedEncodedSeeker<SeekerState>(comparator, decodingCtx) {
@Override @Override
protected void decodeNext() { protected void decodeNext() {
current.keyLength = currentBuffer.getInt(); current.keyLength = currentBuffer.getInt();

View File

@ -20,6 +20,7 @@ import java.io.DataInputStream;
import java.io.DataOutputStream; import java.io.DataOutputStream;
import java.io.IOException; import java.io.IOException;
import java.nio.ByteBuffer; import java.nio.ByteBuffer;
import org.apache.hadoop.hbase.Cell; import org.apache.hadoop.hbase.Cell;
import org.apache.hadoop.hbase.CellComparator; import org.apache.hadoop.hbase.CellComparator;
import org.apache.hadoop.hbase.io.hfile.HFileContext; import org.apache.hadoop.hbase.io.hfile.HFileContext;
@ -44,13 +45,20 @@ public interface DataBlockEncoder {
* Starts encoding for a block of KeyValues. Call * Starts encoding for a block of KeyValues. Call
* {@link #endBlockEncoding(HFileBlockEncodingContext, DataOutputStream, byte[])} to finish * {@link #endBlockEncoding(HFileBlockEncodingContext, DataOutputStream, byte[])} to finish
* encoding of a block. * encoding of a block.
* @param encodingCtx
* @param out
* @throws IOException
*/ */
void startBlockEncoding(HFileBlockEncodingContext encodingCtx, DataOutputStream out) void startBlockEncoding(HFileBlockEncodingContext encodingCtx, DataOutputStream out)
throws IOException; throws IOException;
/** /**
* Encodes a KeyValue. * Encodes a KeyValue.
* @param cell
* @param encodingCtx
* @param out
* @return unencoded kv size written * @return unencoded kv size written
* @throws IOException
*/ */
int encode(Cell cell, HFileBlockEncodingContext encodingCtx, DataOutputStream out) int encode(Cell cell, HFileBlockEncodingContext encodingCtx, DataOutputStream out)
throws IOException; throws IOException;
@ -58,6 +66,10 @@ public interface DataBlockEncoder {
/** /**
* Ends encoding for a block of KeyValues. Gives a chance for the encoder to do the finishing * Ends encoding for a block of KeyValues. Gives a chance for the encoder to do the finishing
* stuff for the encoded block. It must be called at the end of block encoding. * stuff for the encoded block. It must be called at the end of block encoding.
* @param encodingCtx
* @param out
* @param uncompressedBytesWithHeader
* @throws IOException
*/ */
void endBlockEncoding(HFileBlockEncodingContext encodingCtx, DataOutputStream out, void endBlockEncoding(HFileBlockEncodingContext encodingCtx, DataOutputStream out,
byte[] uncompressedBytesWithHeader) throws IOException; byte[] uncompressedBytesWithHeader) throws IOException;
@ -65,6 +77,7 @@ public interface DataBlockEncoder {
/** /**
* Decode. * Decode.
* @param source Compressed stream of KeyValues. * @param source Compressed stream of KeyValues.
* @param decodingCtx
* @return Uncompressed block of KeyValues. * @return Uncompressed block of KeyValues.
* @throws IOException If there is an error in source. * @throws IOException If there is an error in source.
*/ */
@ -83,9 +96,11 @@ public interface DataBlockEncoder {
/** /**
* Create a HFileBlock seeker which find KeyValues within a block. * Create a HFileBlock seeker which find KeyValues within a block.
* @param comparator what kind of comparison should be used
* @param decodingCtx
* @return A newly created seeker. * @return A newly created seeker.
*/ */
EncodedSeeker createSeeker(HFileBlockDecodingContext decodingCtx); EncodedSeeker createSeeker(CellComparator comparator, HFileBlockDecodingContext decodingCtx);
/** /**
* Creates a encoder specific encoding context * Creates a encoder specific encoding context
@ -173,6 +188,8 @@ public interface DataBlockEncoder {
/** /**
* Compare the given key against the current key * Compare the given key against the current key
* @param comparator
* @param key
* @return -1 is the passed key is smaller than the current key, 0 if equal and 1 if greater * @return -1 is the passed key is smaller than the current key, 0 if equal and 1 if greater
*/ */
public int compareKey(CellComparator comparator, Cell key); public int compareKey(CellComparator comparator, Cell key);

View File

@ -20,7 +20,9 @@ import java.io.DataInputStream;
import java.io.DataOutputStream; import java.io.DataOutputStream;
import java.io.IOException; import java.io.IOException;
import java.nio.ByteBuffer; import java.nio.ByteBuffer;
import org.apache.hadoop.hbase.Cell; import org.apache.hadoop.hbase.Cell;
import org.apache.hadoop.hbase.CellComparator;
import org.apache.hadoop.hbase.KeyValue; import org.apache.hadoop.hbase.KeyValue;
import org.apache.hadoop.hbase.KeyValueUtil; import org.apache.hadoop.hbase.KeyValueUtil;
import org.apache.hadoop.hbase.PrivateCellUtil; import org.apache.hadoop.hbase.PrivateCellUtil;
@ -380,8 +382,9 @@ public class DiffKeyDeltaEncoder extends BufferedDataBlockEncoder {
} }
@Override @Override
public EncodedSeeker createSeeker(HFileBlockDecodingContext decodingCtx) { public EncodedSeeker createSeeker(CellComparator comparator,
return new BufferedEncodedSeeker<DiffSeekerState>(decodingCtx) { HFileBlockDecodingContext decodingCtx) {
return new BufferedEncodedSeeker<DiffSeekerState>(comparator, decodingCtx) {
private byte[] familyNameWithSize; private byte[] familyNameWithSize;
private static final int TIMESTAMP_WITH_TYPE_LENGTH = private static final int TIMESTAMP_WITH_TYPE_LENGTH =
Bytes.SIZEOF_LONG + Bytes.SIZEOF_BYTE; Bytes.SIZEOF_LONG + Bytes.SIZEOF_BYTE;

View File

@ -21,7 +21,9 @@ import java.io.DataOutput;
import java.io.DataOutputStream; import java.io.DataOutputStream;
import java.io.IOException; import java.io.IOException;
import java.nio.ByteBuffer; import java.nio.ByteBuffer;
import org.apache.hadoop.hbase.Cell; import org.apache.hadoop.hbase.Cell;
import org.apache.hadoop.hbase.CellComparator;
import org.apache.hadoop.hbase.KeyValue; import org.apache.hadoop.hbase.KeyValue;
import org.apache.hadoop.hbase.KeyValueUtil; import org.apache.hadoop.hbase.KeyValueUtil;
import org.apache.hadoop.hbase.PrivateCellUtil; import org.apache.hadoop.hbase.PrivateCellUtil;
@ -395,8 +397,9 @@ public class FastDiffDeltaEncoder extends BufferedDataBlockEncoder {
} }
@Override @Override
public EncodedSeeker createSeeker(final HFileBlockDecodingContext decodingCtx) { public EncodedSeeker createSeeker(CellComparator comparator,
return new BufferedEncodedSeeker<FastDiffSeekerState>(decodingCtx) { final HFileBlockDecodingContext decodingCtx) {
return new BufferedEncodedSeeker<FastDiffSeekerState>(comparator, decodingCtx) {
private void decode(boolean isFirst) { private void decode(boolean isFirst) {
byte flag = currentBuffer.get(); byte flag = currentBuffer.get();
if ((flag & FLAG_SAME_KEY_LENGTH) == 0) { if ((flag & FLAG_SAME_KEY_LENGTH) == 0) {

View File

@ -17,18 +17,20 @@
package org.apache.hadoop.hbase.io.encoding; package org.apache.hadoop.hbase.io.encoding;
import java.io.IOException; import java.io.IOException;
import org.apache.hadoop.hbase.io.hfile.HFileContext; import org.apache.hadoop.hbase.io.hfile.HFileContext;
import org.apache.hadoop.hbase.nio.ByteBuff; import org.apache.hadoop.hbase.nio.ByteBuff;
import org.apache.yetus.audience.InterfaceAudience; import org.apache.yetus.audience.InterfaceAudience;
/** /**
* A decoding context that is created by a reader's encoder, and is shared * A decoding context that is created by a reader's encoder, and is shared
* across all of the reader's read operations. * across the reader's all read operations.
* *
* @see HFileBlockEncodingContext for encoding * @see HFileBlockEncodingContext for encoding
*/ */
@InterfaceAudience.Private @InterfaceAudience.Private
public interface HFileBlockDecodingContext { public interface HFileBlockDecodingContext {
/** /**
* Perform all actions that need to be done before the encoder's real decoding * Perform all actions that need to be done before the encoder's real decoding
* process. Decompression needs to be done if * process. Decompression needs to be done if
@ -44,6 +46,7 @@ public interface HFileBlockDecodingContext {
* ByteBuffer pointed after the header but before the data * ByteBuffer pointed after the header but before the data
* @param onDiskBlock * @param onDiskBlock
* on disk data to be decoded * on disk data to be decoded
* @throws IOException
*/ */
void prepareDecoding( void prepareDecoding(
int onDiskSizeWithoutHeader, int onDiskSizeWithoutHeader,

View File

@ -19,6 +19,7 @@ package org.apache.hadoop.hbase.io.encoding;
import java.io.DataInputStream; import java.io.DataInputStream;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
import org.apache.commons.io.IOUtils; import org.apache.commons.io.IOUtils;
import org.apache.hadoop.hbase.io.ByteBuffInputStream; import org.apache.hadoop.hbase.io.ByteBuffInputStream;
import org.apache.hadoop.hbase.io.TagCompressionContext; import org.apache.hadoop.hbase.io.TagCompressionContext;
@ -40,10 +41,11 @@ import org.apache.yetus.audience.InterfaceAudience;
* *
*/ */
@InterfaceAudience.Private @InterfaceAudience.Private
public class HFileBlockDefaultDecodingContext implements HFileBlockDecodingContext { public class HFileBlockDefaultDecodingContext implements
HFileBlockDecodingContext {
private final HFileContext fileContext; private final HFileContext fileContext;
private TagCompressionContext tagCompressionContext; private TagCompressionContext tagCompressionContext;
public HFileBlockDefaultDecodingContext(HFileContext fileContext) { public HFileBlockDefaultDecodingContext(HFileContext fileContext) {
this.fileContext = fileContext; this.fileContext = fileContext;
} }

View File

@ -17,11 +17,13 @@
package org.apache.hadoop.hbase.io.encoding; package org.apache.hadoop.hbase.io.encoding;
import static org.apache.hadoop.hbase.io.compress.Compression.Algorithm.NONE; import static org.apache.hadoop.hbase.io.compress.Compression.Algorithm.NONE;
import java.io.ByteArrayInputStream; import java.io.ByteArrayInputStream;
import java.io.DataOutputStream; import java.io.DataOutputStream;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
import java.security.SecureRandom; import java.security.SecureRandom;
import org.apache.hadoop.hbase.io.ByteArrayOutputStream; import org.apache.hadoop.hbase.io.ByteArrayOutputStream;
import org.apache.hadoop.hbase.io.TagCompressionContext; import org.apache.hadoop.hbase.io.TagCompressionContext;
import org.apache.hadoop.hbase.io.compress.Compression; import org.apache.hadoop.hbase.io.compress.Compression;
@ -34,6 +36,7 @@ import org.apache.hadoop.hbase.util.Bytes;
import org.apache.hadoop.io.compress.CompressionOutputStream; import org.apache.hadoop.io.compress.CompressionOutputStream;
import org.apache.hadoop.io.compress.Compressor; import org.apache.hadoop.io.compress.Compressor;
import org.apache.yetus.audience.InterfaceAudience; import org.apache.yetus.audience.InterfaceAudience;
import org.apache.hbase.thirdparty.com.google.common.base.Preconditions; import org.apache.hbase.thirdparty.com.google.common.base.Preconditions;
/** /**
@ -44,7 +47,8 @@ import org.apache.hbase.thirdparty.com.google.common.base.Preconditions;
* *
*/ */
@InterfaceAudience.Private @InterfaceAudience.Private
public class HFileBlockDefaultEncodingContext implements HFileBlockEncodingContext { public class HFileBlockDefaultEncodingContext implements
HFileBlockEncodingContext {
private BlockType blockType; private BlockType blockType;
private final DataBlockEncoding encodingAlgo; private final DataBlockEncoding encodingAlgo;
@ -109,6 +113,7 @@ public class HFileBlockDefaultEncodingContext implements HFileBlockEncodingConte
/** /**
* prepare to start a new encoding. * prepare to start a new encoding.
* @throws IOException
*/ */
public void prepareEncoding(DataOutputStream out) throws IOException { public void prepareEncoding(DataOutputStream out) throws IOException {
if (encodingAlgo != null && encodingAlgo != DataBlockEncoding.NONE) { if (encodingAlgo != null && encodingAlgo != DataBlockEncoding.NONE) {
@ -128,8 +133,7 @@ public class HFileBlockDefaultEncodingContext implements HFileBlockEncodingConte
} }
private Bytes compressAfterEncoding(byte[] uncompressedBytesWithHeaderBuffer, private Bytes compressAfterEncoding(byte[] uncompressedBytesWithHeaderBuffer,
int uncompressedBytesWithHeaderOffset, int uncompressedBytesWithHeaderLength, int uncompressedBytesWithHeaderOffset, int uncompressedBytesWithHeaderLength, byte[] headerBytes)
byte[] headerBytes)
throws IOException { throws IOException {
Encryption.Context cryptoContext = fileContext.getEncryptionContext(); Encryption.Context cryptoContext = fileContext.getEncryptionContext();
if (cryptoContext != Encryption.Context.NONE) { if (cryptoContext != Encryption.Context.NONE) {
@ -154,8 +158,7 @@ public class HFileBlockDefaultEncodingContext implements HFileBlockEncodingConte
compressedByteStream.reset(); compressedByteStream.reset();
compressionStream.resetState(); compressionStream.resetState();
compressionStream.write(uncompressedBytesWithHeaderBuffer, compressionStream.write(uncompressedBytesWithHeaderBuffer,
headerBytes.length + uncompressedBytesWithHeaderOffset, headerBytes.length + uncompressedBytesWithHeaderOffset, uncompressedBytesWithHeaderLength - headerBytes.length);
uncompressedBytesWithHeaderLength - headerBytes.length);
compressionStream.flush(); compressionStream.flush();
compressionStream.finish(); compressionStream.finish();
byte[] plaintext = compressedByteStream.toByteArray(); byte[] plaintext = compressedByteStream.toByteArray();

View File

@ -17,6 +17,7 @@
package org.apache.hadoop.hbase.io.encoding; package org.apache.hadoop.hbase.io.encoding;
import java.io.IOException; import java.io.IOException;
import org.apache.hadoop.hbase.io.hfile.BlockType; import org.apache.hadoop.hbase.io.hfile.BlockType;
import org.apache.hadoop.hbase.io.hfile.HFileContext; import org.apache.hadoop.hbase.io.hfile.HFileContext;
import org.apache.hadoop.hbase.util.Bytes; import org.apache.hadoop.hbase.util.Bytes;
@ -45,6 +46,9 @@ public interface HFileBlockEncodingContext {
/** /**
* Do any action that needs to be performed after the encoding. * Do any action that needs to be performed after the encoding.
* Compression is also included if a non-null compression algorithm is used * Compression is also included if a non-null compression algorithm is used
*
* @param blockType
* @throws IOException
*/ */
void postEncoding(BlockType blockType) throws IOException; void postEncoding(BlockType blockType) throws IOException;
@ -60,6 +64,7 @@ public interface HFileBlockEncodingContext {
/** /**
* Sets the encoding state. * Sets the encoding state.
* @param state
*/ */
void setEncodingState(EncodingState state); void setEncodingState(EncodingState state);

View File

@ -21,7 +21,9 @@ import java.io.DataOutput;
import java.io.DataOutputStream; import java.io.DataOutputStream;
import java.io.IOException; import java.io.IOException;
import java.nio.ByteBuffer; import java.nio.ByteBuffer;
import org.apache.hadoop.hbase.Cell; import org.apache.hadoop.hbase.Cell;
import org.apache.hadoop.hbase.CellComparator;
import org.apache.hadoop.hbase.KeyValue; import org.apache.hadoop.hbase.KeyValue;
import org.apache.hadoop.hbase.KeyValueUtil; import org.apache.hadoop.hbase.KeyValueUtil;
import org.apache.hadoop.hbase.PrivateCellUtil; import org.apache.hadoop.hbase.PrivateCellUtil;
@ -193,8 +195,9 @@ public class PrefixKeyDeltaEncoder extends BufferedDataBlockEncoder {
} }
@Override @Override
public EncodedSeeker createSeeker(final HFileBlockDecodingContext decodingCtx) { public EncodedSeeker createSeeker(CellComparator comparator,
return new BufferedEncodedSeeker<SeekerState>(decodingCtx) { final HFileBlockDecodingContext decodingCtx) {
return new BufferedEncodedSeeker<SeekerState>(comparator, decodingCtx) {
@Override @Override
protected void decodeNext() { protected void decodeNext() {
current.keyLength = ByteBuff.readCompressedInt(currentBuffer); current.keyLength = ByteBuff.readCompressedInt(currentBuffer);

View File

@ -22,7 +22,10 @@ import java.io.IOException;
import java.nio.ByteBuffer; import java.nio.ByteBuffer;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import org.apache.hadoop.hbase.Cell; import org.apache.hadoop.hbase.Cell;
import org.apache.hadoop.hbase.CellComparator;
import org.apache.hadoop.hbase.CellComparatorImpl;
import org.apache.hadoop.hbase.KeyValue; import org.apache.hadoop.hbase.KeyValue;
import org.apache.hadoop.hbase.KeyValueUtil; import org.apache.hadoop.hbase.KeyValueUtil;
import org.apache.hadoop.hbase.io.ByteArrayOutputStream; import org.apache.hadoop.hbase.io.ByteArrayOutputStream;
@ -68,8 +71,7 @@ public class RowIndexCodecV1 extends AbstractDataBlockEncoder {
+ "encoding context."); + "encoding context.");
} }
HFileBlockDefaultEncodingContext encodingCtx = HFileBlockDefaultEncodingContext encodingCtx = (HFileBlockDefaultEncodingContext) blkEncodingCtx;
(HFileBlockDefaultEncodingContext) blkEncodingCtx;
encodingCtx.prepareEncoding(out); encodingCtx.prepareEncoding(out);
RowIndexEncoderV1 encoder = new RowIndexEncoderV1(out, encodingCtx); RowIndexEncoderV1 encoder = new RowIndexEncoderV1(out, encodingCtx);
@ -113,7 +115,8 @@ public class RowIndexCodecV1 extends AbstractDataBlockEncoder {
dup.limit(sourceAsBuffer.position() + onDiskSize); dup.limit(sourceAsBuffer.position() + onDiskSize);
return dup.slice(); return dup.slice();
} else { } else {
RowIndexSeekerV1 seeker = new RowIndexSeekerV1(decodingCtx); RowIndexSeekerV1 seeker = new RowIndexSeekerV1(CellComparatorImpl.COMPARATOR,
decodingCtx);
seeker.setCurrentBuffer(new SingleByteBuff(sourceAsBuffer)); seeker.setCurrentBuffer(new SingleByteBuff(sourceAsBuffer));
List<Cell> kvs = new ArrayList<>(); List<Cell> kvs = new ArrayList<>();
kvs.add(seeker.getCell()); kvs.add(seeker.getCell());
@ -147,7 +150,9 @@ public class RowIndexCodecV1 extends AbstractDataBlockEncoder {
} }
@Override @Override
public EncodedSeeker createSeeker(HFileBlockDecodingContext decodingCtx) { public EncodedSeeker createSeeker(CellComparator comparator,
return new RowIndexSeekerV1(decodingCtx); HFileBlockDecodingContext decodingCtx) {
return new RowIndexSeekerV1(comparator, decodingCtx);
} }
} }

View File

@ -12,7 +12,9 @@ package org.apache.hadoop.hbase.io.encoding;
import java.io.DataOutputStream; import java.io.DataOutputStream;
import java.io.IOException; import java.io.IOException;
import org.apache.hadoop.hbase.Cell; import org.apache.hadoop.hbase.Cell;
import org.apache.hadoop.hbase.CellComparatorImpl;
import org.apache.hadoop.hbase.KeyValueUtil; import org.apache.hadoop.hbase.KeyValueUtil;
import org.apache.hadoop.hbase.io.ByteArrayOutputStream; import org.apache.hadoop.hbase.io.ByteArrayOutputStream;
import org.apache.yetus.audience.InterfaceAudience; import org.apache.yetus.audience.InterfaceAudience;
@ -30,12 +32,10 @@ public class RowIndexEncoderV1 {
private NoneEncoder encoder; private NoneEncoder encoder;
private int startOffset = -1; private int startOffset = -1;
private ByteArrayOutputStream rowsOffsetBAOS = new ByteArrayOutputStream(64 * 4); private ByteArrayOutputStream rowsOffsetBAOS = new ByteArrayOutputStream(64 * 4);
private final HFileBlockEncodingContext context;
public RowIndexEncoderV1(DataOutputStream out, HFileBlockDefaultEncodingContext encodingCtx) { public RowIndexEncoderV1(DataOutputStream out, HFileBlockDefaultEncodingContext encodingCtx) {
this.out = out; this.out = out;
this.encoder = new NoneEncoder(out, encodingCtx); this.encoder = new NoneEncoder(out, encodingCtx);
this.context = encodingCtx;
} }
public int write(Cell cell) throws IOException { public int write(Cell cell) throws IOException {
@ -56,7 +56,7 @@ public class RowIndexEncoderV1 {
throw new IOException("Key cannot be null or empty"); throw new IOException("Key cannot be null or empty");
} }
if (lastCell != null) { if (lastCell != null) {
int keyComp = this.context.getHFileContext().getCellComparator().compareRows(lastCell, cell); int keyComp = CellComparatorImpl.COMPARATOR.compareRows(lastCell, cell);
if (keyComp > 0) { if (keyComp > 0) {
throw new IOException("Added a key not lexically larger than" throw new IOException("Added a key not lexically larger than"
+ " previous. Current cell = " + cell + ", lastCell = " + lastCell); + " previous. Current cell = " + cell + ", lastCell = " + lastCell);

View File

@ -17,6 +17,8 @@
package org.apache.hadoop.hbase.io.encoding; package org.apache.hadoop.hbase.io.encoding;
import java.nio.ByteBuffer; import java.nio.ByteBuffer;
import org.apache.hadoop.hbase.ByteBufferExtendedCell;
import org.apache.hadoop.hbase.ByteBufferKeyOnlyKeyValue; import org.apache.hadoop.hbase.ByteBufferKeyOnlyKeyValue;
import org.apache.hadoop.hbase.ByteBufferKeyValue; import org.apache.hadoop.hbase.ByteBufferKeyValue;
import org.apache.hadoop.hbase.Cell; import org.apache.hadoop.hbase.Cell;
@ -48,11 +50,10 @@ public class RowIndexSeekerV1 extends AbstractEncodedSeeker {
private int rowNumber; private int rowNumber;
private ByteBuff rowOffsets = null; private ByteBuff rowOffsets = null;
private final CellComparator cellComparator;
public RowIndexSeekerV1(HFileBlockDecodingContext decodingCtx) { public RowIndexSeekerV1(CellComparator comparator,
super(decodingCtx); HFileBlockDecodingContext decodingCtx) {
this.cellComparator = decodingCtx.getHFileContext().getCellComparator(); super(comparator, decodingCtx);
} }
@Override @Override
@ -130,7 +131,8 @@ public class RowIndexSeekerV1 extends AbstractEncodedSeeker {
int comp = 0; int comp = 0;
while (low <= high) { while (low <= high) {
mid = low + ((high - low) >> 1); mid = low + ((high - low) >> 1);
comp = this.cellComparator.compareRows(getRow(mid), seekCell); ByteBuffer row = getRow(mid);
comp = compareRows(row, seekCell);
if (comp < 0) { if (comp < 0) {
low = mid + 1; low = mid + 1;
} else if (comp > 0) { } else if (comp > 0) {
@ -152,6 +154,19 @@ public class RowIndexSeekerV1 extends AbstractEncodedSeeker {
} }
} }
private int compareRows(ByteBuffer row, Cell seekCell) {
if (seekCell instanceof ByteBufferExtendedCell) {
return ByteBufferUtils.compareTo(row, row.position(), row.remaining(),
((ByteBufferExtendedCell) seekCell).getRowByteBuffer(),
((ByteBufferExtendedCell) seekCell).getRowPosition(),
seekCell.getRowLength());
} else {
return ByteBufferUtils.compareTo(row, row.position(), row.remaining(),
seekCell.getRowArray(), seekCell.getRowOffset(),
seekCell.getRowLength());
}
}
private ByteBuffer getRow(int index) { private ByteBuffer getRow(int index) {
int offset = rowOffsets.getIntAfterPosition(index * Bytes.SIZEOF_INT); int offset = rowOffsets.getIntAfterPosition(index * Bytes.SIZEOF_INT);
ByteBuff block = currentBuffer.duplicate(); ByteBuff block = currentBuffer.duplicate();
@ -176,8 +191,8 @@ public class RowIndexSeekerV1 extends AbstractEncodedSeeker {
} }
} }
do { do {
int comp = int comp;
PrivateCellUtil.compareKeyIgnoresMvcc(this.cellComparator, seekCell, current.currentKey); comp = PrivateCellUtil.compareKeyIgnoresMvcc(comparator, seekCell, current.currentKey);
if (comp == 0) { // exact match if (comp == 0) { // exact match
if (seekBefore) { if (seekBefore) {
if (!previous.isValid()) { if (!previous.isValid()) {
@ -385,4 +400,5 @@ public class RowIndexSeekerV1 extends AbstractEncodedSeeker {
return ret; return ret;
} }
} }
} }

View File

@ -17,8 +17,6 @@
*/ */
package org.apache.hadoop.hbase.io.hfile; package org.apache.hadoop.hbase.io.hfile;
import org.apache.hadoop.hbase.CellComparator;
import org.apache.hadoop.hbase.CellComparatorImpl;
import org.apache.hadoop.hbase.HConstants; import org.apache.hadoop.hbase.HConstants;
import org.apache.hadoop.hbase.io.HeapSize; import org.apache.hadoop.hbase.io.HeapSize;
import org.apache.hadoop.hbase.io.compress.Compression; import org.apache.hadoop.hbase.io.compress.Compression;
@ -30,10 +28,9 @@ import org.apache.hadoop.hbase.util.ClassSize;
import org.apache.yetus.audience.InterfaceAudience; import org.apache.yetus.audience.InterfaceAudience;
/** /**
* Read-only HFile Context Information. Meta data that is used by HFileWriter/Readers and by * This carries the information on some of the meta data about the HFile. This
* HFileBlocks. Create one using the {@link HFileContextBuilder} (See HFileInfo and the HFile * meta data is used across the HFileWriter/Readers and the HFileBlocks.
* Trailer class). * This helps to add new information to the HFile.
* @see HFileContextBuilder
*/ */
@InterfaceAudience.Private @InterfaceAudience.Private
public class HFileContext implements HeapSize, Cloneable { public class HFileContext implements HeapSize, Cloneable {
@ -45,7 +42,7 @@ public class HFileContext implements HeapSize, Cloneable {
//byte[] headers for column family and table name //byte[] headers for column family and table name
2 * ClassSize.ARRAY + 2 * ClassSize.REFERENCE); 2 * ClassSize.ARRAY + 2 * ClassSize.REFERENCE);
private static final int DEFAULT_BYTES_PER_CHECKSUM = 16 * 1024; public static final int DEFAULT_BYTES_PER_CHECKSUM = 16 * 1024;
/** Whether checksum is enabled or not**/ /** Whether checksum is enabled or not**/
private boolean usesHBaseChecksum = true; private boolean usesHBaseChecksum = true;
@ -70,7 +67,6 @@ public class HFileContext implements HeapSize, Cloneable {
private String hfileName; private String hfileName;
private byte[] columnFamily; private byte[] columnFamily;
private byte[] tableName; private byte[] tableName;
private CellComparator cellComparator;
//Empty constructor. Go with setters //Empty constructor. Go with setters
public HFileContext() { public HFileContext() {
@ -78,6 +74,7 @@ public class HFileContext implements HeapSize, Cloneable {
/** /**
* Copy constructor * Copy constructor
* @param context
*/ */
public HFileContext(HFileContext context) { public HFileContext(HFileContext context) {
this.usesHBaseChecksum = context.usesHBaseChecksum; this.usesHBaseChecksum = context.usesHBaseChecksum;
@ -94,14 +91,13 @@ public class HFileContext implements HeapSize, Cloneable {
this.hfileName = context.hfileName; this.hfileName = context.hfileName;
this.columnFamily = context.columnFamily; this.columnFamily = context.columnFamily;
this.tableName = context.tableName; this.tableName = context.tableName;
this.cellComparator = context.cellComparator;
} }
HFileContext(boolean useHBaseChecksum, boolean includesMvcc, boolean includesTags, HFileContext(boolean useHBaseChecksum, boolean includesMvcc, boolean includesTags,
Compression.Algorithm compressAlgo, boolean compressTags, ChecksumType checksumType, Compression.Algorithm compressAlgo, boolean compressTags, ChecksumType checksumType,
int bytesPerChecksum, int blockSize, DataBlockEncoding encoding, int bytesPerChecksum, int blockSize, DataBlockEncoding encoding,
Encryption.Context cryptoContext, long fileCreateTime, String hfileName, Encryption.Context cryptoContext, long fileCreateTime, String hfileName,
byte[] columnFamily, byte[] tableName, CellComparator cellComparator) { byte[] columnFamily, byte[] tableName) {
this.usesHBaseChecksum = useHBaseChecksum; this.usesHBaseChecksum = useHBaseChecksum;
this.includesMvcc = includesMvcc; this.includesMvcc = includesMvcc;
this.includesTags = includesTags; this.includesTags = includesTags;
@ -118,14 +114,11 @@ public class HFileContext implements HeapSize, Cloneable {
this.hfileName = hfileName; this.hfileName = hfileName;
this.columnFamily = columnFamily; this.columnFamily = columnFamily;
this.tableName = tableName; this.tableName = tableName;
// If no cellComparator specified, make a guess based off tablename. If hbase:meta, then should
// be the meta table comparator. Comparators are per table.
this.cellComparator = cellComparator != null ? cellComparator : this.tableName != null ?
CellComparatorImpl.getCellComparator(this.tableName) : CellComparator.getInstance();
} }
/** /**
* @return true when on-disk blocks are compressed, and/or encrypted; false otherwise. * @return true when on-disk blocks from this file are compressed, and/or encrypted;
* false otherwise.
*/ */
public boolean isCompressedOrEncrypted() { public boolean isCompressedOrEncrypted() {
Compression.Algorithm compressAlgo = getCompression(); Compression.Algorithm compressAlgo = getCompression();
@ -215,11 +208,6 @@ public class HFileContext implements HeapSize, Cloneable {
public byte[] getTableName() { public byte[] getTableName() {
return this.tableName; return this.tableName;
} }
public CellComparator getCellComparator() {
return this.cellComparator;
}
/** /**
* HeapSize implementation. NOTE : The heap size should be altered when new state variable are * HeapSize implementation. NOTE : The heap size should be altered when new state variable are
* added. * added.
@ -275,9 +263,8 @@ public class HFileContext implements HeapSize, Cloneable {
sb.append(", columnFamily="); sb.append(", columnFamily=");
sb.append(Bytes.toStringBinary(columnFamily)); sb.append(Bytes.toStringBinary(columnFamily));
} }
sb.append(", cellComparator=");
sb.append(this.cellComparator);
sb.append("]"); sb.append("]");
return sb.toString(); return sb.toString();
} }
} }

View File

@ -17,7 +17,6 @@
*/ */
package org.apache.hadoop.hbase.io.hfile; package org.apache.hadoop.hbase.io.hfile;
import org.apache.hadoop.hbase.CellComparator;
import org.apache.hadoop.hbase.HConstants; import org.apache.hadoop.hbase.HConstants;
import org.apache.hadoop.hbase.io.compress.Compression.Algorithm; import org.apache.hadoop.hbase.io.compress.Compression.Algorithm;
import org.apache.hadoop.hbase.io.crypto.Encryption; import org.apache.hadoop.hbase.io.crypto.Encryption;
@ -57,7 +56,6 @@ public class HFileContextBuilder {
private String hfileName = null; private String hfileName = null;
private byte[] columnFamily = null; private byte[] columnFamily = null;
private byte[] tableName = null; private byte[] tableName = null;
private CellComparator cellComparator;
public HFileContextBuilder() {} public HFileContextBuilder() {}
@ -79,7 +77,6 @@ public class HFileContextBuilder {
this.hfileName = hfc.getHFileName(); this.hfileName = hfc.getHFileName();
this.columnFamily = hfc.getColumnFamily(); this.columnFamily = hfc.getColumnFamily();
this.tableName = hfc.getTableName(); this.tableName = hfc.getTableName();
this.cellComparator = hfc.getCellComparator();
} }
public HFileContextBuilder withHBaseCheckSum(boolean useHBaseCheckSum) { public HFileContextBuilder withHBaseCheckSum(boolean useHBaseCheckSum) {
@ -152,14 +149,9 @@ public class HFileContextBuilder {
return this; return this;
} }
public HFileContextBuilder withCellComparator(CellComparator cellComparator) {
this.cellComparator = cellComparator;
return this;
}
public HFileContext build() { public HFileContext build() {
return new HFileContext(usesHBaseChecksum, includesMvcc, includesTags, compression, return new HFileContext(usesHBaseChecksum, includesMvcc, includesTags, compression,
compressTags, checksumType, bytesPerChecksum, blocksize, encoding, cryptoContext, compressTags, checksumType, bytesPerChecksum, blocksize, encoding, cryptoContext,
fileCreateTime, hfileName, columnFamily, tableName, cellComparator); fileCreateTime, hfileName, columnFamily, tableName);
} }
} }

View File

@ -1,4 +1,4 @@
/* /**
* Licensed to the Apache Software Foundation (ASF) under one * Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file * or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information * distributed with this work for additional information
@ -21,6 +21,7 @@ import static org.apache.hadoop.hbase.regionserver.HStoreFile.BULKLOAD_TASK_KEY;
import static org.apache.hadoop.hbase.regionserver.HStoreFile.BULKLOAD_TIME_KEY; import static org.apache.hadoop.hbase.regionserver.HStoreFile.BULKLOAD_TIME_KEY;
import static org.apache.hadoop.hbase.regionserver.HStoreFile.EXCLUDE_FROM_MINOR_COMPACTION_KEY; import static org.apache.hadoop.hbase.regionserver.HStoreFile.EXCLUDE_FROM_MINOR_COMPACTION_KEY;
import static org.apache.hadoop.hbase.regionserver.HStoreFile.MAJOR_COMPACTION_KEY; import static org.apache.hadoop.hbase.regionserver.HStoreFile.MAJOR_COMPACTION_KEY;
import java.io.IOException; import java.io.IOException;
import java.io.UnsupportedEncodingException; import java.io.UnsupportedEncodingException;
import java.net.InetSocketAddress; import java.net.InetSocketAddress;
@ -36,11 +37,13 @@ import java.util.TreeSet;
import java.util.UUID; import java.util.UUID;
import java.util.function.Function; import java.util.function.Function;
import java.util.stream.Collectors; import java.util.stream.Collectors;
import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.StringUtils;
import org.apache.hadoop.conf.Configuration; import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.FileSystem; import org.apache.hadoop.fs.FileSystem;
import org.apache.hadoop.fs.Path; import org.apache.hadoop.fs.Path;
import org.apache.hadoop.hbase.Cell; import org.apache.hadoop.hbase.Cell;
import org.apache.hadoop.hbase.CellComparator;
import org.apache.hadoop.hbase.CellUtil; import org.apache.hadoop.hbase.CellUtil;
import org.apache.hadoop.hbase.HConstants; import org.apache.hadoop.hbase.HConstants;
import org.apache.hadoop.hbase.HRegionLocation; import org.apache.hadoop.hbase.HRegionLocation;
@ -88,6 +91,7 @@ import org.apache.hadoop.mapreduce.lib.partition.TotalOrderPartitioner;
import org.apache.yetus.audience.InterfaceAudience; import org.apache.yetus.audience.InterfaceAudience;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import org.apache.hbase.thirdparty.com.google.common.annotations.VisibleForTesting; import org.apache.hbase.thirdparty.com.google.common.annotations.VisibleForTesting;
/** /**
@ -188,17 +192,18 @@ public class HFileOutputFormat2
return combineTableNameSuffix(tableName, family); return combineTableNameSuffix(tableName, family);
} }
static <V extends Cell> RecordWriter<ImmutableBytesWritable, V> createRecordWriter( static <V extends Cell> RecordWriter<ImmutableBytesWritable, V>
final TaskAttemptContext context, final OutputCommitter committer) throws IOException { createRecordWriter(final TaskAttemptContext context, final OutputCommitter committer)
throws IOException {
// Get the path of the temporary output file // Get the path of the temporary output file
final Path outputDir = ((FileOutputCommitter)committer).getWorkPath(); final Path outputDir = ((FileOutputCommitter)committer).getWorkPath();
final Configuration conf = context.getConfiguration(); final Configuration conf = context.getConfiguration();
final boolean writeMultipleTables = final boolean writeMultipleTables = conf.getBoolean(MULTI_TABLE_HFILEOUTPUTFORMAT_CONF_KEY, false) ;
conf.getBoolean(MULTI_TABLE_HFILEOUTPUTFORMAT_CONF_KEY, false);
final String writeTableNames = conf.get(OUTPUT_TABLE_NAME_CONF_KEY); final String writeTableNames = conf.get(OUTPUT_TABLE_NAME_CONF_KEY);
if (writeTableNames == null || writeTableNames.isEmpty()) { if (writeTableNames==null || writeTableNames.isEmpty()) {
throw new IllegalArgumentException("" + OUTPUT_TABLE_NAME_CONF_KEY + " cannot be empty"); throw new IllegalArgumentException("Configuration parameter " + OUTPUT_TABLE_NAME_CONF_KEY
+ " cannot be empty");
} }
final FileSystem fs = outputDir.getFileSystem(conf); final FileSystem fs = outputDir.getFileSystem(conf);
// These configs. are from hbase-*.xml // These configs. are from hbase-*.xml
@ -207,12 +212,18 @@ public class HFileOutputFormat2
// Invented config. Add to hbase-*.xml if other than default compression. // Invented config. Add to hbase-*.xml if other than default compression.
final String defaultCompressionStr = conf.get("hfile.compression", final String defaultCompressionStr = conf.get("hfile.compression",
Compression.Algorithm.NONE.getName()); Compression.Algorithm.NONE.getName());
final Algorithm defaultCompression = HFileWriterImpl.compressionByName(defaultCompressionStr); final Algorithm defaultCompression = HFileWriterImpl
.compressionByName(defaultCompressionStr);
String compressionStr = conf.get(COMPRESSION_OVERRIDE_CONF_KEY); String compressionStr = conf.get(COMPRESSION_OVERRIDE_CONF_KEY);
final Algorithm overriddenCompression = compressionStr != null ? final Algorithm overriddenCompression;
Compression.getCompressionAlgorithmByName(compressionStr): null; if (compressionStr != null) {
overriddenCompression = Compression.getCompressionAlgorithmByName(compressionStr);
} else {
overriddenCompression = null;
}
final boolean compactionExclude = conf.getBoolean( final boolean compactionExclude = conf.getBoolean(
"hbase.mapreduce.hfileoutputformat.compaction.exclude", false); "hbase.mapreduce.hfileoutputformat.compaction.exclude", false);
final Set<String> allTableNames = Arrays.stream(writeTableNames.split( final Set<String> allTableNames = Arrays.stream(writeTableNames.split(
Bytes.toString(tableSeparator))).collect(Collectors.toSet()); Bytes.toString(tableSeparator))).collect(Collectors.toSet());
@ -225,17 +236,24 @@ public class HFileOutputFormat2
String dataBlockEncodingStr = conf.get(DATABLOCK_ENCODING_OVERRIDE_CONF_KEY); String dataBlockEncodingStr = conf.get(DATABLOCK_ENCODING_OVERRIDE_CONF_KEY);
final Map<byte[], DataBlockEncoding> datablockEncodingMap final Map<byte[], DataBlockEncoding> datablockEncodingMap
= createFamilyDataBlockEncodingMap(conf); = createFamilyDataBlockEncodingMap(conf);
final DataBlockEncoding overriddenEncoding = dataBlockEncodingStr != null ? final DataBlockEncoding overriddenEncoding;
DataBlockEncoding.valueOf(dataBlockEncodingStr) : null; if (dataBlockEncodingStr != null) {
overriddenEncoding = DataBlockEncoding.valueOf(dataBlockEncodingStr);
} else {
overriddenEncoding = null;
}
return new RecordWriter<ImmutableBytesWritable, V>() { return new RecordWriter<ImmutableBytesWritable, V>() {
// Map of families to writers and how much has been output on the writer. // Map of families to writers and how much has been output on the writer.
private final Map<byte[], WriterLength> writers = new TreeMap<>(Bytes.BYTES_COMPARATOR); private final Map<byte[], WriterLength> writers =
private final Map<byte[], byte[]> previousRows = new TreeMap<>(Bytes.BYTES_COMPARATOR); new TreeMap<>(Bytes.BYTES_COMPARATOR);
private final Map<byte[], byte[]> previousRows =
new TreeMap<>(Bytes.BYTES_COMPARATOR);
private final long now = EnvironmentEdgeManager.currentTime(); private final long now = EnvironmentEdgeManager.currentTime();
@Override @Override
public void write(ImmutableBytesWritable row, V cell) throws IOException { public void write(ImmutableBytesWritable row, V cell)
throws IOException {
Cell kv = cell; Cell kv = cell;
// null input == user explicitly wants to flush // null input == user explicitly wants to flush
if (row == null && kv == null) { if (row == null && kv == null) {
@ -249,15 +267,13 @@ public class HFileOutputFormat2
byte[] tableNameBytes = null; byte[] tableNameBytes = null;
if (writeMultipleTables) { if (writeMultipleTables) {
tableNameBytes = MultiTableHFileOutputFormat.getTableName(row.get()); tableNameBytes = MultiTableHFileOutputFormat.getTableName(row.get());
tableNameBytes = TableName.valueOf(tableNameBytes).toBytes();
if (!allTableNames.contains(Bytes.toString(tableNameBytes))) { if (!allTableNames.contains(Bytes.toString(tableNameBytes))) {
throw new IllegalArgumentException("TableName " + Bytes.toString(tableNameBytes) + throw new IllegalArgumentException("TableName '" + Bytes.toString(tableNameBytes) +
" not expected"); "' not" + " expected");
} }
} else { } else {
tableNameBytes = Bytes.toBytes(writeTableNames); tableNameBytes = Bytes.toBytes(writeTableNames);
} }
Path tableRelPath = getTableRelativePath(tableNameBytes);
byte[] tableAndFamily = getTableNameSuffixedWithFamily(tableNameBytes, family); byte[] tableAndFamily = getTableNameSuffixedWithFamily(tableNameBytes, family);
WriterLength wl = this.writers.get(tableAndFamily); WriterLength wl = this.writers.get(tableAndFamily);
@ -265,7 +281,8 @@ public class HFileOutputFormat2
if (wl == null) { if (wl == null) {
Path writerPath = null; Path writerPath = null;
if (writeMultipleTables) { if (writeMultipleTables) {
writerPath = new Path(outputDir,new Path(tableRelPath, Bytes.toString(family))); writerPath = new Path(outputDir, new Path(Bytes.toString(tableNameBytes), Bytes
.toString(family)));
} }
else { else {
writerPath = new Path(outputDir, Bytes.toString(family)); writerPath = new Path(outputDir, Bytes.toString(family));
@ -292,23 +309,33 @@ public class HFileOutputFormat2
connection.getRegionLocator(TableName.valueOf(tableName))) { connection.getRegionLocator(TableName.valueOf(tableName))) {
loc = locator.getRegionLocation(rowKey); loc = locator.getRegionLocation(rowKey);
} catch (Throwable e) { } catch (Throwable e) {
LOG.warn("Something wrong locating rowkey {} in {}", LOG.warn("There's something wrong when locating rowkey: " +
Bytes.toString(rowKey), tableName, e); Bytes.toString(rowKey) + " for tablename: " + tableName, e);
loc = null; loc = null;
} } } }
if (null == loc) { if (null == loc) {
LOG.trace("Failed get of location, use default writer {}", Bytes.toString(rowKey)); if (LOG.isTraceEnabled()) {
LOG.trace("failed to get region location, so use default writer for rowkey: " +
Bytes.toString(rowKey));
}
wl = getNewWriter(tableNameBytes, family, conf, null); wl = getNewWriter(tableNameBytes, family, conf, null);
} else { } else {
LOG.debug("First rowkey: [{}]", Bytes.toString(rowKey)); if (LOG.isDebugEnabled()) {
LOG.debug("first rowkey: [" + Bytes.toString(rowKey) + "]");
}
InetSocketAddress initialIsa = InetSocketAddress initialIsa =
new InetSocketAddress(loc.getHostname(), loc.getPort()); new InetSocketAddress(loc.getHostname(), loc.getPort());
if (initialIsa.isUnresolved()) { if (initialIsa.isUnresolved()) {
LOG.trace("Failed resolve address {}, use default writer", loc.getHostnamePort()); if (LOG.isTraceEnabled()) {
LOG.trace("failed to resolve bind address: " + loc.getHostname() + ":"
+ loc.getPort() + ", so use default writer");
}
wl = getNewWriter(tableNameBytes, family, conf, null); wl = getNewWriter(tableNameBytes, family, conf, null);
} else { } else {
LOG.debug("Use favored nodes writer: {}", initialIsa.getHostString()); if (LOG.isDebugEnabled()) {
LOG.debug("use favored nodes writer: " + initialIsa.getHostString());
}
wl = getNewWriter(tableNameBytes, family, conf, new InetSocketAddress[] { initialIsa wl = getNewWriter(tableNameBytes, family, conf, new InetSocketAddress[] { initialIsa
}); });
} }
@ -327,16 +354,6 @@ public class HFileOutputFormat2
this.previousRows.put(family, rowKey); this.previousRows.put(family, rowKey);
} }
private Path getTableRelativePath(byte[] tableNameBytes) {
String tableName = Bytes.toString(tableNameBytes);
String[] tableNameParts = tableName.split(":");
Path tableRelPath = new Path(tableName.split(":")[0]);
if (tableNameParts.length > 1) {
tableRelPath = new Path(tableRelPath, tableName.split(":")[1]);
}
return tableRelPath;
}
private void rollWriters(WriterLength writerLength) throws IOException { private void rollWriters(WriterLength writerLength) throws IOException {
if (writerLength != null) { if (writerLength != null) {
closeWriter(writerLength); closeWriter(writerLength);
@ -349,27 +366,29 @@ public class HFileOutputFormat2
private void closeWriter(WriterLength wl) throws IOException { private void closeWriter(WriterLength wl) throws IOException {
if (wl.writer != null) { if (wl.writer != null) {
LOG.info("Writer=" + wl.writer.getPath() + LOG.info(
((wl.written == 0)? "": ", wrote=" + wl.written)); "Writer=" + wl.writer.getPath() + ((wl.written == 0)? "": ", wrote=" + wl.written));
close(wl.writer); close(wl.writer);
wl.writer = null;
} }
wl.writer = null;
wl.written = 0; wl.written = 0;
} }
/* /*
* Create a new StoreFile.Writer. * Create a new StoreFile.Writer.
* @param family
* @return A WriterLength, containing a new StoreFile.Writer. * @return A WriterLength, containing a new StoreFile.Writer.
* @throws IOException
*/ */
@edu.umd.cs.findbugs.annotations.SuppressWarnings(value="BX_UNBOXING_IMMEDIATELY_REBOXED", @edu.umd.cs.findbugs.annotations.SuppressWarnings(value="BX_UNBOXING_IMMEDIATELY_REBOXED",
justification="Not important") justification="Not important")
private WriterLength getNewWriter(byte[] tableName, byte[] family, Configuration conf, private WriterLength getNewWriter(byte[] tableName, byte[] family, Configuration
InetSocketAddress[] favoredNodes) throws IOException { conf, InetSocketAddress[] favoredNodes) throws IOException {
byte[] tableAndFamily = getTableNameSuffixedWithFamily(tableName, family); byte[] tableAndFamily = getTableNameSuffixedWithFamily(tableName, family);
Path familydir = new Path(outputDir, Bytes.toString(family)); Path familydir = new Path(outputDir, Bytes.toString(family));
if (writeMultipleTables) { if (writeMultipleTables) {
familydir = new Path(outputDir, familydir = new Path(outputDir,
new Path(getTableRelativePath(tableName), Bytes.toString(family))); new Path(Bytes.toString(tableName), Bytes.toString(family)));
} }
WriterLength wl = new WriterLength(); WriterLength wl = new WriterLength();
Algorithm compression = overriddenCompression; Algorithm compression = overriddenCompression;
@ -387,9 +406,12 @@ public class HFileOutputFormat2
encoding = encoding == null ? datablockEncodingMap.get(tableAndFamily) : encoding; encoding = encoding == null ? datablockEncodingMap.get(tableAndFamily) : encoding;
encoding = encoding == null ? DataBlockEncoding.NONE : encoding; encoding = encoding == null ? DataBlockEncoding.NONE : encoding;
HFileContextBuilder contextBuilder = new HFileContextBuilder() HFileContextBuilder contextBuilder = new HFileContextBuilder()
.withCompression(compression).withChecksumType(HStore.getChecksumType(conf)) .withCompression(compression)
.withBytesPerCheckSum(HStore.getBytesPerChecksum(conf)).withBlockSize(blockSize) .withChecksumType(HStore.getChecksumType(conf))
.withColumnFamily(family).withTableName(tableName); .withBytesPerCheckSum(HStore.getBytesPerChecksum(conf))
.withBlockSize(blockSize)
.withColumnFamily(family)
.withTableName(tableName);
if (HFile.getFormatVersion(conf) >= HFile.MIN_FORMAT_VERSION_WITH_TAGS) { if (HFile.getFormatVersion(conf) >= HFile.MIN_FORMAT_VERSION_WITH_TAGS) {
contextBuilder.withIncludesTags(true); contextBuilder.withIncludesTags(true);
@ -398,13 +420,16 @@ public class HFileOutputFormat2
contextBuilder.withDataBlockEncoding(encoding); contextBuilder.withDataBlockEncoding(encoding);
HFileContext hFileContext = contextBuilder.build(); HFileContext hFileContext = contextBuilder.build();
if (null == favoredNodes) { if (null == favoredNodes) {
wl.writer = new StoreFileWriter.Builder(conf, CacheConfig.DISABLED, fs) wl.writer =
.withOutputDir(familydir).withBloomType(bloomType) new StoreFileWriter.Builder(conf, CacheConfig.DISABLED, fs)
.withFileContext(hFileContext).build(); .withOutputDir(familydir).withBloomType(bloomType)
.withComparator(CellComparator.getInstance()).withFileContext(hFileContext).build();
} else { } else {
wl.writer = new StoreFileWriter.Builder(conf, CacheConfig.DISABLED, new HFileSystem(fs)) wl.writer =
.withOutputDir(familydir).withBloomType(bloomType) new StoreFileWriter.Builder(conf, CacheConfig.DISABLED, new HFileSystem(fs))
.withFileContext(hFileContext).withFavoredNodes(favoredNodes).build(); .withOutputDir(familydir).withBloomType(bloomType)
.withComparator(CellComparator.getInstance()).withFileContext(hFileContext)
.withFavoredNodes(favoredNodes).build();
} }
this.writers.put(tableAndFamily, wl); this.writers.put(tableAndFamily, wl);
@ -413,17 +438,22 @@ public class HFileOutputFormat2
private void close(final StoreFileWriter w) throws IOException { private void close(final StoreFileWriter w) throws IOException {
if (w != null) { if (w != null) {
w.appendFileInfo(BULKLOAD_TIME_KEY, Bytes.toBytes(System.currentTimeMillis())); w.appendFileInfo(BULKLOAD_TIME_KEY,
w.appendFileInfo(BULKLOAD_TASK_KEY, Bytes.toBytes(context.getTaskAttemptID().toString())); Bytes.toBytes(System.currentTimeMillis()));
w.appendFileInfo(MAJOR_COMPACTION_KEY, Bytes.toBytes(true)); w.appendFileInfo(BULKLOAD_TASK_KEY,
w.appendFileInfo(EXCLUDE_FROM_MINOR_COMPACTION_KEY, Bytes.toBytes(compactionExclude)); Bytes.toBytes(context.getTaskAttemptID().toString()));
w.appendFileInfo(MAJOR_COMPACTION_KEY,
Bytes.toBytes(true));
w.appendFileInfo(EXCLUDE_FROM_MINOR_COMPACTION_KEY,
Bytes.toBytes(compactionExclude));
w.appendTrackedTimestampsToMetadata(); w.appendTrackedTimestampsToMetadata();
w.close(); w.close();
} }
} }
@Override @Override
public void close(TaskAttemptContext c) throws IOException, InterruptedException { public void close(TaskAttemptContext c)
throws IOException, InterruptedException {
for (WriterLength wl: this.writers.values()) { for (WriterLength wl: this.writers.values()) {
close(wl.writer); close(wl.writer);
} }
@ -463,18 +493,21 @@ public class HFileOutputFormat2
throws IOException { throws IOException {
ArrayList<ImmutableBytesWritable> ret = new ArrayList<>(); ArrayList<ImmutableBytesWritable> ret = new ArrayList<>();
for(RegionLocator regionLocator : regionLocators) { for(RegionLocator regionLocator : regionLocators)
{
TableName tableName = regionLocator.getName(); TableName tableName = regionLocator.getName();
LOG.info("Looking up current regions for table " + tableName); LOG.info("Looking up current regions for table " + tableName);
byte[][] byteKeys = regionLocator.getStartKeys(); byte[][] byteKeys = regionLocator.getStartKeys();
for (byte[] byteKey : byteKeys) { for (byte[] byteKey : byteKeys) {
byte[] fullKey = byteKey; //HFileOutputFormat2 use case byte[] fullKey = byteKey; //HFileOutputFormat2 use case
if (writeMultipleTables) { if (writeMultipleTables)
{
//MultiTableHFileOutputFormat use case //MultiTableHFileOutputFormat use case
fullKey = combineTableNameSuffix(tableName.getName(), byteKey); fullKey = combineTableNameSuffix(tableName.getName(), byteKey);
} }
if (LOG.isDebugEnabled()) { if (LOG.isDebugEnabled()) {
LOG.debug("SplitPoint startkey for " + tableName + ": " + Bytes.toStringBinary(fullKey)); LOG.debug("SplitPoint startkey for table [" + tableName + "]: [" + Bytes.toStringBinary
(fullKey) + "]");
} }
ret.add(new ImmutableBytesWritable(fullKey)); ret.add(new ImmutableBytesWritable(fullKey));
} }
@ -501,8 +534,8 @@ public class HFileOutputFormat2
TreeSet<ImmutableBytesWritable> sorted = new TreeSet<>(startKeys); TreeSet<ImmutableBytesWritable> sorted = new TreeSet<>(startKeys);
ImmutableBytesWritable first = sorted.first(); ImmutableBytesWritable first = sorted.first();
if (writeMultipleTables) { if (writeMultipleTables) {
first = first = new ImmutableBytesWritable(MultiTableHFileOutputFormat.getSuffix(sorted.first
new ImmutableBytesWritable(MultiTableHFileOutputFormat.getSuffix(sorted.first().get())); ().get()));
} }
if (!first.equals(HConstants.EMPTY_BYTE_ARRAY)) { if (!first.equals(HConstants.EMPTY_BYTE_ARRAY)) {
throw new IllegalArgumentException( throw new IllegalArgumentException(
@ -605,20 +638,19 @@ public class HFileOutputFormat2
/* Now get the region start keys for every table required */ /* Now get the region start keys for every table required */
List<String> allTableNames = new ArrayList<>(multiTableInfo.size()); List<String> allTableNames = new ArrayList<>(multiTableInfo.size());
List<RegionLocator> regionLocators = new ArrayList<>(multiTableInfo.size()); List<RegionLocator> regionLocators = new ArrayList<>( multiTableInfo.size());
List<TableDescriptor> tableDescriptors = new ArrayList<>(multiTableInfo.size()); List<TableDescriptor> tableDescriptors = new ArrayList<>( multiTableInfo.size());
for(TableInfo tableInfo : multiTableInfo) { for( TableInfo tableInfo : multiTableInfo )
{
regionLocators.add(tableInfo.getRegionLocator()); regionLocators.add(tableInfo.getRegionLocator());
allTableNames.add(tableInfo.getRegionLocator().getName().getNameAsString()); allTableNames.add(tableInfo.getRegionLocator().getName().getNameAsString());
tableDescriptors.add(tableInfo.getTableDescriptor()); tableDescriptors.add(tableInfo.getTableDescriptor());
} }
// Record tablenames for creating writer by favored nodes, and decoding compression, // Record tablenames for creating writer by favored nodes, and decoding compression, block size and other attributes of columnfamily per table
// block size and other attributes of columnfamily per table
conf.set(OUTPUT_TABLE_NAME_CONF_KEY, StringUtils.join(allTableNames, Bytes conf.set(OUTPUT_TABLE_NAME_CONF_KEY, StringUtils.join(allTableNames, Bytes
.toString(tableSeparator))); .toString(tableSeparator)));
List<ImmutableBytesWritable> startKeys = List<ImmutableBytesWritable> startKeys = getRegionStartKeys(regionLocators, writeMultipleTables);
getRegionStartKeys(regionLocators, writeMultipleTables);
// Use table's region boundaries for TOP split points. // Use table's region boundaries for TOP split points.
LOG.info("Configuring " + startKeys.size() + " reduce partitions " + LOG.info("Configuring " + startKeys.size() + " reduce partitions " +
"to match current region count for all tables"); "to match current region count for all tables");
@ -814,11 +846,9 @@ public class HFileOutputFormat2
TotalOrderPartitioner.setPartitionFile(conf, partitionsPath); TotalOrderPartitioner.setPartitionFile(conf, partitionsPath);
} }
@edu.umd.cs.findbugs.annotations.SuppressWarnings(value = @edu.umd.cs.findbugs.annotations.SuppressWarnings(value = "RCN_REDUNDANT_NULLCHECK_OF_NONNULL_VALUE")
"RCN_REDUNDANT_NULLCHECK_OF_NONNULL_VALUE")
@VisibleForTesting @VisibleForTesting
static String serializeColumnFamilyAttribute(Function<ColumnFamilyDescriptor, String> fn, static String serializeColumnFamilyAttribute(Function<ColumnFamilyDescriptor, String> fn, List<TableDescriptor> allTables)
List<TableDescriptor> allTables)
throws UnsupportedEncodingException { throws UnsupportedEncodingException {
StringBuilder attributeValue = new StringBuilder(); StringBuilder attributeValue = new StringBuilder();
int i = 0; int i = 0;
@ -833,8 +863,8 @@ public class HFileOutputFormat2
attributeValue.append('&'); attributeValue.append('&');
} }
attributeValue.append(URLEncoder.encode( attributeValue.append(URLEncoder.encode(
Bytes.toString(combineTableNameSuffix(tableDescriptor.getTableName().getName(), Bytes.toString(combineTableNameSuffix(tableDescriptor.getTableName().getName(), familyDescriptor.getName())),
familyDescriptor.getName())), "UTF-8")); "UTF-8"));
attributeValue.append('='); attributeValue.append('=');
attributeValue.append(URLEncoder.encode(fn.apply(familyDescriptor), "UTF-8")); attributeValue.append(URLEncoder.encode(fn.apply(familyDescriptor), "UTF-8"));
} }

View File

@ -26,25 +26,27 @@ import java.io.DataInputStream;
import java.io.DataOutputStream; import java.io.DataOutputStream;
import java.io.IOException; import java.io.IOException;
import java.nio.ByteBuffer; import java.nio.ByteBuffer;
import org.apache.hadoop.fs.FSDataInputStream; import org.apache.hadoop.fs.FSDataInputStream;
import org.apache.hadoop.hbase.CellComparator; import org.apache.hadoop.hbase.CellComparator;
import org.apache.hadoop.hbase.CellComparatorImpl; import org.apache.hadoop.hbase.CellComparatorImpl;
import org.apache.hadoop.hbase.CellComparatorImpl.MetaCellComparator; import org.apache.hadoop.hbase.CellComparatorImpl.MetaCellComparator;
import org.apache.hadoop.hbase.KeyValue; import org.apache.hadoop.hbase.KeyValue;
import org.apache.hadoop.hbase.io.compress.Compression;
import org.apache.hadoop.hbase.util.Bytes;
import org.apache.yetus.audience.InterfaceAudience; import org.apache.yetus.audience.InterfaceAudience;
import org.slf4j.Logger; import org.apache.hadoop.hbase.io.compress.Compression;
import org.slf4j.LoggerFactory;
import org.apache.hbase.thirdparty.com.google.protobuf.UnsafeByteOperations; import org.apache.hbase.thirdparty.com.google.protobuf.UnsafeByteOperations;
import org.apache.hadoop.hbase.shaded.protobuf.generated.HFileProtos; import org.apache.hadoop.hbase.shaded.protobuf.generated.HFileProtos;
import org.apache.hadoop.hbase.util.Bytes;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/** /**
* The {@link HFile} has a fixed trailer which contains offsets to other * The {@link HFile} has a fixed trailer which contains offsets to other
* variable parts of the file. Also includes basic metadata on this file. The * variable parts of the file. Also includes basic metadata on this file. The
* trailer size is fixed within a given {@link HFile} format version only, but * trailer size is fixed within a given {@link HFile} format version only, but
* we always store the version number as the last four-byte integer of the file. * we always store the version number as the last four-byte integer of the file.
* The version number itself is split into two portions, a major * The version number itself is split into two portions, a major
* version and a minor version. The last three bytes of a file are the major * version and a minor version. The last three bytes of a file are the major
* version and a single preceding byte is the minor number. The major version * version and a single preceding byte is the minor number. The major version
* determines which readers/writers to use to read/write a hfile while a minor * determines which readers/writers to use to read/write a hfile while a minor
@ -75,24 +77,16 @@ public class FixedFileTrailer {
*/ */
private long loadOnOpenDataOffset; private long loadOnOpenDataOffset;
/** /** The number of entries in the root data index. */
* The number of entries in the root data index.
*/
private int dataIndexCount; private int dataIndexCount;
/** /** Total uncompressed size of all blocks of the data index */
* Total uncompressed size of all blocks of the data index
*/
private long uncompressedDataIndexSize; private long uncompressedDataIndexSize;
/** /** The number of entries in the meta index */
* The number of entries in the meta index
*/
private int metaIndexCount; private int metaIndexCount;
/** /** The total uncompressed size of keys/values stored in the file. */
* The total uncompressed size of keys/values stored in the file.
*/
private long totalUncompressedBytes; private long totalUncompressedBytes;
/** /**
@ -101,9 +95,7 @@ public class FixedFileTrailer {
*/ */
private long entryCount; private long entryCount;
/** /** The compression codec used for all blocks. */
* The compression codec used for all blocks.
*/
private Compression.Algorithm compressionCodec = Compression.Algorithm.NONE; private Compression.Algorithm compressionCodec = Compression.Algorithm.NONE;
/** /**
@ -112,9 +104,7 @@ public class FixedFileTrailer {
*/ */
private int numDataIndexLevels; private int numDataIndexLevels;
/** /** The offset of the first data block. */
* The offset of the first data block.
*/
private long firstDataBlockOffset; private long firstDataBlockOffset;
/** /**
@ -123,25 +113,17 @@ public class FixedFileTrailer {
*/ */
private long lastDataBlockOffset; private long lastDataBlockOffset;
/** /** Raw key comparator class name in version 3 */
* Raw key comparator class name in version 3
*/
// We could write the actual class name from 2.0 onwards and handle BC // We could write the actual class name from 2.0 onwards and handle BC
private String comparatorClassName = CellComparator.getInstance().getClass().getName(); private String comparatorClassName = CellComparator.getInstance().getClass().getName();
/** /** The encryption key */
* The encryption key
*/
private byte[] encryptionKey; private byte[] encryptionKey;
/** /** The {@link HFile} format major version. */
* The {@link HFile} format major version.
*/
private final int majorVersion; private final int majorVersion;
/** /** The {@link HFile} format minor version. */
* The {@link HFile} format minor version.
*/
private final int minorVersion; private final int minorVersion;
FixedFileTrailer(int majorVersion, int minorVersion) { FixedFileTrailer(int majorVersion, int minorVersion) {
@ -151,7 +133,7 @@ public class FixedFileTrailer {
} }
private static int[] computeTrailerSizeByVersion() { private static int[] computeTrailerSizeByVersion() {
int[] versionToSize = new int[HFile.MAX_FORMAT_VERSION + 1]; int versionToSize[] = new int[HFile.MAX_FORMAT_VERSION + 1];
// We support only 2 major versions now. ie. V2, V3 // We support only 2 major versions now. ie. V2, V3
versionToSize[2] = 212; versionToSize[2] = 212;
for (int version = 3; version <= HFile.MAX_FORMAT_VERSION; version++) { for (int version = 3; version <= HFile.MAX_FORMAT_VERSION; version++) {
@ -165,13 +147,14 @@ public class FixedFileTrailer {
private static int getMaxTrailerSize() { private static int getMaxTrailerSize() {
int maxSize = 0; int maxSize = 0;
for (int version = HFile.MIN_FORMAT_VERSION; version <= HFile.MAX_FORMAT_VERSION; ++version) { for (int version = HFile.MIN_FORMAT_VERSION;
version <= HFile.MAX_FORMAT_VERSION;
++version)
maxSize = Math.max(getTrailerSize(version), maxSize); maxSize = Math.max(getTrailerSize(version), maxSize);
}
return maxSize; return maxSize;
} }
private static final int[] TRAILER_SIZE = computeTrailerSizeByVersion(); private static final int TRAILER_SIZE[] = computeTrailerSizeByVersion();
private static final int MAX_TRAILER_SIZE = getMaxTrailerSize(); private static final int MAX_TRAILER_SIZE = getMaxTrailerSize();
private static final int NOT_PB_SIZE = BlockType.MAGIC_LENGTH + Bytes.SIZEOF_INT; private static final int NOT_PB_SIZE = BlockType.MAGIC_LENGTH + Bytes.SIZEOF_INT;
@ -188,6 +171,9 @@ public class FixedFileTrailer {
* Write the trailer to a data stream. We support writing version 1 for * Write the trailer to a data stream. We support writing version 1 for
* testing and for determining version 1 trailer size. It is also easy to see * testing and for determining version 1 trailer size. It is also easy to see
* what fields changed in version 2. * what fields changed in version 2.
*
* @param outputStream
* @throws IOException
*/ */
void serialize(DataOutputStream outputStream) throws IOException { void serialize(DataOutputStream outputStream) throws IOException {
HFile.checkFormatVersion(majorVersion); HFile.checkFormatVersion(majorVersion);
@ -207,18 +193,18 @@ public class FixedFileTrailer {
@org.apache.hbase.thirdparty.com.google.common.annotations.VisibleForTesting @org.apache.hbase.thirdparty.com.google.common.annotations.VisibleForTesting
HFileProtos.FileTrailerProto toProtobuf() { HFileProtos.FileTrailerProto toProtobuf() {
HFileProtos.FileTrailerProto.Builder builder = HFileProtos.FileTrailerProto.newBuilder() HFileProtos.FileTrailerProto.Builder builder = HFileProtos.FileTrailerProto.newBuilder()
.setFileInfoOffset(fileInfoOffset) .setFileInfoOffset(fileInfoOffset)
.setLoadOnOpenDataOffset(loadOnOpenDataOffset) .setLoadOnOpenDataOffset(loadOnOpenDataOffset)
.setUncompressedDataIndexSize(uncompressedDataIndexSize) .setUncompressedDataIndexSize(uncompressedDataIndexSize)
.setTotalUncompressedBytes(totalUncompressedBytes) .setTotalUncompressedBytes(totalUncompressedBytes)
.setDataIndexCount(dataIndexCount) .setDataIndexCount(dataIndexCount)
.setMetaIndexCount(metaIndexCount) .setMetaIndexCount(metaIndexCount)
.setEntryCount(entryCount) .setEntryCount(entryCount)
.setNumDataIndexLevels(numDataIndexLevels) .setNumDataIndexLevels(numDataIndexLevels)
.setFirstDataBlockOffset(firstDataBlockOffset) .setFirstDataBlockOffset(firstDataBlockOffset)
.setLastDataBlockOffset(lastDataBlockOffset) .setLastDataBlockOffset(lastDataBlockOffset)
.setComparatorClassName(getHBase1CompatibleName(comparatorClassName)) .setComparatorClassName(getHBase1CompatibleName(comparatorClassName))
.setCompressionCodec(compressionCodec.ordinal()); .setCompressionCodec(compressionCodec.ordinal());
if (encryptionKey != null) { if (encryptionKey != null) {
builder.setEncryptionKey(UnsafeByteOperations.unsafeWrap(encryptionKey)); builder.setEncryptionKey(UnsafeByteOperations.unsafeWrap(encryptionKey));
} }
@ -253,6 +239,9 @@ public class FixedFileTrailer {
* Deserialize the fixed file trailer from the given stream. The version needs * Deserialize the fixed file trailer from the given stream. The version needs
* to already be specified. Make sure this is consistent with * to already be specified. Make sure this is consistent with
* {@link #serialize(DataOutputStream)}. * {@link #serialize(DataOutputStream)}.
*
* @param inputStream
* @throws IOException
*/ */
void deserialize(DataInputStream inputStream) throws IOException { void deserialize(DataInputStream inputStream) throws IOException {
HFile.checkFormatVersion(majorVersion); HFile.checkFormatVersion(majorVersion);
@ -260,7 +249,7 @@ public class FixedFileTrailer {
BlockType.TRAILER.readAndCheck(inputStream); BlockType.TRAILER.readAndCheck(inputStream);
if (majorVersion > 2 if (majorVersion > 2
|| (majorVersion == 2 && minorVersion >= HFileReaderImpl.PBUF_TRAILER_MINOR_VERSION)) { || (majorVersion == 2 && minorVersion >= HFileReaderImpl.PBUF_TRAILER_MINOR_VERSION)) {
deserializeFromPB(inputStream); deserializeFromPB(inputStream);
} else { } else {
deserializeFromWritable(inputStream); deserializeFromWritable(inputStream);
@ -274,12 +263,14 @@ public class FixedFileTrailer {
/** /**
* Deserialize the file trailer as protobuf * Deserialize the file trailer as protobuf
* @param inputStream
* @throws IOException
*/ */
void deserializeFromPB(DataInputStream inputStream) throws IOException { void deserializeFromPB(DataInputStream inputStream) throws IOException {
// read PB and skip padding // read PB and skip padding
int start = inputStream.available(); int start = inputStream.available();
HFileProtos.FileTrailerProto trailerProto = HFileProtos.FileTrailerProto trailerProto =
HFileProtos.FileTrailerProto.PARSER.parseDelimitedFrom(inputStream); HFileProtos.FileTrailerProto.PARSER.parseDelimitedFrom(inputStream);
int size = start - inputStream.available(); int size = start - inputStream.available();
inputStream.skip(getTrailerSize() - NOT_PB_SIZE - size); inputStream.skip(getTrailerSize() - NOT_PB_SIZE - size);
@ -329,6 +320,8 @@ public class FixedFileTrailer {
/** /**
* Deserialize the file trailer as writable data * Deserialize the file trailer as writable data
* @param input
* @throws IOException
*/ */
void deserializeFromWritable(DataInput input) throws IOException { void deserializeFromWritable(DataInput input) throws IOException {
fileInfoOffset = input.readLong(); fileInfoOffset = input.readLong();
@ -346,13 +339,12 @@ public class FixedFileTrailer {
// TODO this is a classname encoded into an HFile's trailer. We are going to need to have // TODO this is a classname encoded into an HFile's trailer. We are going to need to have
// some compat code here. // some compat code here.
setComparatorClass(getComparatorClass(Bytes.readStringFixedSize(input, setComparatorClass(getComparatorClass(Bytes.readStringFixedSize(input,
MAX_COMPARATOR_NAME_LENGTH))); MAX_COMPARATOR_NAME_LENGTH)));
} }
private void append(StringBuilder sb, String s) { private void append(StringBuilder sb, String s) {
if (sb.length() > 0) { if (sb.length() > 0)
sb.append(", "); sb.append(", ");
}
sb.append(s); sb.append(s);
} }
@ -383,18 +375,18 @@ public class FixedFileTrailer {
/** /**
* Reads a file trailer from the given file. * Reads a file trailer from the given file.
* *
* @param istream the input stream with the ability to seek. Does not have to * @param istream the input stream with the ability to seek. Does not have to
* be buffered, as only one read operation is made. * be buffered, as only one read operation is made.
* @param fileSize the file size. Can be obtained using * @param fileSize the file size. Can be obtained using
* {@link org.apache.hadoop.fs.FileSystem#getFileStatus( * {@link org.apache.hadoop.fs.FileSystem#getFileStatus(
*org.apache.hadoop.fs.Path)}. * org.apache.hadoop.fs.Path)}.
* @return the fixed file trailer read * @return the fixed file trailer read
* @throws IOException if failed to read from the underlying stream, or the * @throws IOException if failed to read from the underlying stream, or the
* trailer is corrupted, or the version of the trailer is * trailer is corrupted, or the version of the trailer is
* unsupported * unsupported
*/ */
public static FixedFileTrailer readFromStream(FSDataInputStream istream, public static FixedFileTrailer readFromStream(FSDataInputStream istream,
long fileSize) throws IOException { long fileSize) throws IOException {
int bufferSize = MAX_TRAILER_SIZE; int bufferSize = MAX_TRAILER_SIZE;
long seekPoint = fileSize - bufferSize; long seekPoint = fileSize - bufferSize;
if (seekPoint < 0) { if (seekPoint < 0) {
@ -407,7 +399,7 @@ public class FixedFileTrailer {
ByteBuffer buf = ByteBuffer.allocate(bufferSize); ByteBuffer buf = ByteBuffer.allocate(bufferSize);
istream.readFully(buf.array(), buf.arrayOffset(), istream.readFully(buf.array(), buf.arrayOffset(),
buf.arrayOffset() + buf.limit()); buf.arrayOffset() + buf.limit());
// Read the version from the last int of the file. // Read the version from the last int of the file.
buf.position(buf.limit() - Bytes.SIZEOF_INT); buf.position(buf.limit() - Bytes.SIZEOF_INT);
@ -423,30 +415,30 @@ public class FixedFileTrailer {
FixedFileTrailer fft = new FixedFileTrailer(majorVersion, minorVersion); FixedFileTrailer fft = new FixedFileTrailer(majorVersion, minorVersion);
fft.deserialize(new DataInputStream(new ByteArrayInputStream(buf.array(), fft.deserialize(new DataInputStream(new ByteArrayInputStream(buf.array(),
buf.arrayOffset() + bufferSize - trailerSize, trailerSize))); buf.arrayOffset() + bufferSize - trailerSize, trailerSize)));
return fft; return fft;
} }
public void expectMajorVersion(int expected) { public void expectMajorVersion(int expected) {
if (majorVersion != expected) { if (majorVersion != expected) {
throw new IllegalArgumentException("Invalid HFile major version: " throw new IllegalArgumentException("Invalid HFile major version: "
+ majorVersion + majorVersion
+ " (expected: " + expected + ")"); + " (expected: " + expected + ")");
} }
} }
public void expectMinorVersion(int expected) { public void expectMinorVersion(int expected) {
if (minorVersion != expected) { if (minorVersion != expected) {
throw new IllegalArgumentException("Invalid HFile minor version: " throw new IllegalArgumentException("Invalid HFile minor version: "
+ minorVersion + " (expected: " + expected + ")"); + minorVersion + " (expected: " + expected + ")");
} }
} }
public void expectAtLeastMajorVersion(int lowerBound) { public void expectAtLeastMajorVersion(int lowerBound) {
if (majorVersion < lowerBound) { if (majorVersion < lowerBound) {
throw new IllegalArgumentException("Invalid HFile major version: " throw new IllegalArgumentException("Invalid HFile major version: "
+ majorVersion + majorVersion
+ " (expected: " + lowerBound + " or higher)."); + " (expected: " + lowerBound + " or higher).");
} }
} }
@ -574,7 +566,7 @@ public class FixedFileTrailer {
* than the new name; writing the new name will make it so newly-written hfiles are not parseable * than the new name; writing the new name will make it so newly-written hfiles are not parseable
* by hbase-1.x, a facility we'd like to preserve across rolling upgrade and hbase-1.x clusters * by hbase-1.x, a facility we'd like to preserve across rolling upgrade and hbase-1.x clusters
* reading hbase-2.x produce. * reading hbase-2.x produce.
* <p> *
* The Comparators in hbase-2.x work the same as they did in hbase-1.x; they compare * The Comparators in hbase-2.x work the same as they did in hbase-1.x; they compare
* KeyValues. In hbase-2.x they were renamed making use of the more generic 'Cell' * KeyValues. In hbase-2.x they were renamed making use of the more generic 'Cell'
* nomenclature to indicate that we intend to move away from KeyValues post hbase-2. A naming * nomenclature to indicate that we intend to move away from KeyValues post hbase-2. A naming
@ -587,9 +579,9 @@ public class FixedFileTrailer {
* *
* @param comparator String class name of the Comparator used in this hfile. * @param comparator String class name of the Comparator used in this hfile.
* @return What to store in the trailer as our comparator name. * @return What to store in the trailer as our comparator name.
* @see #getComparatorClass(String)
* @since hbase-2.0.0. * @since hbase-2.0.0.
* @deprecated Since hbase-2.0.0. Will be removed in hbase-3.0.0. * @deprecated Since hbase-2.0.0. Will be removed in hbase-3.0.0.
* @see #getComparatorClass(String)
*/ */
@Deprecated @Deprecated
private String getHBase1CompatibleName(final String comparator) { private String getHBase1CompatibleName(final String comparator) {
@ -604,20 +596,20 @@ public class FixedFileTrailer {
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
private static Class<? extends CellComparator> getComparatorClass(String comparatorClassName) private static Class<? extends CellComparator> getComparatorClass(String comparatorClassName)
throws IOException { throws IOException {
Class<? extends CellComparator> comparatorKlass; Class<? extends CellComparator> comparatorKlass;
// for BC // for BC
if (comparatorClassName.equals(KeyValue.COMPARATOR.getLegacyKeyComparatorName()) if (comparatorClassName.equals(KeyValue.COMPARATOR.getLegacyKeyComparatorName())
|| comparatorClassName.equals(KeyValue.COMPARATOR.getClass().getName()) || comparatorClassName.equals(KeyValue.COMPARATOR.getClass().getName())
|| (comparatorClassName.equals("org.apache.hadoop.hbase.CellComparator"))) { || (comparatorClassName.equals("org.apache.hadoop.hbase.CellComparator"))) {
comparatorKlass = CellComparatorImpl.class; comparatorKlass = CellComparatorImpl.class;
} else if (comparatorClassName.equals(KeyValue.META_COMPARATOR.getLegacyKeyComparatorName()) } else if (comparatorClassName.equals(KeyValue.META_COMPARATOR.getLegacyKeyComparatorName())
|| comparatorClassName.equals(KeyValue.META_COMPARATOR.getClass().getName()) || comparatorClassName.equals(KeyValue.META_COMPARATOR.getClass().getName())
|| (comparatorClassName || (comparatorClassName
.equals("org.apache.hadoop.hbase.CellComparator$MetaCellComparator"))) { .equals("org.apache.hadoop.hbase.CellComparator$MetaCellComparator"))) {
comparatorKlass = MetaCellComparator.class; comparatorKlass = MetaCellComparator.class;
} else if (comparatorClassName.equals("org.apache.hadoop.hbase.KeyValue$RawBytesComparator") } else if (comparatorClassName.equals("org.apache.hadoop.hbase.KeyValue$RawBytesComparator")
|| comparatorClassName.equals("org.apache.hadoop.hbase.util.Bytes$ByteArrayComparator")) { || comparatorClassName.equals("org.apache.hadoop.hbase.util.Bytes$ByteArrayComparator")) {
// When the comparator to be used is Bytes.BYTES_RAWCOMPARATOR, we just return null from here // When the comparator to be used is Bytes.BYTES_RAWCOMPARATOR, we just return null from here
// Bytes.BYTES_RAWCOMPARATOR is not a CellComparator // Bytes.BYTES_RAWCOMPARATOR is not a CellComparator
comparatorKlass = null; comparatorKlass = null;
@ -632,22 +624,19 @@ public class FixedFileTrailer {
return comparatorKlass; return comparatorKlass;
} }
static CellComparator createComparator(String comparatorClassName) throws IOException { public static CellComparator createComparator(
if (comparatorClassName.equals(CellComparatorImpl.COMPARATOR.getClass().getName())) { String comparatorClassName) throws IOException {
return CellComparatorImpl.COMPARATOR;
} else if (comparatorClassName.equals(
CellComparatorImpl.META_COMPARATOR.getClass().getName())) {
return CellComparatorImpl.META_COMPARATOR;
}
try { try {
Class<? extends CellComparator> comparatorClass = getComparatorClass(comparatorClassName); Class<? extends CellComparator> comparatorClass = getComparatorClass(comparatorClassName);
if (comparatorClass != null) { if(comparatorClass != null){
return comparatorClass.getDeclaredConstructor().newInstance(); return comparatorClass.getDeclaredConstructor().newInstance();
} }
LOG.warn("No Comparator class for " + comparatorClassName + ". Returning Null."); LOG.warn("No Comparator class for " + comparatorClassName + ". Returning Null.");
return null; return null;
} catch (Exception e) { } catch (Exception e) {
throw new IOException("Comparator class " + comparatorClassName + " is not instantiable", e); throw new IOException("Comparator class " + comparatorClassName +
" is not instantiable", e);
} }
} }
@ -661,7 +650,7 @@ public class FixedFileTrailer {
} }
public void setUncompressedDataIndexSize( public void setUncompressedDataIndexSize(
long uncompressedDataIndexSize) { long uncompressedDataIndexSize) {
expectAtLeastMajorVersion(2); expectAtLeastMajorVersion(2);
this.uncompressedDataIndexSize = uncompressedDataIndexSize; this.uncompressedDataIndexSize = uncompressedDataIndexSize;
} }

View File

@ -1,4 +1,4 @@
/* /**
* *
* Licensed to the Apache Software Foundation (ASF) under one * Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file * or more contributor license agreements. See the NOTICE file
@ -26,6 +26,7 @@ import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.Optional; import java.util.Optional;
import java.util.concurrent.atomic.LongAdder; import java.util.concurrent.atomic.LongAdder;
import org.apache.commons.io.IOUtils; import org.apache.commons.io.IOUtils;
import org.apache.hadoop.conf.Configuration; import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.FSDataOutputStream; import org.apache.hadoop.fs.FSDataOutputStream;
@ -51,6 +52,7 @@ import org.apache.hadoop.io.Writable;
import org.apache.yetus.audience.InterfaceAudience; import org.apache.yetus.audience.InterfaceAudience;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import org.apache.hbase.thirdparty.com.google.common.annotations.VisibleForTesting; import org.apache.hbase.thirdparty.com.google.common.annotations.VisibleForTesting;
import org.apache.hbase.thirdparty.com.google.common.base.Preconditions; import org.apache.hbase.thirdparty.com.google.common.base.Preconditions;
@ -119,7 +121,7 @@ import org.apache.hbase.thirdparty.com.google.common.base.Preconditions;
* an HFile instance? * an HFile instance?
*/ */
@InterfaceAudience.Private @InterfaceAudience.Private
public final class HFile { public class HFile {
// LOG is being used in HFileBlock and CheckSumUtil // LOG is being used in HFileBlock and CheckSumUtil
static final Logger LOG = LoggerFactory.getLogger(HFile.class); static final Logger LOG = LoggerFactory.getLogger(HFile.class);
@ -175,11 +177,6 @@ public final class HFile {
/** Static instance for the metrics so that HFileReaders access the same instance */ /** Static instance for the metrics so that HFileReaders access the same instance */
static final MetricsIO metrics = new MetricsIO(new MetricsIOWrapperImpl()); static final MetricsIO metrics = new MetricsIO(new MetricsIOWrapperImpl());
/**
* Shutdown constructor.
*/
private HFile() {}
/** /**
* Number of checksum verification failures. It also * Number of checksum verification failures. It also
* clears the counter. * clears the counter.
@ -225,11 +222,10 @@ public final class HFile {
*/ */
void addInlineBlockWriter(InlineBlockWriter bloomWriter); void addInlineBlockWriter(InlineBlockWriter bloomWriter);
// The below three methods take Writables. We'd like to undo Writables but undoing the below // The below three methods take Writables. We'd like to undo Writables but undoing the below would be pretty
// would be pretty painful. Could take a byte [] or a Message but we want to be backward // painful. Could take a byte [] or a Message but we want to be backward compatible around hfiles so would need
// compatible around hfiles so would need to map between Message and Writable or byte [] and // to map between Message and Writable or byte [] and current Writable serialization. This would be a bit of work
// current Writable serialization. This would be a bit of work to little gain. Thats my // to little gain. Thats my thinking at moment. St.Ack 20121129
// thinking at moment. St.Ack 20121129
void appendMetaBlock(String bloomFilterMetaKey, Writable metaWriter); void appendMetaBlock(String bloomFilterMetaKey, Writable metaWriter);
@ -262,6 +258,7 @@ public final class HFile {
protected FileSystem fs; protected FileSystem fs;
protected Path path; protected Path path;
protected FSDataOutputStream ostream; protected FSDataOutputStream ostream;
protected CellComparator comparator = CellComparator.getInstance();
protected InetSocketAddress[] favoredNodes; protected InetSocketAddress[] favoredNodes;
private HFileContext fileContext; private HFileContext fileContext;
protected boolean shouldDropBehind = false; protected boolean shouldDropBehind = false;
@ -285,6 +282,12 @@ public final class HFile {
return this; return this;
} }
public WriterFactory withComparator(CellComparator comparator) {
Preconditions.checkNotNull(comparator);
this.comparator = comparator;
return this;
}
public WriterFactory withFavoredNodes(InetSocketAddress[] favoredNodes) { public WriterFactory withFavoredNodes(InetSocketAddress[] favoredNodes) {
// Deliberately not checking for null here. // Deliberately not checking for null here.
this.favoredNodes = favoredNodes; this.favoredNodes = favoredNodes;
@ -316,7 +319,7 @@ public final class HFile {
LOG.debug("Unable to set drop behind on {}", path.getName()); LOG.debug("Unable to set drop behind on {}", path.getName());
} }
} }
return new HFileWriterImpl(conf, cacheConf, path, ostream, fileContext); return new HFileWriterImpl(conf, cacheConf, path, ostream, comparator, fileContext);
} }
} }
@ -346,16 +349,16 @@ public final class HFile {
CacheConfig cacheConf) { CacheConfig cacheConf) {
int version = getFormatVersion(conf); int version = getFormatVersion(conf);
switch (version) { switch (version) {
case 2: case 2:
throw new IllegalArgumentException("This should never happen. " + throw new IllegalArgumentException("This should never happen. " +
"Did you change hfile.format.version to read v2? This version of the software writes v3" + "Did you change hfile.format.version to read v2? This version of the software writes v3" +
" hfiles only (but it can read v2 files without having to update hfile.format.version " + " hfiles only (but it can read v2 files without having to update hfile.format.version " +
"in hbase-site.xml)"); "in hbase-site.xml)");
case 3: case 3:
return new HFile.WriterFactory(conf, cacheConf); return new HFile.WriterFactory(conf, cacheConf);
default: default:
throw new IllegalArgumentException("Cannot create writer for HFile " + throw new IllegalArgumentException("Cannot create writer for HFile " +
"format version " + version); "format version " + version);
} }
} }
@ -369,15 +372,18 @@ public final class HFile {
* Read in a file block. * Read in a file block.
* @param offset offset to read. * @param offset offset to read.
* @param onDiskBlockSize size of the block * @param onDiskBlockSize size of the block
* @param cacheBlock
* @param pread
* @param isCompaction is this block being read as part of a compaction * @param isCompaction is this block being read as part of a compaction
* @param expectedBlockType the block type we are expecting to read with this read operation, * @param expectedBlockType the block type we are expecting to read with this read operation,
* or null to read whatever block type is available and avoid checking (that might reduce * or null to read whatever block type is available and avoid checking (that might reduce
* caching efficiency of encoded data blocks) * caching efficiency of encoded data blocks)
* @param expectedDataBlockEncoding the data block encoding the caller is expecting data blocks * @param expectedDataBlockEncoding the data block encoding the caller is expecting data blocks
* to be in, or null to not perform this check and return the block irrespective of the * to be in, or null to not perform this check and return the block irrespective of the
* encoding. This check only applies to data blocks and can be set to null when the caller is * encoding. This check only applies to data blocks and can be set to null when the caller is
* expecting to read a non-data block and has set expectedBlockType accordingly. * expecting to read a non-data block and has set expectedBlockType accordingly.
* @return Block wrapped in a ByteBuffer. * @return Block wrapped in a ByteBuffer.
* @throws IOException
*/ */
HFileBlock readBlock(long offset, long onDiskBlockSize, HFileBlock readBlock(long offset, long onDiskBlockSize,
boolean cacheBlock, final boolean pread, final boolean isCompaction, boolean cacheBlock, final boolean pread, final boolean isCompaction,

View File

@ -18,6 +18,7 @@
package org.apache.hadoop.hbase.io.hfile; package org.apache.hadoop.hbase.io.hfile;
import static org.apache.hadoop.hbase.io.ByteBuffAllocator.HEAP; import static org.apache.hadoop.hbase.io.ByteBuffAllocator.HEAP;
import java.io.DataInputStream; import java.io.DataInputStream;
import java.io.DataOutput; import java.io.DataOutput;
import java.io.DataOutputStream; import java.io.DataOutputStream;
@ -28,13 +29,18 @@ import java.util.List;
import java.util.concurrent.atomic.AtomicReference; import java.util.concurrent.atomic.AtomicReference;
import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock; import java.util.concurrent.locks.ReentrantLock;
import org.apache.hadoop.fs.FSDataInputStream; import org.apache.hadoop.fs.FSDataInputStream;
import org.apache.hadoop.fs.FSDataOutputStream; import org.apache.hadoop.fs.FSDataOutputStream;
import org.apache.hadoop.hbase.Cell; import org.apache.hadoop.hbase.Cell;
import org.apache.hadoop.hbase.HConstants; import org.apache.hadoop.hbase.HConstants;
import org.apache.hadoop.hbase.io.ByteBuffAllocator;
import org.apache.hadoop.hbase.io.util.BlockIOUtils;
import org.apache.yetus.audience.InterfaceAudience;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.apache.hadoop.hbase.fs.HFileSystem; import org.apache.hadoop.hbase.fs.HFileSystem;
import org.apache.hadoop.hbase.io.ByteArrayOutputStream; import org.apache.hadoop.hbase.io.ByteArrayOutputStream;
import org.apache.hadoop.hbase.io.ByteBuffAllocator;
import org.apache.hadoop.hbase.io.ByteBuffInputStream; import org.apache.hadoop.hbase.io.ByteBuffInputStream;
import org.apache.hadoop.hbase.io.ByteBufferWriterDataOutputStream; import org.apache.hadoop.hbase.io.ByteBufferWriterDataOutputStream;
import org.apache.hadoop.hbase.io.FSDataInputStreamWrapper; import org.apache.hadoop.hbase.io.FSDataInputStreamWrapper;
@ -44,7 +50,6 @@ import org.apache.hadoop.hbase.io.encoding.HFileBlockDecodingContext;
import org.apache.hadoop.hbase.io.encoding.HFileBlockDefaultDecodingContext; import org.apache.hadoop.hbase.io.encoding.HFileBlockDefaultDecodingContext;
import org.apache.hadoop.hbase.io.encoding.HFileBlockDefaultEncodingContext; import org.apache.hadoop.hbase.io.encoding.HFileBlockDefaultEncodingContext;
import org.apache.hadoop.hbase.io.encoding.HFileBlockEncodingContext; import org.apache.hadoop.hbase.io.encoding.HFileBlockEncodingContext;
import org.apache.hadoop.hbase.io.util.BlockIOUtils;
import org.apache.hadoop.hbase.nio.ByteBuff; import org.apache.hadoop.hbase.nio.ByteBuff;
import org.apache.hadoop.hbase.nio.MultiByteBuff; import org.apache.hadoop.hbase.nio.MultiByteBuff;
import org.apache.hadoop.hbase.nio.SingleByteBuff; import org.apache.hadoop.hbase.nio.SingleByteBuff;
@ -52,9 +57,7 @@ import org.apache.hadoop.hbase.regionserver.ShipperListener;
import org.apache.hadoop.hbase.util.Bytes; import org.apache.hadoop.hbase.util.Bytes;
import org.apache.hadoop.hbase.util.ChecksumType; import org.apache.hadoop.hbase.util.ChecksumType;
import org.apache.hadoop.hbase.util.ClassSize; import org.apache.hadoop.hbase.util.ClassSize;
import org.apache.yetus.audience.InterfaceAudience;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.apache.hbase.thirdparty.com.google.common.annotations.VisibleForTesting; import org.apache.hbase.thirdparty.com.google.common.annotations.VisibleForTesting;
import org.apache.hbase.thirdparty.com.google.common.base.Preconditions; import org.apache.hbase.thirdparty.com.google.common.base.Preconditions;
@ -358,8 +361,8 @@ public class HFileBlock implements Cacheable {
final long prevBlockOffset = buf.getLong(Header.PREV_BLOCK_OFFSET_INDEX); final long prevBlockOffset = buf.getLong(Header.PREV_BLOCK_OFFSET_INDEX);
// This constructor is called when we deserialize a block from cache and when we read a block in // This constructor is called when we deserialize a block from cache and when we read a block in
// from the fs. fileCache is null when deserialized from cache so need to make up one. // from the fs. fileCache is null when deserialized from cache so need to make up one.
HFileContextBuilder fileContextBuilder = fileContext != null ? HFileContextBuilder fileContextBuilder =
new HFileContextBuilder(fileContext) : new HFileContextBuilder(); fileContext != null ? new HFileContextBuilder(fileContext) : new HFileContextBuilder();
fileContextBuilder.withHBaseCheckSum(usesHBaseChecksum); fileContextBuilder.withHBaseCheckSum(usesHBaseChecksum);
int onDiskDataSizeWithHeader; int onDiskDataSizeWithHeader;
if (usesHBaseChecksum) { if (usesHBaseChecksum) {
@ -405,8 +408,8 @@ public class HFileBlock implements Cacheable {
/** /**
* @return the on-disk size of the next block (including the header size and any checksums if * @return the on-disk size of the next block (including the header size and any checksums if
* present) read by peeking into the next block's header; use as a hint when doing * present) read by peeking into the next block's header; use as a hint when doing
* a read of the next block when scanning or running over a file. * a read of the next block when scanning or running over a file.
*/ */
int getNextBlockOnDiskSize() { int getNextBlockOnDiskSize() {
return nextBlockOnDiskSize; return nextBlockOnDiskSize;
@ -463,7 +466,7 @@ public class HFileBlock implements Cacheable {
/** /**
* @return the uncompressed size of data part (header and checksum excluded). * @return the uncompressed size of data part (header and checksum excluded).
*/ */
int getUncompressedSizeWithoutHeader() { int getUncompressedSizeWithoutHeader() {
return uncompressedSizeWithoutHeader; return uncompressedSizeWithoutHeader;
} }
@ -703,8 +706,8 @@ public class HFileBlock implements Cacheable {
} }
/** /**
* Cannot be {@link #UNSET}. Must be a legitimate value. Used re-making the {@link BlockCacheKey} * Cannot be {@link #UNSET}. Must be a legitimate value. Used re-making the {@link BlockCacheKey} when
* when block is returned to the cache. * block is returned to the cache.
* @return the offset of this block in the file it was read from * @return the offset of this block in the file it was read from
*/ */
long getOffset() { long getOffset() {
@ -890,6 +893,7 @@ public class HFileBlock implements Cacheable {
* Starts writing into the block. The previous block's data is discarded. * Starts writing into the block. The previous block's data is discarded.
* *
* @return the stream the user can write their data into * @return the stream the user can write their data into
* @throws IOException
*/ */
DataOutputStream startWriting(BlockType newBlockType) DataOutputStream startWriting(BlockType newBlockType)
throws IOException { throws IOException {
@ -919,6 +923,8 @@ public class HFileBlock implements Cacheable {
/** /**
* Writes the Cell to this block * Writes the Cell to this block
* @param cell
* @throws IOException
*/ */
void write(Cell cell) throws IOException{ void write(Cell cell) throws IOException{
expectState(State.WRITING); expectState(State.WRITING);
@ -1036,6 +1042,9 @@ public class HFileBlock implements Cacheable {
* Similar to {@link #writeHeaderAndData(FSDataOutputStream)}, but records * Similar to {@link #writeHeaderAndData(FSDataOutputStream)}, but records
* the offset of this block so that it can be referenced in the next block * the offset of this block so that it can be referenced in the next block
* of the same type. * of the same type.
*
* @param out
* @throws IOException
*/ */
void writeHeaderAndData(FSDataOutputStream out) throws IOException { void writeHeaderAndData(FSDataOutputStream out) throws IOException {
long offset = out.getPos(); long offset = out.getPos();
@ -1053,7 +1062,9 @@ public class HFileBlock implements Cacheable {
* data when not using compression) into the given stream. Can be called in * data when not using compression) into the given stream. Can be called in
* the "writing" state or in the "block ready" state. If called in the * the "writing" state or in the "block ready" state. If called in the
* "writing" state, transitions the writer to the "block ready" state. * "writing" state, transitions the writer to the "block ready" state.
*
* @param out the output stream to write the * @param out the output stream to write the
* @throws IOException
*/ */
protected void finishBlockAndWriteHeaderAndData(DataOutputStream out) protected void finishBlockAndWriteHeaderAndData(DataOutputStream out)
throws IOException { throws IOException {
@ -1072,6 +1083,7 @@ public class HFileBlock implements Cacheable {
* the header + data + checksums stored on disk. * the header + data + checksums stored on disk.
* *
* @return header and data as they would be stored on disk in a byte array * @return header and data as they would be stored on disk in a byte array
* @throws IOException
*/ */
byte[] getHeaderAndDataForTest() throws IOException { byte[] getHeaderAndDataForTest() throws IOException {
ensureBlockReady(); ensureBlockReady();
@ -1156,7 +1168,9 @@ public class HFileBlock implements Cacheable {
* @return the number of bytes written * @return the number of bytes written
*/ */
public int encodedBlockSizeWritten() { public int encodedBlockSizeWritten() {
return state != State.WRITING ? 0 : this.encodedDataSizeWritten; if (state != State.WRITING)
return 0;
return this.encodedDataSizeWritten;
} }
/** /**
@ -1167,7 +1181,8 @@ public class HFileBlock implements Cacheable {
* @return the number of bytes written * @return the number of bytes written
*/ */
int blockSizeWritten() { int blockSizeWritten() {
return state != State.WRITING ? 0 : this.unencodedDataSizeWritten; if (state != State.WRITING) return 0;
return this.unencodedDataSizeWritten;
} }
/** /**
@ -1220,6 +1235,7 @@ public class HFileBlock implements Cacheable {
* *
* @param bw the block-writable object to write as a block * @param bw the block-writable object to write as a block
* @param out the file system output stream * @param out the file system output stream
* @throws IOException
*/ */
void writeBlock(BlockWritable bw, FSDataOutputStream out) void writeBlock(BlockWritable bw, FSDataOutputStream out)
throws IOException { throws IOException {
@ -1416,8 +1432,7 @@ public class HFileBlock implements Cacheable {
* next blocks header seems unnecessary given we usually get the block size * next blocks header seems unnecessary given we usually get the block size
* from the hfile index. Review! * from the hfile index. Review!
*/ */
private AtomicReference<PrefetchedHeader> prefetchedHeader = private AtomicReference<PrefetchedHeader> prefetchedHeader = new AtomicReference<>(new PrefetchedHeader());
new AtomicReference<>(new PrefetchedHeader());
/** The size of the file we are reading from, or -1 if unknown. */ /** The size of the file we are reading from, or -1 if unknown. */
private long fileSize; private long fileSize;
@ -1629,9 +1644,10 @@ public class HFileBlock implements Cacheable {
/** /**
* @return Check <code>onDiskSizeWithHeaderL</code> size is healthy and then return it as an int * @return Check <code>onDiskSizeWithHeaderL</code> size is healthy and then return it as an int
* @throws IOException
*/ */
private static int checkAndGetSizeAsInt(final long onDiskSizeWithHeaderL, final int hdrSize) private static int checkAndGetSizeAsInt(final long onDiskSizeWithHeaderL, final int hdrSize)
throws IOException { throws IOException {
if ((onDiskSizeWithHeaderL < hdrSize && onDiskSizeWithHeaderL != -1) if ((onDiskSizeWithHeaderL < hdrSize && onDiskSizeWithHeaderL != -1)
|| onDiskSizeWithHeaderL >= Integer.MAX_VALUE) { || onDiskSizeWithHeaderL >= Integer.MAX_VALUE) {
throw new IOException("Invalid onDisksize=" + onDiskSizeWithHeaderL throw new IOException("Invalid onDisksize=" + onDiskSizeWithHeaderL
@ -1644,10 +1660,11 @@ public class HFileBlock implements Cacheable {
/** /**
* Verify the passed in onDiskSizeWithHeader aligns with what is in the header else something * Verify the passed in onDiskSizeWithHeader aligns with what is in the header else something
* is not right. * is not right.
* @throws IOException
*/ */
private void verifyOnDiskSizeMatchesHeader(final int passedIn, final ByteBuff headerBuf, private void verifyOnDiskSizeMatchesHeader(final int passedIn, final ByteBuff headerBuf,
final long offset, boolean verifyChecksum) final long offset, boolean verifyChecksum)
throws IOException { throws IOException {
// Assert size provided aligns with what is in the header // Assert size provided aligns with what is in the header
int fromHeader = getOnDiskSizeWithHeader(headerBuf, verifyChecksum); int fromHeader = getOnDiskSizeWithHeader(headerBuf, verifyChecksum);
if (passedIn != fromHeader) { if (passedIn != fromHeader) {
@ -1811,8 +1828,7 @@ public class HFileBlock implements Cacheable {
@Override @Override
public void setIncludesMemStoreTS(boolean includesMemstoreTS) { public void setIncludesMemStoreTS(boolean includesMemstoreTS) {
this.fileContext = new HFileContextBuilder(this.fileContext) this.fileContext.setIncludesMvcc(includesMemstoreTS);
.withIncludesMvcc(includesMemstoreTS).build();
} }
@Override @Override
@ -2058,7 +2074,7 @@ public class HFileBlock implements Cacheable {
/** /**
* @return This HFileBlocks fileContext which will a derivative of the * @return This HFileBlocks fileContext which will a derivative of the
* fileContext for the file from which this block's data was originally read. * fileContext for the file from which this block's data was originally read.
*/ */
HFileContext getHFileContext() { HFileContext getHFileContext() {
return this.fileContext; return this.fileContext;

View File

@ -1,4 +1,4 @@
/* /**
* *
* Licensed to the Apache Software Foundation (ASF) under one * Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file * or more contributor license agreements. See the NOTICE file
@ -32,6 +32,7 @@ import java.util.Map;
import java.util.Set; import java.util.Set;
import java.util.SortedMap; import java.util.SortedMap;
import java.util.TreeMap; import java.util.TreeMap;
import org.apache.commons.io.IOUtils; import org.apache.commons.io.IOUtils;
import org.apache.hadoop.conf.Configuration; import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.Path; import org.apache.hadoop.fs.Path;
@ -50,14 +51,7 @@ import org.apache.hadoop.hbase.shaded.protobuf.generated.HBaseProtos.BytesBytesP
import org.apache.hadoop.hbase.shaded.protobuf.generated.HFileProtos; import org.apache.hadoop.hbase.shaded.protobuf.generated.HFileProtos;
/** /**
* Metadata Map of attributes for HFile written out as HFile Trailer. Created by the Writer and * Metadata for HFile. Conjured by the writer. Read in by the reader.
* added to the tail of the file just before close. Metadata includes core attributes such as last
* key seen, comparator used writing the file, etc. Clients can add their own attributes via
* {@link #append(byte[], byte[], boolean)} and they'll be persisted and available at read time.
* Reader creates the HFileInfo on open by reading the tail of the HFile. The parse of the HFile
* trailer also creates a {@link HFileContext}, a read-only data structure that includes bulk of
* the HFileInfo and extras that is safe to pass around when working on HFiles.
* @see HFileContext
*/ */
@InterfaceAudience.Private @InterfaceAudience.Private
public class HFileInfo implements SortedMap<byte[], byte[]> { public class HFileInfo implements SortedMap<byte[], byte[]> {
@ -67,6 +61,7 @@ public class HFileInfo implements SortedMap<byte[], byte[]> {
static final byte [] AVG_KEY_LEN = Bytes.toBytes(RESERVED_PREFIX + "AVG_KEY_LEN"); static final byte [] AVG_KEY_LEN = Bytes.toBytes(RESERVED_PREFIX + "AVG_KEY_LEN");
static final byte [] AVG_VALUE_LEN = Bytes.toBytes(RESERVED_PREFIX + "AVG_VALUE_LEN"); static final byte [] AVG_VALUE_LEN = Bytes.toBytes(RESERVED_PREFIX + "AVG_VALUE_LEN");
static final byte [] CREATE_TIME_TS = Bytes.toBytes(RESERVED_PREFIX + "CREATE_TIME_TS"); static final byte [] CREATE_TIME_TS = Bytes.toBytes(RESERVED_PREFIX + "CREATE_TIME_TS");
static final byte [] COMPARATOR = Bytes.toBytes(RESERVED_PREFIX + "COMPARATOR");
static final byte [] TAGS_COMPRESSED = Bytes.toBytes(RESERVED_PREFIX + "TAGS_COMPRESSED"); static final byte [] TAGS_COMPRESSED = Bytes.toBytes(RESERVED_PREFIX + "TAGS_COMPRESSED");
public static final byte [] MAX_TAGS_LEN = Bytes.toBytes(RESERVED_PREFIX + "MAX_TAGS_LEN"); public static final byte [] MAX_TAGS_LEN = Bytes.toBytes(RESERVED_PREFIX + "MAX_TAGS_LEN");
private final SortedMap<byte [], byte []> map = new TreeMap<>(Bytes.BYTES_COMPARATOR); private final SortedMap<byte [], byte []> map = new TreeMap<>(Bytes.BYTES_COMPARATOR);
@ -383,8 +378,7 @@ public class HFileInfo implements SortedMap<byte[], byte[]> {
HFileContextBuilder builder = new HFileContextBuilder() HFileContextBuilder builder = new HFileContextBuilder()
.withHBaseCheckSum(true) .withHBaseCheckSum(true)
.withHFileName(path.getName()) .withHFileName(path.getName())
.withCompression(trailer.getCompressionCodec()) .withCompression(trailer.getCompressionCodec());
.withCellComparator(trailer.createComparator(trailer.getComparatorClassName()));
// Check for any key material available // Check for any key material available
byte[] keyBytes = trailer.getEncryptionKey(); byte[] keyBytes = trailer.getEncryptionKey();
if (keyBytes != null) { if (keyBytes != null) {

View File

@ -22,6 +22,7 @@ import java.io.IOException;
import java.nio.ByteBuffer; import java.nio.ByteBuffer;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Optional; import java.util.Optional;
import org.apache.hadoop.conf.Configurable; import org.apache.hadoop.conf.Configurable;
import org.apache.hadoop.conf.Configuration; import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.Path; import org.apache.hadoop.fs.Path;
@ -48,10 +49,12 @@ import org.apache.hadoop.hbase.util.Bytes;
import org.apache.hadoop.hbase.util.IdLock; import org.apache.hadoop.hbase.util.IdLock;
import org.apache.hadoop.hbase.util.ObjectIntPair; import org.apache.hadoop.hbase.util.ObjectIntPair;
import org.apache.hadoop.io.WritableUtils; import org.apache.hadoop.io.WritableUtils;
import org.apache.htrace.core.TraceScope; import org.apache.htrace.core.TraceScope;
import org.apache.yetus.audience.InterfaceAudience; import org.apache.yetus.audience.InterfaceAudience;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import org.apache.hbase.thirdparty.com.google.common.annotations.VisibleForTesting; import org.apache.hbase.thirdparty.com.google.common.annotations.VisibleForTesting;
/** /**
@ -82,6 +85,9 @@ public abstract class HFileReaderImpl implements HFile.Reader, Configurable {
*/ */
protected HFileDataBlockEncoder dataBlockEncoder = NoOpDataBlockEncoder.INSTANCE; protected HFileDataBlockEncoder dataBlockEncoder = NoOpDataBlockEncoder.INSTANCE;
/** Key comparator */
protected CellComparator comparator = CellComparator.getInstance();
/** Block cache configuration. */ /** Block cache configuration. */
protected final CacheConfig cacheConf; protected final CacheConfig cacheConf;
@ -139,6 +145,8 @@ public abstract class HFileReaderImpl implements HFile.Reader, Configurable {
this.primaryReplicaReader = context.isPrimaryReplicaReader(); this.primaryReplicaReader = context.isPrimaryReplicaReader();
this.fileInfo = fileInfo; this.fileInfo = fileInfo;
this.trailer = fileInfo.getTrailer(); this.trailer = fileInfo.getTrailer();
// Comparator class name is stored in the trailer in version 2.
this.comparator = trailer.createComparator();
this.hfileContext = fileInfo.getHFileContext(); this.hfileContext = fileInfo.getHFileContext();
this.fsBlockReader = new HFileBlock.FSReaderImpl(context, hfileContext, this.fsBlockReader = new HFileBlock.FSReaderImpl(context, hfileContext,
cacheConf.getByteBuffAllocator()); cacheConf.getByteBuffAllocator());
@ -230,7 +238,7 @@ public abstract class HFileReaderImpl implements HFile.Reader, Configurable {
/** @return comparator */ /** @return comparator */
@Override @Override
public CellComparator getComparator() { public CellComparator getComparator() {
return this.hfileContext.getCellComparator(); return comparator;
} }
@VisibleForTesting @VisibleForTesting
@ -390,9 +398,8 @@ public abstract class HFileReaderImpl implements HFile.Reader, Configurable {
} }
protected void assertSeeked() { protected void assertSeeked() {
if (!isSeeked()) { if (!isSeeked())
throw new NotSeekedException(reader.getPath()); throw new NotSeekedException(reader.getPath());
}
} }
@Override @Override
@ -469,6 +476,7 @@ public abstract class HFileReaderImpl implements HFile.Reader, Configurable {
/** /**
* Read mvcc. Does checks to see if we even need to read the mvcc at all. * Read mvcc. Does checks to see if we even need to read the mvcc at all.
* @param offsetFromPos
*/ */
protected void readMvccVersion(final int offsetFromPos) { protected void readMvccVersion(final int offsetFromPos) {
// See if we even need to decode mvcc. // See if we even need to decode mvcc.
@ -485,6 +493,7 @@ public abstract class HFileReaderImpl implements HFile.Reader, Configurable {
/** /**
* Actually do the mvcc read. Does no checks. * Actually do the mvcc read. Does no checks.
* @param offsetFromPos
*/ */
private void _readMvccVersion(int offsetFromPos) { private void _readMvccVersion(int offsetFromPos) {
// This is Bytes#bytesToVint inlined so can save a few instructions in this hot method; i.e. // This is Bytes#bytesToVint inlined so can save a few instructions in this hot method; i.e.
@ -672,6 +681,7 @@ public abstract class HFileReaderImpl implements HFile.Reader, Configurable {
* 0 if we are at the given key, 1 if we are past the given key * 0 if we are at the given key, 1 if we are past the given key
* -2 if the key is earlier than the first key of the file while * -2 if the key is earlier than the first key of the file while
* using a faked index key * using a faked index key
* @throws IOException
*/ */
public int seekTo(Cell key, boolean rewind) throws IOException { public int seekTo(Cell key, boolean rewind) throws IOException {
HFileBlockIndex.BlockIndexReader indexReader = reader.getDataBlockIndexReader(); HFileBlockIndex.BlockIndexReader indexReader = reader.getDataBlockIndexReader();
@ -737,6 +747,7 @@ public abstract class HFileReaderImpl implements HFile.Reader, Configurable {
* data block is found. * data block is found.
* *
* @return the next block, or null if there are no more data blocks * @return the next block, or null if there are no more data blocks
* @throws IOException
*/ */
@edu.umd.cs.findbugs.annotations.SuppressWarnings(value="NP_NULL_ON_SOME_PATH", @edu.umd.cs.findbugs.annotations.SuppressWarnings(value="NP_NULL_ON_SOME_PATH",
justification="Yeah, unnecessary null check; could do w/ clean up") justification="Yeah, unnecessary null check; could do w/ clean up")
@ -753,7 +764,8 @@ public abstract class HFileReaderImpl implements HFile.Reader, Configurable {
} }
if (block.getOffset() < 0) { if (block.getOffset() < 0) {
releaseIfNotCurBlock(block); releaseIfNotCurBlock(block);
throw new IOException("Invalid block offset=" + block + ", path=" + reader.getPath()); throw new IOException(
"Invalid block file offset: " + block + ", path=" + reader.getPath());
} }
// We are reading the next block without block type validation, because // We are reading the next block without block type validation, because
// it might turn out to be a non-data block. // it might turn out to be a non-data block.
@ -775,9 +787,8 @@ public abstract class HFileReaderImpl implements HFile.Reader, Configurable {
@Override @Override
public Cell getCell() { public Cell getCell() {
if (!isSeeked()) { if (!isSeeked())
return null; return null;
}
Cell ret; Cell ret;
int cellBufSize = getKVBufSize(); int cellBufSize = getKVBufSize();
@ -876,6 +887,7 @@ public abstract class HFileReaderImpl implements HFile.Reader, Configurable {
/** /**
* Set our selves up for the next 'next' invocation, set up next block. * Set our selves up for the next 'next' invocation, set up next block.
* @return True is more to read else false if at the end. * @return True is more to read else false if at the end.
* @throws IOException
*/ */
private boolean positionForNextBlock() throws IOException { private boolean positionForNextBlock() throws IOException {
// Methods are small so they get inlined because they are 'hot'. // Methods are small so they get inlined because they are 'hot'.
@ -931,6 +943,7 @@ public abstract class HFileReaderImpl implements HFile.Reader, Configurable {
* *
* @return false if empty file; i.e. a call to next would return false and * @return false if empty file; i.e. a call to next would return false and
* the current key and value are undefined. * the current key and value are undefined.
* @throws IOException
*/ */
@Override @Override
public boolean seekTo() throws IOException { public boolean seekTo() throws IOException {
@ -963,8 +976,8 @@ public abstract class HFileReaderImpl implements HFile.Reader, Configurable {
isCompaction, true, BlockType.DATA, getEffectiveDataBlockEncoding()); isCompaction, true, BlockType.DATA, getEffectiveDataBlockEncoding());
if (newBlock.getOffset() < 0) { if (newBlock.getOffset() < 0) {
releaseIfNotCurBlock(newBlock); releaseIfNotCurBlock(newBlock);
throw new IOException("Invalid offset=" + newBlock.getOffset() + throw new IOException(
", path=" + reader.getPath()); "Invalid block offset: " + newBlock.getOffset() + ", path=" + reader.getPath());
} }
updateCurrentBlock(newBlock); updateCurrentBlock(newBlock);
} }
@ -982,6 +995,7 @@ public abstract class HFileReaderImpl implements HFile.Reader, Configurable {
} }
/** /**
* @param v
* @return True if v &lt;= 0 or v &gt; current block buffer limit. * @return True if v &lt;= 0 or v &gt; current block buffer limit.
*/ */
protected final boolean checkKeyLen(final int v) { protected final boolean checkKeyLen(final int v) {
@ -989,6 +1003,7 @@ public abstract class HFileReaderImpl implements HFile.Reader, Configurable {
} }
/** /**
* @param v
* @return True if v &lt; 0 or v &gt; current block buffer limit. * @return True if v &lt; 0 or v &gt; current block buffer limit.
*/ */
protected final boolean checkLen(final int v) { protected final boolean checkLen(final int v) {
@ -1159,9 +1174,10 @@ public abstract class HFileReaderImpl implements HFile.Reader, Configurable {
// so blocks with the old encoding still linger in cache for some // so blocks with the old encoding still linger in cache for some
// period of time. This event should be rare as it only happens on // period of time. This event should be rare as it only happens on
// schema definition change. // schema definition change.
LOG.info("Evicting cached block with key {} because data block encoding mismatch; " + LOG.info("Evicting cached block with key " + cacheKey
"expected {}, actual {}, path={}", cacheKey, actualDataBlockEncoding, + " because of a data block encoding mismatch" + "; expected: "
expectedDataBlockEncoding, path); + expectedDataBlockEncoding + ", actual: " + actualDataBlockEncoding + ", path="
+ path);
// This is an error scenario. so here we need to release the block. // This is an error scenario. so here we need to release the block.
returnAndEvictBlock(cache, cacheKey, cachedBlock); returnAndEvictBlock(cache, cacheKey, cachedBlock);
} }
@ -1179,8 +1195,10 @@ public abstract class HFileReaderImpl implements HFile.Reader, Configurable {
} }
/** /**
* @param metaBlockName
* @param cacheBlock Add block to cache, if found * @param cacheBlock Add block to cache, if found
* @return block wrapped in a ByteBuffer, with header skipped * @return block wrapped in a ByteBuffer, with header skipped
* @throws IOException
*/ */
@Override @Override
public HFileBlock getMetaBlock(String metaBlockName, boolean cacheBlock) public HFileBlock getMetaBlock(String metaBlockName, boolean cacheBlock)
@ -1195,9 +1213,8 @@ public abstract class HFileReaderImpl implements HFile.Reader, Configurable {
byte[] mbname = Bytes.toBytes(metaBlockName); byte[] mbname = Bytes.toBytes(metaBlockName);
int block = metaBlockIndexReader.rootBlockContainingKey(mbname, int block = metaBlockIndexReader.rootBlockContainingKey(mbname,
0, mbname.length); 0, mbname.length);
if (block == -1) { if (block == -1)
return null; return null;
}
long blockSize = metaBlockIndexReader.getRootBlockDataSize(block); long blockSize = metaBlockIndexReader.getRootBlockDataSize(block);
// Per meta key from any given file, synchronize reads for said block. This // Per meta key from any given file, synchronize reads for said block. This
@ -1404,6 +1421,7 @@ public abstract class HFileReaderImpl implements HFile.Reader, Configurable {
/** /**
* @return Midkey for this file. We work with block boundaries only so * @return Midkey for this file. We work with block boundaries only so
* returned midkey is an approximation only. * returned midkey is an approximation only.
* @throws IOException
*/ */
@Override @Override
public Optional<Cell> midKey() throws IOException { public Optional<Cell> midKey() throws IOException {
@ -1440,7 +1458,8 @@ public abstract class HFileReaderImpl implements HFile.Reader, Configurable {
DataBlockEncoding encoding = reader.getDataBlockEncoding(); DataBlockEncoding encoding = reader.getDataBlockEncoding();
dataBlockEncoder = encoding.getEncoder(); dataBlockEncoder = encoding.getEncoder();
decodingCtx = dataBlockEncoder.newDataBlockDecodingContext(meta); decodingCtx = dataBlockEncoder.newDataBlockDecodingContext(meta);
seeker = dataBlockEncoder.createSeeker(decodingCtx); seeker = dataBlockEncoder.createSeeker(
reader.getComparator(), decodingCtx);
} }
@Override @Override
@ -1459,6 +1478,7 @@ public abstract class HFileReaderImpl implements HFile.Reader, Configurable {
* @param newBlock the block to make current, and read by {@link HFileReaderImpl#readBlock}, * @param newBlock the block to make current, and read by {@link HFileReaderImpl#readBlock},
* it's a totally new block with new allocated {@link ByteBuff}, so if no further * it's a totally new block with new allocated {@link ByteBuff}, so if no further
* reference to this block, we should release it carefully. * reference to this block, we should release it carefully.
* @throws CorruptHFileException
*/ */
@Override @Override
protected void updateCurrentBlock(HFileBlock newBlock) throws CorruptHFileException { protected void updateCurrentBlock(HFileBlock newBlock) throws CorruptHFileException {
@ -1470,9 +1490,9 @@ public abstract class HFileReaderImpl implements HFile.Reader, Configurable {
short dataBlockEncoderId = newBlock.getDataBlockEncodingId(); short dataBlockEncoderId = newBlock.getDataBlockEncodingId();
if (!DataBlockEncoding.isCorrectEncoder(dataBlockEncoder, dataBlockEncoderId)) { if (!DataBlockEncoding.isCorrectEncoder(dataBlockEncoder, dataBlockEncoderId)) {
String encoderCls = dataBlockEncoder.getClass().getName(); String encoderCls = dataBlockEncoder.getClass().getName();
throw new CorruptHFileException("Encoder " + encoderCls + throw new CorruptHFileException("Encoder " + encoderCls
" doesn't support data block encoding " + + " doesn't support data block encoding "
DataBlockEncoding.getNameFromId(dataBlockEncoderId) + ",path=" + reader.getPath()); + DataBlockEncoding.getNameFromId(dataBlockEncoderId) + ",path=" + reader.getPath());
} }
updateCurrBlockRef(newBlock); updateCurrBlockRef(newBlock);
ByteBuff encodedBuffer = getEncodedBuffer(newBlock); ByteBuff encodedBuffer = getEncodedBuffer(newBlock);
@ -1589,7 +1609,7 @@ public abstract class HFileReaderImpl implements HFile.Reader, Configurable {
} }
private DataInput getBloomFilterMetadata(BlockType blockType) private DataInput getBloomFilterMetadata(BlockType blockType)
throws IOException { throws IOException {
if (blockType != BlockType.GENERAL_BLOOM_META && if (blockType != BlockType.GENERAL_BLOOM_META &&
blockType != BlockType.DELETE_FAMILY_BLOOM_META) { blockType != BlockType.DELETE_FAMILY_BLOOM_META) {
throw new RuntimeException("Block Type: " + blockType.toString() + throw new RuntimeException("Block Type: " + blockType.toString() +

View File

@ -25,6 +25,7 @@ import java.net.InetSocketAddress;
import java.nio.ByteBuffer; import java.nio.ByteBuffer;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import org.apache.hadoop.conf.Configuration; import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.FSDataOutputStream; import org.apache.hadoop.fs.FSDataOutputStream;
import org.apache.hadoop.fs.FileSystem; import org.apache.hadoop.fs.FileSystem;
@ -64,8 +65,7 @@ public class HFileWriterImpl implements HFile.Writer {
private static final long UNSET = -1; private static final long UNSET = -1;
/** if this feature is enabled, preCalculate encoded data size before real encoding happens*/ /** if this feature is enabled, preCalculate encoded data size before real encoding happens*/
public static final String UNIFIED_ENCODED_BLOCKSIZE_RATIO = public static final String UNIFIED_ENCODED_BLOCKSIZE_RATIO = "hbase.writer.unified.encoded.blocksize.ratio";
"hbase.writer.unified.encoded.blocksize.ratio";
/** Block size limit after encoding, used to unify encoded block Cache entry size*/ /** Block size limit after encoding, used to unify encoded block Cache entry size*/
private final int encodedBlockSizeLimit; private final int encodedBlockSizeLimit;
@ -94,6 +94,9 @@ public class HFileWriterImpl implements HFile.Writer {
/** Total uncompressed bytes, maybe calculate a compression ratio later. */ /** Total uncompressed bytes, maybe calculate a compression ratio later. */
protected long totalUncompressedBytes = 0; protected long totalUncompressedBytes = 0;
/** Key comparator. Used to ensure we write in order. */
protected final CellComparator comparator;
/** Meta block names. */ /** Meta block names. */
protected List<byte[]> metaNames = new ArrayList<>(); protected List<byte[]> metaNames = new ArrayList<>();
@ -162,7 +165,8 @@ public class HFileWriterImpl implements HFile.Writer {
protected long maxMemstoreTS = 0; protected long maxMemstoreTS = 0;
public HFileWriterImpl(final Configuration conf, CacheConfig cacheConf, Path path, public HFileWriterImpl(final Configuration conf, CacheConfig cacheConf, Path path,
FSDataOutputStream outputStream, HFileContext fileContext) { FSDataOutputStream outputStream,
CellComparator comparator, HFileContext fileContext) {
this.outputStream = outputStream; this.outputStream = outputStream;
this.path = path; this.path = path;
this.name = path != null ? path.getName() : outputStream.toString(); this.name = path != null ? path.getName() : outputStream.toString();
@ -173,6 +177,8 @@ public class HFileWriterImpl implements HFile.Writer {
} else { } else {
this.blockEncoder = NoOpDataBlockEncoder.INSTANCE; this.blockEncoder = NoOpDataBlockEncoder.INSTANCE;
} }
this.comparator = comparator != null ? comparator : CellComparator.getInstance();
closeOutputStream = path != null; closeOutputStream = path != null;
this.cacheConf = cacheConf; this.cacheConf = cacheConf;
float encodeBlockSizeRatio = conf.getFloat(UNIFIED_ENCODED_BLOCKSIZE_RATIO, 1f); float encodeBlockSizeRatio = conf.getFloat(UNIFIED_ENCODED_BLOCKSIZE_RATIO, 1f);
@ -181,6 +187,7 @@ public class HFileWriterImpl implements HFile.Writer {
if (LOG.isTraceEnabled()) { if (LOG.isTraceEnabled()) {
LOG.trace("Writer" + (path != null ? " for " + path : "") + LOG.trace("Writer" + (path != null ? " for " + path : "") +
" initialized with cacheConf: " + cacheConf + " initialized with cacheConf: " + cacheConf +
" comparator: " + comparator.getClass().getSimpleName() +
" fileContext: " + fileContext); " fileContext: " + fileContext);
} }
} }
@ -207,9 +214,10 @@ public class HFileWriterImpl implements HFile.Writer {
* *
* @param trailer fixed file trailer * @param trailer fixed file trailer
* @param out the data output to write the file info to * @param out the data output to write the file info to
* @throws IOException
*/ */
protected final void writeFileInfo(FixedFileTrailer trailer, DataOutputStream out) protected final void writeFileInfo(FixedFileTrailer trailer, DataOutputStream out)
throws IOException { throws IOException {
trailer.setFileInfoOffset(outputStream.getPos()); trailer.setFileInfoOffset(outputStream.getPos());
finishFileInfo(); finishFileInfo();
long startTime = System.currentTimeMillis(); long startTime = System.currentTimeMillis();
@ -231,8 +239,7 @@ public class HFileWriterImpl implements HFile.Writer {
throw new IOException("Key cannot be null or empty"); throw new IOException("Key cannot be null or empty");
} }
if (lastCell != null) { if (lastCell != null) {
int keyComp = PrivateCellUtil.compareKeyIgnoresMvcc(this.hFileContext.getCellComparator(), int keyComp = PrivateCellUtil.compareKeyIgnoresMvcc(comparator, lastCell, cell);
lastCell, cell);
if (keyComp > 0) { if (keyComp > 0) {
String message = getLexicalErrorMessage(cell); String message = getLexicalErrorMessage(cell);
throw new IOException(message); throw new IOException(message);
@ -278,9 +285,8 @@ public class HFileWriterImpl implements HFile.Writer {
} }
public static Compression.Algorithm compressionByName(String algoName) { public static Compression.Algorithm compressionByName(String algoName) {
if (algoName == null) { if (algoName == null)
return HFile.DEFAULT_COMPRESSION_ALGORITHM; return HFile.DEFAULT_COMPRESSION_ALGORITHM;
}
return Compression.getCompressionAlgorithmByName(algoName); return Compression.getCompressionAlgorithmByName(algoName);
} }
@ -312,15 +318,17 @@ public class HFileWriterImpl implements HFile.Writer {
// Meta data block index writer // Meta data block index writer
metaBlockIndexWriter = new HFileBlockIndex.BlockIndexWriter(); metaBlockIndexWriter = new HFileBlockIndex.BlockIndexWriter();
LOG.trace("Initialized with {}", cacheConf); if (LOG.isTraceEnabled()) LOG.trace("Initialized with " + cacheConf);
} }
/** /**
* At a block boundary, write all the inline blocks and opens new block. * At a block boundary, write all the inline blocks and opens new block.
*
* @throws IOException
*/ */
protected void checkBlockBoundary() throws IOException { protected void checkBlockBoundary() throws IOException {
// For encoder like prefixTree, encoded size is not available, so we have to compare both //for encoder like prefixTree, encoded size is not available, so we have to compare both encoded size
// encoded size and unencoded size to blocksize limit. //and unencoded size to blocksize limit.
if (blockWriter.encodedBlockSizeWritten() >= encodedBlockSizeLimit if (blockWriter.encodedBlockSizeWritten() >= encodedBlockSizeLimit
|| blockWriter.blockSizeWritten() >= hFileContext.getBlocksize()) { || blockWriter.blockSizeWritten() >= hFileContext.getBlocksize()) {
finishBlock(); finishBlock();
@ -331,9 +339,7 @@ public class HFileWriterImpl implements HFile.Writer {
/** Clean up the data block that is currently being written.*/ /** Clean up the data block that is currently being written.*/
private void finishBlock() throws IOException { private void finishBlock() throws IOException {
if (!blockWriter.isWriting() || blockWriter.blockSizeWritten() == 0) { if (!blockWriter.isWriting() || blockWriter.blockSizeWritten() == 0) return;
return;
}
// Update the first data block offset if UNSET; used scanning. // Update the first data block offset if UNSET; used scanning.
if (firstDataBlockOffset == UNSET) { if (firstDataBlockOffset == UNSET) {
@ -344,7 +350,7 @@ public class HFileWriterImpl implements HFile.Writer {
blockWriter.writeHeaderAndData(outputStream); blockWriter.writeHeaderAndData(outputStream);
int onDiskSize = blockWriter.getOnDiskSizeWithHeader(); int onDiskSize = blockWriter.getOnDiskSizeWithHeader();
Cell indexEntry = Cell indexEntry =
getMidpoint(this.hFileContext.getCellComparator(), lastCellOfPreviousBlock, firstCellInBlock); getMidpoint(this.comparator, lastCellOfPreviousBlock, firstCellInBlock);
dataBlockIndexWriter.addEntry(PrivateCellUtil.getCellKeySerializedAsKeyValueKey(indexEntry), dataBlockIndexWriter.addEntry(PrivateCellUtil.getCellKeySerializedAsKeyValueKey(indexEntry),
lastDataBlockOffset, onDiskSize); lastDataBlockOffset, onDiskSize);
totalUncompressedBytes += blockWriter.getUncompressedSizeWithHeader(); totalUncompressedBytes += blockWriter.getUncompressedSizeWithHeader();
@ -358,6 +364,11 @@ public class HFileWriterImpl implements HFile.Writer {
* <code>right</code> but that is shorter; i.e. takes up less space. This * <code>right</code> but that is shorter; i.e. takes up less space. This
* trick is used building HFile block index. Its an optimization. It does not * trick is used building HFile block index. Its an optimization. It does not
* always work. In this case we'll just return the <code>right</code> cell. * always work. In this case we'll just return the <code>right</code> cell.
*
* @param comparator
* Comparator to use.
* @param left
* @param right
* @return A cell that sorts between <code>left</code> and <code>right</code>. * @return A cell that sorts between <code>left</code> and <code>right</code>.
*/ */
public static Cell getMidpoint(final CellComparator comparator, final Cell left, public static Cell getMidpoint(final CellComparator comparator, final Cell left,
@ -396,9 +407,7 @@ public class HFileWriterImpl implements HFile.Writer {
left.getRowLength(), right.getRowArray(), right.getRowOffset(), right.getRowLength()); left.getRowLength(), right.getRowArray(), right.getRowOffset(), right.getRowLength());
} }
// If midRow is null, just return 'right'. Can't do optimization. // If midRow is null, just return 'right'. Can't do optimization.
if (midRow == null) { if (midRow == null) return right;
return right;
}
return PrivateCellUtil.createFirstOnRow(midRow); return PrivateCellUtil.createFirstOnRow(midRow);
} }
// Rows are same. Compare on families. // Rows are same. Compare on families.
@ -419,9 +428,7 @@ public class HFileWriterImpl implements HFile.Writer {
right.getFamilyLength()); right.getFamilyLength());
} }
// If midRow is null, just return 'right'. Can't do optimization. // If midRow is null, just return 'right'. Can't do optimization.
if (midRow == null) { if (midRow == null) return right;
return right;
}
// Return new Cell where we use right row and then a mid sort family. // Return new Cell where we use right row and then a mid sort family.
return PrivateCellUtil.createFirstOnRowFamily(right, midRow, 0, midRow.length); return PrivateCellUtil.createFirstOnRowFamily(right, midRow, 0, midRow.length);
} }
@ -443,9 +450,7 @@ public class HFileWriterImpl implements HFile.Writer {
right.getQualifierLength()); right.getQualifierLength());
} }
// If midRow is null, just return 'right'. Can't do optimization. // If midRow is null, just return 'right'. Can't do optimization.
if (midRow == null) { if (midRow == null) return right;
return right;
}
// Return new Cell where we use right row and family and then a mid sort qualifier. // Return new Cell where we use right row and family and then a mid sort qualifier.
return PrivateCellUtil.createFirstOnRowCol(right, midRow, 0, midRow.length); return PrivateCellUtil.createFirstOnRowCol(right, midRow, 0, midRow.length);
} }
@ -454,6 +459,12 @@ public class HFileWriterImpl implements HFile.Writer {
} }
/** /**
* @param leftArray
* @param leftOffset
* @param leftLength
* @param rightArray
* @param rightOffset
* @param rightLength
* @return Return a new array that is between left and right and minimally * @return Return a new array that is between left and right and minimally
* sized else just return null as indicator that we could not create a * sized else just return null as indicator that we could not create a
* mid point. * mid point.
@ -555,6 +566,8 @@ public class HFileWriterImpl implements HFile.Writer {
/** /**
* Ready a new block for writing. * Ready a new block for writing.
*
* @throws IOException
*/ */
protected void newBlock() throws IOException { protected void newBlock() throws IOException {
// This is where the next block begins. // This is where the next block begins.
@ -665,7 +678,7 @@ public class HFileWriterImpl implements HFile.Writer {
dataBlockIndexWriter.getTotalUncompressedSize()); dataBlockIndexWriter.getTotalUncompressedSize());
trailer.setFirstDataBlockOffset(firstDataBlockOffset); trailer.setFirstDataBlockOffset(firstDataBlockOffset);
trailer.setLastDataBlockOffset(lastDataBlockOffset); trailer.setLastDataBlockOffset(lastDataBlockOffset);
trailer.setComparatorClass(this.hFileContext.getCellComparator().getClass()); trailer.setComparatorClass(comparator.getClass());
trailer.setDataIndexCount(dataBlockIndexWriter.getNumRootEntries()); trailer.setDataIndexCount(dataBlockIndexWriter.getNumRootEntries());
@ -691,9 +704,8 @@ public class HFileWriterImpl implements HFile.Writer {
private void addBloomFilter(final BloomFilterWriter bfw, private void addBloomFilter(final BloomFilterWriter bfw,
final BlockType blockType) { final BlockType blockType) {
if (bfw.getKeyCount() <= 0) { if (bfw.getKeyCount() <= 0)
return; return;
}
if (blockType != BlockType.GENERAL_BLOOM_META && if (blockType != BlockType.GENERAL_BLOOM_META &&
blockType != BlockType.DELETE_FAMILY_BLOOM_META) { blockType != BlockType.DELETE_FAMILY_BLOOM_META) {
@ -710,9 +722,8 @@ public class HFileWriterImpl implements HFile.Writer {
public void writeToBlock(DataOutput out) throws IOException { public void writeToBlock(DataOutput out) throws IOException {
bfw.getMetaWriter().write(out); bfw.getMetaWriter().write(out);
Writable dataWriter = bfw.getDataWriter(); Writable dataWriter = bfw.getDataWriter();
if (dataWriter != null) { if (dataWriter != null)
dataWriter.write(out); dataWriter.write(out);
}
} }
}); });
} }
@ -728,6 +739,7 @@ public class HFileWriterImpl implements HFile.Writer {
* *
* @param cell * @param cell
* Cell to add. Cannot be empty nor null. * Cell to add. Cannot be empty nor null.
* @throws IOException
*/ */
@Override @Override
public void append(final Cell cell) throws IOException { public void append(final Cell cell) throws IOException {

View File

@ -1,4 +1,4 @@
/* /**
* *
* Licensed to the Apache Software Foundation (ASF) under one * Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file * or more contributor license agreements. See the NOTICE file
@ -35,11 +35,13 @@ import java.util.concurrent.RejectedExecutionHandler;
import java.util.concurrent.SynchronousQueue; import java.util.concurrent.SynchronousQueue;
import java.util.concurrent.ThreadPoolExecutor; import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
import org.apache.hadoop.conf.Configuration; import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.FileStatus; import org.apache.hadoop.fs.FileStatus;
import org.apache.hadoop.fs.FileSystem; import org.apache.hadoop.fs.FileSystem;
import org.apache.hadoop.fs.Path; import org.apache.hadoop.fs.Path;
import org.apache.hadoop.hbase.Cell; import org.apache.hadoop.hbase.Cell;
import org.apache.hadoop.hbase.CellComparator;
import org.apache.hadoop.hbase.HConstants; import org.apache.hadoop.hbase.HConstants;
import org.apache.hadoop.hbase.PrivateCellUtil; import org.apache.hadoop.hbase.PrivateCellUtil;
import org.apache.hadoop.hbase.TableName; import org.apache.hadoop.hbase.TableName;
@ -122,6 +124,7 @@ public final class MobUtils {
* Parses the string to a date. * Parses the string to a date.
* @param dateString The string format of a date, it's yyyymmdd. * @param dateString The string format of a date, it's yyyymmdd.
* @return A date. * @return A date.
* @throws ParseException
*/ */
public static Date parseDate(String dateString) throws ParseException { public static Date parseDate(String dateString) throws ParseException {
return LOCAL_FORMAT.get().parse(dateString); return LOCAL_FORMAT.get().parse(dateString);
@ -285,6 +288,7 @@ public final class MobUtils {
* @param columnDescriptor The descriptor of the current column family. * @param columnDescriptor The descriptor of the current column family.
* @param cacheConfig The cacheConfig that disables the block cache. * @param cacheConfig The cacheConfig that disables the block cache.
* @param current The current time. * @param current The current time.
* @throws IOException
*/ */
public static void cleanExpiredMobFiles(FileSystem fs, Configuration conf, TableName tableName, public static void cleanExpiredMobFiles(FileSystem fs, Configuration conf, TableName tableName,
ColumnFamilyDescriptor columnDescriptor, CacheConfig cacheConfig, long current) ColumnFamilyDescriptor columnDescriptor, CacheConfig cacheConfig, long current)
@ -380,6 +384,7 @@ public final class MobUtils {
* Gets the qualified root dir of the mob files. * Gets the qualified root dir of the mob files.
* @param conf The current configuration. * @param conf The current configuration.
* @return The qualified root dir. * @return The qualified root dir.
* @throws IOException
*/ */
public static Path getQualifiedMobRootDir(Configuration conf) throws IOException { public static Path getQualifiedMobRootDir(Configuration conf) throws IOException {
Path hbaseDir = new Path(conf.get(HConstants.HBASE_DIR)); Path hbaseDir = new Path(conf.get(HConstants.HBASE_DIR));
@ -500,6 +505,7 @@ public final class MobUtils {
* @param tableDir The table directory. * @param tableDir The table directory.
* @param family The name of the column family. * @param family The name of the column family.
* @param storeFiles The files to be deleted. * @param storeFiles The files to be deleted.
* @throws IOException
*/ */
public static void removeMobFiles(Configuration conf, FileSystem fs, TableName tableName, public static void removeMobFiles(Configuration conf, FileSystem fs, TableName tableName,
Path tableDir, byte[] family, Collection<HStoreFile> storeFiles) throws IOException { Path tableDir, byte[] family, Collection<HStoreFile> storeFiles) throws IOException {
@ -550,6 +556,7 @@ public final class MobUtils {
* @param cryptoContext The encryption context. * @param cryptoContext The encryption context.
* @param isCompaction If the writer is used in compaction. * @param isCompaction If the writer is used in compaction.
* @return The writer for the mob file. * @return The writer for the mob file.
* @throws IOException
*/ */
public static StoreFileWriter createWriter(Configuration conf, FileSystem fs, public static StoreFileWriter createWriter(Configuration conf, FileSystem fs,
ColumnFamilyDescriptor family, String date, Path basePath, long maxKeyCount, ColumnFamilyDescriptor family, String date, Path basePath, long maxKeyCount,
@ -573,6 +580,7 @@ public final class MobUtils {
* @param cryptoContext The encryption context. * @param cryptoContext The encryption context.
* @param isCompaction If the writer is used in compaction. * @param isCompaction If the writer is used in compaction.
* @return The writer for the mob file. * @return The writer for the mob file.
* @throws IOException
*/ */
public static StoreFileWriter createRefFileWriter(Configuration conf, FileSystem fs, public static StoreFileWriter createRefFileWriter(Configuration conf, FileSystem fs,
ColumnFamilyDescriptor family, Path basePath, long maxKeyCount, CacheConfig cacheConfig, ColumnFamilyDescriptor family, Path basePath, long maxKeyCount, CacheConfig cacheConfig,
@ -599,6 +607,7 @@ public final class MobUtils {
* @param cryptoContext The encryption context. * @param cryptoContext The encryption context.
* @param isCompaction If the writer is used in compaction. * @param isCompaction If the writer is used in compaction.
* @return The writer for the mob file. * @return The writer for the mob file.
* @throws IOException
*/ */
public static StoreFileWriter createWriter(Configuration conf, FileSystem fs, public static StoreFileWriter createWriter(Configuration conf, FileSystem fs,
ColumnFamilyDescriptor family, String date, Path basePath, long maxKeyCount, ColumnFamilyDescriptor family, String date, Path basePath, long maxKeyCount,
@ -624,6 +633,7 @@ public final class MobUtils {
* @param cacheConfig The current cache config. * @param cacheConfig The current cache config.
* @param cryptoContext The encryption context. * @param cryptoContext The encryption context.
* @return The writer for the del file. * @return The writer for the del file.
* @throws IOException
*/ */
public static StoreFileWriter createDelFileWriter(Configuration conf, FileSystem fs, public static StoreFileWriter createDelFileWriter(Configuration conf, FileSystem fs,
ColumnFamilyDescriptor family, String date, Path basePath, long maxKeyCount, ColumnFamilyDescriptor family, String date, Path basePath, long maxKeyCount,
@ -650,9 +660,10 @@ public final class MobUtils {
* @param cryptoContext The encryption context. * @param cryptoContext The encryption context.
* @param isCompaction If the writer is used in compaction. * @param isCompaction If the writer is used in compaction.
* @return The writer for the mob file. * @return The writer for the mob file.
* @throws IOException
*/ */
public static StoreFileWriter createWriter(Configuration conf, FileSystem fs, public static StoreFileWriter createWriter(Configuration conf, FileSystem fs,
ColumnFamilyDescriptor family, MobFileName mobFileName, Path basePath, long maxKeyCount, ColumnFamilyDescriptor family, MobFileName mobFileName, Path basePath, long maxKeyCount,
Compression.Algorithm compression, CacheConfig cacheConfig, Encryption.Context cryptoContext, Compression.Algorithm compression, CacheConfig cacheConfig, Encryption.Context cryptoContext,
boolean isCompaction) boolean isCompaction)
throws IOException { throws IOException {
@ -678,6 +689,7 @@ public final class MobUtils {
* @param bloomType The bloom filter type. * @param bloomType The bloom filter type.
* @param isCompaction If the writer is used in compaction. * @param isCompaction If the writer is used in compaction.
* @return The writer for the mob file. * @return The writer for the mob file.
* @throws IOException
*/ */
public static StoreFileWriter createWriter(Configuration conf, FileSystem fs, public static StoreFileWriter createWriter(Configuration conf, FileSystem fs,
ColumnFamilyDescriptor family, Path path, long maxKeyCount, ColumnFamilyDescriptor family, Path path, long maxKeyCount,
@ -706,7 +718,8 @@ public final class MobUtils {
.withCreateTime(EnvironmentEdgeManager.currentTime()).build(); .withCreateTime(EnvironmentEdgeManager.currentTime()).build();
StoreFileWriter w = new StoreFileWriter.Builder(conf, writerCacheConf, fs) StoreFileWriter w = new StoreFileWriter.Builder(conf, writerCacheConf, fs)
.withFilePath(path).withBloomType(bloomType) .withFilePath(path)
.withComparator(CellComparator.getInstance()).withBloomType(bloomType)
.withMaxKeyCount(maxKeyCount).withFileContext(hFileContext).build(); .withMaxKeyCount(maxKeyCount).withFileContext(hFileContext).build();
return w; return w;
} }
@ -719,6 +732,7 @@ public final class MobUtils {
* @param targetPath The directory path where the source file is renamed to. * @param targetPath The directory path where the source file is renamed to.
* @param cacheConfig The current cache config. * @param cacheConfig The current cache config.
* @return The target file path the source file is renamed to. * @return The target file path the source file is renamed to.
* @throws IOException
*/ */
public static Path commitFile(Configuration conf, FileSystem fs, final Path sourceFile, public static Path commitFile(Configuration conf, FileSystem fs, final Path sourceFile,
Path targetPath, CacheConfig cacheConfig) throws IOException { Path targetPath, CacheConfig cacheConfig) throws IOException {
@ -823,8 +837,7 @@ public final class MobUtils {
* @param allFiles Whether add all mob files into the compaction. * @param allFiles Whether add all mob files into the compaction.
*/ */
public static void doMobCompaction(Configuration conf, FileSystem fs, TableName tableName, public static void doMobCompaction(Configuration conf, FileSystem fs, TableName tableName,
ColumnFamilyDescriptor hcd, ExecutorService pool, boolean allFiles, ColumnFamilyDescriptor hcd, ExecutorService pool, boolean allFiles, LockManager.MasterLock lock)
LockManager.MasterLock lock)
throws IOException { throws IOException {
String className = conf.get(MobConstants.MOB_COMPACTOR_CLASS_KEY, String className = conf.get(MobConstants.MOB_COMPACTOR_CLASS_KEY,
PartitionedMobCompactor.class.getName()); PartitionedMobCompactor.class.getName());
@ -930,8 +943,7 @@ public final class MobUtils {
* @param fileDate The date string parsed from the mob file name. * @param fileDate The date string parsed from the mob file name.
* @return True if the mob file is expired. * @return True if the mob file is expired.
*/ */
public static boolean isMobFileExpired(ColumnFamilyDescriptor column, long current, public static boolean isMobFileExpired(ColumnFamilyDescriptor column, long current, String fileDate) {
String fileDate) {
if (column.getMinVersions() > 0) { if (column.getMinVersions() > 0) {
return false; return false;
} }

View File

@ -52,6 +52,7 @@ import java.util.function.Predicate;
import java.util.function.ToLongFunction; import java.util.function.ToLongFunction;
import java.util.stream.Collectors; import java.util.stream.Collectors;
import java.util.stream.LongStream; import java.util.stream.LongStream;
import org.apache.hadoop.conf.Configuration; import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.FileSystem; import org.apache.hadoop.fs.FileSystem;
import org.apache.hadoop.fs.Path; import org.apache.hadoop.fs.Path;
@ -131,8 +132,7 @@ import org.apache.hadoop.hbase.shaded.protobuf.generated.WALProtos.CompactionDes
* not be called directly but by an HRegion manager. * not be called directly but by an HRegion manager.
*/ */
@InterfaceAudience.Private @InterfaceAudience.Private
public class HStore implements Store, HeapSize, StoreConfigInformation, public class HStore implements Store, HeapSize, StoreConfigInformation, PropagatingConfigurationObserver {
PropagatingConfigurationObserver {
public static final String MEMSTORE_CLASS_NAME = "hbase.regionserver.memstore.class"; public static final String MEMSTORE_CLASS_NAME = "hbase.regionserver.memstore.class";
public static final String COMPACTCHECKER_INTERVAL_MULTIPLIER_KEY = public static final String COMPACTCHECKER_INTERVAL_MULTIPLIER_KEY =
"hbase.server.compactchecker.interval.multiplier"; "hbase.server.compactchecker.interval.multiplier";
@ -237,8 +237,11 @@ public class HStore implements Store, HeapSize, StoreConfigInformation,
/** /**
* Constructor * Constructor
* @param region
* @param family HColumnDescriptor for this column * @param family HColumnDescriptor for this column
* @param confParam configuration object failed. Can be null. * @param confParam configuration object
* failed. Can be null.
* @throws IOException
*/ */
protected HStore(final HRegion region, final ColumnFamilyDescriptor family, protected HStore(final HRegion region, final ColumnFamilyDescriptor family,
final Configuration confParam, boolean warmup) throws IOException { final Configuration confParam, boolean warmup) throws IOException {
@ -396,6 +399,7 @@ public class HStore implements Store, HeapSize, StoreConfigInformation,
} }
/** /**
* @param family
* @return TTL in seconds of the specified family * @return TTL in seconds of the specified family
*/ */
public static long determineTTLFromFamily(final ColumnFamilyDescriptor family) { public static long determineTTLFromFamily(final ColumnFamilyDescriptor family) {
@ -517,7 +521,6 @@ public class HStore implements Store, HeapSize, StoreConfigInformation,
* @param hri {@link RegionInfo} for the region. * @param hri {@link RegionInfo} for the region.
* @param family {@link ColumnFamilyDescriptor} describing the column family * @param family {@link ColumnFamilyDescriptor} describing the column family
* @return Path to family/Store home directory. * @return Path to family/Store home directory.
* @deprecated Since 05/05/2013, HBase-7808, hbase-1.0.0
*/ */
@Deprecated @Deprecated
public static Path getStoreHomedir(final Path tabledir, public static Path getStoreHomedir(final Path tabledir,
@ -530,7 +533,6 @@ public class HStore implements Store, HeapSize, StoreConfigInformation,
* @param encodedName Encoded region name. * @param encodedName Encoded region name.
* @param family {@link ColumnFamilyDescriptor} describing the column family * @param family {@link ColumnFamilyDescriptor} describing the column family
* @return Path to family/Store home directory. * @return Path to family/Store home directory.
* @deprecated Since 05/05/2013, HBase-7808, hbase-1.0.0
*/ */
@Deprecated @Deprecated
public static Path getStoreHomedir(final Path tabledir, public static Path getStoreHomedir(final Path tabledir,
@ -556,6 +558,7 @@ public class HStore implements Store, HeapSize, StoreConfigInformation,
/** /**
* Creates an unsorted list of StoreFile loaded in parallel * Creates an unsorted list of StoreFile loaded in parallel
* from the given directory. * from the given directory.
* @throws IOException
*/ */
private List<HStoreFile> loadStoreFiles(boolean warmup) throws IOException { private List<HStoreFile> loadStoreFiles(boolean warmup) throws IOException {
Collection<StoreFileInfo> files = fs.getStoreFiles(getColumnFamilyName()); Collection<StoreFileInfo> files = fs.getStoreFiles(getColumnFamilyName());
@ -571,8 +574,7 @@ public class HStore implements Store, HeapSize, StoreConfigInformation,
ThreadPoolExecutor storeFileOpenerThreadPool = ThreadPoolExecutor storeFileOpenerThreadPool =
this.region.getStoreFileOpenAndCloseThreadPool("StoreFileOpenerThread-" + this.region.getStoreFileOpenAndCloseThreadPool("StoreFileOpenerThread-" +
this.getColumnFamilyName()); this.getColumnFamilyName());
CompletionService<HStoreFile> completionService = CompletionService<HStoreFile> completionService = new ExecutorCompletionService<>(storeFileOpenerThreadPool);
new ExecutorCompletionService<>(storeFileOpenerThreadPool);
int totalValidStoreFile = 0; int totalValidStoreFile = 0;
for (StoreFileInfo storeFileInfo : files) { for (StoreFileInfo storeFileInfo : files) {
@ -594,13 +596,9 @@ public class HStore implements Store, HeapSize, StoreConfigInformation,
compactedStoreFiles.addAll(storeFile.getCompactedStoreFiles()); compactedStoreFiles.addAll(storeFile.getCompactedStoreFiles());
} }
} catch (InterruptedException e) { } catch (InterruptedException e) {
if (ioe == null) { if (ioe == null) ioe = new InterruptedIOException(e.getMessage());
ioe = new InterruptedIOException(e.getMessage());
}
} catch (ExecutionException e) { } catch (ExecutionException e) {
if (ioe == null) { if (ioe == null) ioe = new IOException(e.getCause());
ioe = new IOException(e.getCause());
}
} }
} }
} finally { } finally {
@ -652,6 +650,7 @@ public class HStore implements Store, HeapSize, StoreConfigInformation,
/** /**
* Replaces the store files that the store has with the given files. Mainly used by secondary * Replaces the store files that the store has with the given files. Mainly used by secondary
* region replicas to keep up to date with the primary region files. * region replicas to keep up to date with the primary region files.
* @throws IOException
*/ */
public void refreshStoreFiles(Collection<String> newFiles) throws IOException { public void refreshStoreFiles(Collection<String> newFiles) throws IOException {
List<StoreFileInfo> storeFiles = new ArrayList<>(newFiles.size()); List<StoreFileInfo> storeFiles = new ArrayList<>(newFiles.size());
@ -666,20 +665,15 @@ public class HStore implements Store, HeapSize, StoreConfigInformation,
* been opened, and removes the store file readers for store files no longer * been opened, and removes the store file readers for store files no longer
* available. Mainly used by secondary region replicas to keep up to date with * available. Mainly used by secondary region replicas to keep up to date with
* the primary region files. * the primary region files.
* @throws IOException
*/ */
private void refreshStoreFilesInternal(Collection<StoreFileInfo> newFiles) throws IOException { private void refreshStoreFilesInternal(Collection<StoreFileInfo> newFiles) throws IOException {
StoreFileManager sfm = storeEngine.getStoreFileManager(); StoreFileManager sfm = storeEngine.getStoreFileManager();
Collection<HStoreFile> currentFiles = sfm.getStorefiles(); Collection<HStoreFile> currentFiles = sfm.getStorefiles();
Collection<HStoreFile> compactedFiles = sfm.getCompactedfiles(); Collection<HStoreFile> compactedFiles = sfm.getCompactedfiles();
if (currentFiles == null) { if (currentFiles == null) currentFiles = Collections.emptySet();
currentFiles = Collections.emptySet(); if (newFiles == null) newFiles = Collections.emptySet();
} if (compactedFiles == null) compactedFiles = Collections.emptySet();
if (newFiles == null) {
newFiles = Collections.emptySet();
}
if (compactedFiles == null) {
compactedFiles = Collections.emptySet();
}
HashMap<StoreFileInfo, HStoreFile> currentFilesSet = new HashMap<>(currentFiles.size()); HashMap<StoreFileInfo, HStoreFile> currentFilesSet = new HashMap<>(currentFiles.size());
for (HStoreFile sf : currentFiles) { for (HStoreFile sf : currentFiles) {
@ -874,13 +868,12 @@ public class HStore implements Store, HeapSize, StoreConfigInformation,
} }
prevCell = cell; prevCell = cell;
} while (scanner.next()); } while (scanner.next());
LOG.info("Full verification complete for bulk load hfile: " + srcPath.toString() + LOG.info("Full verification complete for bulk load hfile: " + srcPath.toString()
" took " + (EnvironmentEdgeManager.currentTime() - verificationStartTime) + " ms"); + " took " + (EnvironmentEdgeManager.currentTime() - verificationStartTime)
+ " ms");
} }
} finally { } finally {
if (reader != null) { if (reader != null) reader.close();
reader.close();
}
} }
} }
@ -888,6 +881,7 @@ public class HStore implements Store, HeapSize, StoreConfigInformation,
* This method should only be called from Region. It is assumed that the ranges of values in the * This method should only be called from Region. It is assumed that the ranges of values in the
* HFile fit within the stores assigned region. (assertBulkLoadHFileOk checks this) * HFile fit within the stores assigned region. (assertBulkLoadHFileOk checks this)
* *
* @param srcPathStr
* @param seqNum sequence Id associated with the HFile * @param seqNum sequence Id associated with the HFile
*/ */
public Pair<Path, Path> preBulkLoadHFile(String srcPathStr, long seqNum) throws IOException { public Pair<Path, Path> preBulkLoadHFile(String srcPathStr, long seqNum) throws IOException {
@ -999,17 +993,13 @@ public class HStore implements Store, HeapSize, StoreConfigInformation,
ioe.initCause(e); ioe.initCause(e);
} }
} catch (ExecutionException e) { } catch (ExecutionException e) {
if (ioe == null) { if (ioe == null) ioe = new IOException(e.getCause());
ioe = new IOException(e.getCause());
}
} }
} }
} finally { } finally {
storeFileCloserThreadPool.shutdownNow(); storeFileCloserThreadPool.shutdownNow();
} }
if (ioe != null) { if (ioe != null) throw ioe;
throw ioe;
}
} }
LOG.trace("Closed {}", this); LOG.trace("Closed {}", this);
return result; return result;
@ -1037,6 +1027,9 @@ public class HStore implements Store, HeapSize, StoreConfigInformation,
/** /**
* Write out current snapshot. Presumes {@link #snapshot()} has been called previously. * Write out current snapshot. Presumes {@link #snapshot()} has been called previously.
* @param logCacheFlushId flush sequence number * @param logCacheFlushId flush sequence number
* @param snapshot
* @param status
* @param throughputController
* @return The path name of the tmp file to which the store was flushed * @return The path name of the tmp file to which the store was flushed
* @throws IOException if exception occurs during process * @throws IOException if exception occurs during process
*/ */
@ -1088,7 +1081,10 @@ public class HStore implements Store, HeapSize, StoreConfigInformation,
/** /**
* @param path The pathname of the tmp file into which the store was flushed * @param path The pathname of the tmp file into which the store was flushed
* @param logCacheFlushId
* @param status
* @return store file created. * @return store file created.
* @throws IOException
*/ */
private HStoreFile commitFile(Path path, long logCacheFlushId, MonitoredTask status) private HStoreFile commitFile(Path path, long logCacheFlushId, MonitoredTask status)
throws IOException { throws IOException {
@ -1111,6 +1107,7 @@ public class HStore implements Store, HeapSize, StoreConfigInformation,
} }
/** /**
* @param maxKeyCount
* @param compression Compression algorithm to use * @param compression Compression algorithm to use
* @param isCompaction whether we are creating a new file in a compaction * @param isCompaction whether we are creating a new file in a compaction
* @param includeMVCCReadpoint - whether to include MVCC or not * @param includeMVCCReadpoint - whether to include MVCC or not
@ -1165,6 +1162,7 @@ public class HStore implements Store, HeapSize, StoreConfigInformation,
StoreFileWriter.Builder builder = new StoreFileWriter.Builder(conf, writerCacheConf, StoreFileWriter.Builder builder = new StoreFileWriter.Builder(conf, writerCacheConf,
this.getFileSystem()) this.getFileSystem())
.withOutputDir(familyTempDir) .withOutputDir(familyTempDir)
.withComparator(comparator)
.withBloomType(family.getBloomFilterType()) .withBloomType(family.getBloomFilterType())
.withMaxKeyCount(maxKeyCount) .withMaxKeyCount(maxKeyCount)
.withFavoredNodes(favoredNodes) .withFavoredNodes(favoredNodes)
@ -1194,7 +1192,6 @@ public class HStore implements Store, HeapSize, StoreConfigInformation,
.withColumnFamily(family.getName()) .withColumnFamily(family.getName())
.withTableName(region.getTableDescriptor() .withTableName(region.getTableDescriptor()
.getTableName().getName()) .getTableName().getName())
.withCellComparator(this.comparator)
.build(); .build();
return hFileContext; return hFileContext;
} }
@ -1207,6 +1204,8 @@ public class HStore implements Store, HeapSize, StoreConfigInformation,
/** /**
* Change storeFiles adding into place the Reader produced by this new flush. * Change storeFiles adding into place the Reader produced by this new flush.
* @param sfs Store files * @param sfs Store files
* @param snapshotId
* @throws IOException
* @return Whether compaction is required. * @return Whether compaction is required.
*/ */
private boolean updateStorefiles(List<HStoreFile> sfs, long snapshotId) throws IOException { private boolean updateStorefiles(List<HStoreFile> sfs, long snapshotId) throws IOException {
@ -1238,6 +1237,7 @@ public class HStore implements Store, HeapSize, StoreConfigInformation,
/** /**
* Notify all observers that set of Readers has changed. * Notify all observers that set of Readers has changed.
* @throws IOException
*/ */
private void notifyChangedReadersObservers(List<HStoreFile> sfs) throws IOException { private void notifyChangedReadersObservers(List<HStoreFile> sfs) throws IOException {
for (ChangedReadersObserver o : this.changedReaderObservers) { for (ChangedReadersObserver o : this.changedReaderObservers) {
@ -1454,6 +1454,7 @@ public class HStore implements Store, HeapSize, StoreConfigInformation,
* See HBASE-2231 for details. * See HBASE-2231 for details.
* *
* @param compaction compaction details obtained from requestCompaction() * @param compaction compaction details obtained from requestCompaction()
* @throws IOException
* @return Storefile we compacted into or null if we failed or opted out early. * @return Storefile we compacted into or null if we failed or opted out early.
*/ */
public List<HStoreFile> compact(CompactionContext compaction, public List<HStoreFile> compact(CompactionContext compaction,
@ -1520,8 +1521,8 @@ public class HStore implements Store, HeapSize, StoreConfigInformation,
return sfs; return sfs;
} }
private List<HStoreFile> moveCompactedFilesIntoPlace(CompactionRequestImpl cr, private List<HStoreFile> moveCompactedFilesIntoPlace(CompactionRequestImpl cr, List<Path> newFiles,
List<Path> newFiles, User user) throws IOException { User user) throws IOException {
List<HStoreFile> sfs = new ArrayList<>(newFiles.size()); List<HStoreFile> sfs = new ArrayList<>(newFiles.size());
for (Path newFile : newFiles) { for (Path newFile : newFiles) {
assert newFile != null; assert newFile != null;
@ -1559,8 +1560,7 @@ public class HStore implements Store, HeapSize, StoreConfigInformation,
newFiles.stream().map(HStoreFile::getPath).collect(Collectors.toList()); newFiles.stream().map(HStoreFile::getPath).collect(Collectors.toList());
RegionInfo info = this.region.getRegionInfo(); RegionInfo info = this.region.getRegionInfo();
CompactionDescriptor compactionDescriptor = ProtobufUtil.toCompactionDescriptor(info, CompactionDescriptor compactionDescriptor = ProtobufUtil.toCompactionDescriptor(info,
family.getName(), inputPaths, outputPaths, family.getName(), inputPaths, outputPaths, fs.getStoreDir(getColumnFamilyDescriptor().getNameAsString()));
fs.getStoreDir(getColumnFamilyDescriptor().getNameAsString()));
// Fix reaching into Region to get the maxWaitForSeqId. // Fix reaching into Region to get the maxWaitForSeqId.
// Does this method belong in Region altogether given it is making so many references up there? // Does this method belong in Region altogether given it is making so many references up there?
// Could be Region#writeCompactionMarker(compactionDescriptor); // Could be Region#writeCompactionMarker(compactionDescriptor);
@ -1664,6 +1664,7 @@ public class HStore implements Store, HeapSize, StoreConfigInformation,
* Call to complete a compaction. Its for the case where we find in the WAL a compaction * Call to complete a compaction. Its for the case where we find in the WAL a compaction
* that was not finished. We could find one recovering a WAL after a regionserver crash. * that was not finished. We could find one recovering a WAL after a regionserver crash.
* See HBASE-2231. * See HBASE-2231.
* @param compaction
*/ */
public void replayCompactionMarker(CompactionDescriptor compaction, boolean pickCompactionFiles, public void replayCompactionMarker(CompactionDescriptor compaction, boolean pickCompactionFiles,
boolean removeFiles) throws IOException { boolean removeFiles) throws IOException {
@ -1916,9 +1917,7 @@ public class HStore implements Store, HeapSize, StoreConfigInformation,
} }
private void removeUnneededFiles() throws IOException { private void removeUnneededFiles() throws IOException {
if (!conf.getBoolean("hbase.store.delete.expired.storefile", true)) { if (!conf.getBoolean("hbase.store.delete.expired.storefile", true)) return;
return;
}
if (getColumnFamilyDescriptor().getMinVersions() > 0) { if (getColumnFamilyDescriptor().getMinVersions() > 0) {
LOG.debug("Skipping expired store file removal due to min version being {}", LOG.debug("Skipping expired store file removal due to min version being {}",
getColumnFamilyDescriptor().getMinVersions()); getColumnFamilyDescriptor().getMinVersions());
@ -2121,6 +2120,7 @@ public class HStore implements Store, HeapSize, StoreConfigInformation,
* @param readPt the read point of the current scane * @param readPt the read point of the current scane
* @param includeMemstoreScanner whether the current scanner should include memstorescanner * @param includeMemstoreScanner whether the current scanner should include memstorescanner
* @return list of scanners recreated on the current Scanners * @return list of scanners recreated on the current Scanners
* @throws IOException
*/ */
public List<KeyValueScanner> recreateScanners(List<KeyValueScanner> currentFileScanners, public List<KeyValueScanner> recreateScanners(List<KeyValueScanner> currentFileScanners,
boolean cacheBlocks, boolean usePread, boolean isCompaction, ScanQueryMatcher matcher, boolean cacheBlocks, boolean usePread, boolean isCompaction, ScanQueryMatcher matcher,
@ -2319,6 +2319,7 @@ public class HStore implements Store, HeapSize, StoreConfigInformation,
* This operation is atomic on each KeyValue (row/family/qualifier) but not necessarily atomic * This operation is atomic on each KeyValue (row/family/qualifier) but not necessarily atomic
* across all of them. * across all of them.
* @param readpoint readpoint below which we can safely remove duplicate KVs * @param readpoint readpoint below which we can safely remove duplicate KVs
* @throws IOException
*/ */
public void upsert(Iterable<Cell> cells, long readpoint, MemStoreSizing memstoreSizing) public void upsert(Iterable<Cell> cells, long readpoint, MemStoreSizing memstoreSizing)
throws IOException { throws IOException {
@ -2432,6 +2433,7 @@ public class HStore implements Store, HeapSize, StoreConfigInformation,
* snapshot depending on dropMemstoreSnapshot argument. * snapshot depending on dropMemstoreSnapshot argument.
* @param fileNames names of the flushed files * @param fileNames names of the flushed files
* @param dropMemstoreSnapshot whether to drop the prepared memstore snapshot * @param dropMemstoreSnapshot whether to drop the prepared memstore snapshot
* @throws IOException
*/ */
@Override @Override
public void replayFlush(List<String> fileNames, boolean dropMemstoreSnapshot) public void replayFlush(List<String> fileNames, boolean dropMemstoreSnapshot)
@ -2463,6 +2465,7 @@ public class HStore implements Store, HeapSize, StoreConfigInformation,
/** /**
* Abort the snapshot preparation. Drops the snapshot if any. * Abort the snapshot preparation. Drops the snapshot if any.
* @throws IOException
*/ */
@Override @Override
public void abort() throws IOException { public void abort() throws IOException {
@ -2717,8 +2720,7 @@ public class HStore implements Store, HeapSize, StoreConfigInformation,
LOG.debug("Moving the files {} to archive", filesToRemove); LOG.debug("Moving the files {} to archive", filesToRemove);
// Only if this is successful it has to be removed // Only if this is successful it has to be removed
try { try {
this.fs.removeStoreFiles(this.getColumnFamilyDescriptor().getNameAsString(), this.fs.removeStoreFiles(this.getColumnFamilyDescriptor().getNameAsString(), filesToRemove);
filesToRemove);
} catch (FailedArchiveException fae) { } catch (FailedArchiveException fae) {
// Even if archiving some files failed, we still need to clear out any of the // Even if archiving some files failed, we still need to clear out any of the
// files which were successfully archived. Otherwise we will receive a // files which were successfully archived. Otherwise we will receive a

View File

@ -26,6 +26,7 @@ import static org.apache.hadoop.hbase.regionserver.HStoreFile.MAJOR_COMPACTION_K
import static org.apache.hadoop.hbase.regionserver.HStoreFile.MAX_SEQ_ID_KEY; import static org.apache.hadoop.hbase.regionserver.HStoreFile.MAX_SEQ_ID_KEY;
import static org.apache.hadoop.hbase.regionserver.HStoreFile.MOB_CELLS_COUNT; import static org.apache.hadoop.hbase.regionserver.HStoreFile.MOB_CELLS_COUNT;
import static org.apache.hadoop.hbase.regionserver.HStoreFile.TIMERANGE_KEY; import static org.apache.hadoop.hbase.regionserver.HStoreFile.TIMERANGE_KEY;
import java.io.IOException; import java.io.IOException;
import java.net.InetSocketAddress; import java.net.InetSocketAddress;
import java.util.Collection; import java.util.Collection;
@ -36,13 +37,15 @@ import java.util.UUID;
import java.util.function.Supplier; import java.util.function.Supplier;
import java.util.regex.Pattern; import java.util.regex.Pattern;
import java.util.stream.Collectors; import java.util.stream.Collectors;
import org.apache.hadoop.conf.Configuration; import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.FileSystem; import org.apache.hadoop.fs.FileSystem;
import org.apache.hadoop.fs.Path; import org.apache.hadoop.fs.Path;
import org.apache.hadoop.hbase.Cell; import org.apache.hadoop.hbase.Cell;
import org.apache.hadoop.hbase.CellComparator;
import org.apache.hadoop.hbase.HConstants; import org.apache.hadoop.hbase.HConstants;
import org.apache.hadoop.hbase.KeyValue;
import org.apache.hadoop.hbase.PrivateCellUtil; import org.apache.hadoop.hbase.PrivateCellUtil;
import org.apache.hadoop.hbase.KeyValue;
import org.apache.hadoop.hbase.client.ColumnFamilyDescriptorBuilder; import org.apache.hadoop.hbase.client.ColumnFamilyDescriptorBuilder;
import org.apache.hadoop.hbase.io.hfile.CacheConfig; import org.apache.hadoop.hbase.io.hfile.CacheConfig;
import org.apache.hadoop.hbase.io.hfile.HFile; import org.apache.hadoop.hbase.io.hfile.HFile;
@ -59,7 +62,9 @@ import org.apache.hadoop.hbase.util.RowPrefixFixedLengthBloomContext;
import org.apache.yetus.audience.InterfaceAudience; import org.apache.yetus.audience.InterfaceAudience;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import org.apache.hbase.thirdparty.com.google.common.base.Preconditions; import org.apache.hbase.thirdparty.com.google.common.base.Preconditions;
import org.apache.hadoop.hbase.shaded.protobuf.ProtobufUtil; import org.apache.hadoop.hbase.shaded.protobuf.ProtobufUtil;
/** /**
@ -89,6 +94,7 @@ public class StoreFileWriter implements CellSink, ShipperListener {
* @param fs file system to write to * @param fs file system to write to
* @param path file name to create * @param path file name to create
* @param conf user configuration * @param conf user configuration
* @param comparator key comparator
* @param bloomType bloom filter setting * @param bloomType bloom filter setting
* @param maxKeys the expected maximum number of keys to be added. Was used * @param maxKeys the expected maximum number of keys to be added. Was used
* for Bloom filter size in {@link HFile} format version 1. * for Bloom filter size in {@link HFile} format version 1.
@ -99,14 +105,15 @@ public class StoreFileWriter implements CellSink, ShipperListener {
* @throws IOException problem writing to FS * @throws IOException problem writing to FS
*/ */
private StoreFileWriter(FileSystem fs, Path path, final Configuration conf, CacheConfig cacheConf, private StoreFileWriter(FileSystem fs, Path path, final Configuration conf, CacheConfig cacheConf,
BloomType bloomType, long maxKeys, InetSocketAddress[] favoredNodes, HFileContext fileContext, final CellComparator comparator, BloomType bloomType, long maxKeys,
boolean shouldDropCacheBehind, Supplier<Collection<HStoreFile>> compactedFilesSupplier) InetSocketAddress[] favoredNodes, HFileContext fileContext, boolean shouldDropCacheBehind,
throws IOException { Supplier<Collection<HStoreFile>> compactedFilesSupplier) throws IOException {
this.compactedFilesSupplier = compactedFilesSupplier; this.compactedFilesSupplier = compactedFilesSupplier;
this.timeRangeTracker = TimeRangeTracker.create(TimeRangeTracker.Type.NON_SYNC); this.timeRangeTracker = TimeRangeTracker.create(TimeRangeTracker.Type.NON_SYNC);
// TODO : Change all writers to be specifically created for compaction context // TODO : Change all writers to be specifically created for compaction context
writer = HFile.getWriterFactory(conf, cacheConf) writer = HFile.getWriterFactory(conf, cacheConf)
.withPath(fs, path) .withPath(fs, path)
.withComparator(comparator)
.withFavoredNodes(favoredNodes) .withFavoredNodes(favoredNodes)
.withFileContext(fileContext) .withFileContext(fileContext)
.withShouldDropCacheBehind(shouldDropCacheBehind) .withShouldDropCacheBehind(shouldDropCacheBehind)
@ -128,16 +135,14 @@ public class StoreFileWriter implements CellSink, ShipperListener {
// init bloom context // init bloom context
switch (bloomType) { switch (bloomType) {
case ROW: case ROW:
bloomContext = bloomContext = new RowBloomContext(generalBloomFilterWriter, comparator);
new RowBloomContext(generalBloomFilterWriter, fileContext.getCellComparator());
break; break;
case ROWCOL: case ROWCOL:
bloomContext = bloomContext = new RowColBloomContext(generalBloomFilterWriter, comparator);
new RowColBloomContext(generalBloomFilterWriter, fileContext.getCellComparator());
break; break;
case ROWPREFIX_FIXED_LENGTH: case ROWPREFIX_FIXED_LENGTH:
bloomContext = new RowPrefixFixedLengthBloomContext(generalBloomFilterWriter, bloomContext = new RowPrefixFixedLengthBloomContext(generalBloomFilterWriter, comparator,
fileContext.getCellComparator(), Bytes.toInt(bloomParam)); Bytes.toInt(bloomParam));
break; break;
default: default:
throw new IOException( throw new IOException(
@ -154,8 +159,7 @@ public class StoreFileWriter implements CellSink, ShipperListener {
this.deleteFamilyBloomFilterWriter = BloomFilterFactory this.deleteFamilyBloomFilterWriter = BloomFilterFactory
.createDeleteBloomAtWrite(conf, cacheConf, .createDeleteBloomAtWrite(conf, cacheConf,
(int) Math.min(maxKeys, Integer.MAX_VALUE), writer); (int) Math.min(maxKeys, Integer.MAX_VALUE), writer);
deleteFamilyBloomContext = deleteFamilyBloomContext = new RowBloomContext(deleteFamilyBloomFilterWriter, comparator);
new RowBloomContext(deleteFamilyBloomFilterWriter, fileContext.getCellComparator());
} else { } else {
deleteFamilyBloomFilterWriter = null; deleteFamilyBloomFilterWriter = null;
} }
@ -392,6 +396,7 @@ public class StoreFileWriter implements CellSink, ShipperListener {
} }
/** /**
* @param fs
* @param dir Directory to create file in. * @param dir Directory to create file in.
* @return random filename inside passed <code>dir</code> * @return random filename inside passed <code>dir</code>
*/ */
@ -409,6 +414,7 @@ public class StoreFileWriter implements CellSink, ShipperListener {
private final CacheConfig cacheConf; private final CacheConfig cacheConf;
private final FileSystem fs; private final FileSystem fs;
private CellComparator comparator = CellComparator.getInstance();
private BloomType bloomType = BloomType.NONE; private BloomType bloomType = BloomType.NONE;
private long maxKeyCount = 0; private long maxKeyCount = 0;
private Path dir; private Path dir;
@ -467,6 +473,12 @@ public class StoreFileWriter implements CellSink, ShipperListener {
return this; return this;
} }
public Builder withComparator(CellComparator comparator) {
Preconditions.checkNotNull(comparator);
this.comparator = comparator;
return this;
}
public Builder withBloomType(BloomType bloomType) { public Builder withBloomType(BloomType bloomType) {
Preconditions.checkNotNull(bloomType); Preconditions.checkNotNull(bloomType);
this.bloomType = bloomType; this.bloomType = bloomType;
@ -533,7 +545,11 @@ public class StoreFileWriter implements CellSink, ShipperListener {
} }
} }
return new StoreFileWriter(fs, filePath, conf, cacheConf, bloomType, maxKeyCount, if (comparator == null) {
comparator = CellComparator.getInstance();
}
return new StoreFileWriter(fs, filePath, conf, cacheConf, comparator, bloomType, maxKeyCount,
favoredNodes, fileContext, shouldDropCacheBehind, compactedFilesSupplier); favoredNodes, fileContext, shouldDropCacheBehind, compactedFilesSupplier);
} }
} }

View File

@ -18,6 +18,7 @@
package org.apache.hadoop.hbase.wal; package org.apache.hadoop.hbase.wal;
import static org.apache.hadoop.hbase.TableName.META_TABLE_NAME; import static org.apache.hadoop.hbase.TableName.META_TABLE_NAME;
import java.io.IOException; import java.io.IOException;
import java.io.InterruptedIOException; import java.io.InterruptedIOException;
import java.util.HashMap; import java.util.HashMap;
@ -28,6 +29,7 @@ import java.util.concurrent.ConcurrentMap;
import java.util.concurrent.ExecutionException; import java.util.concurrent.ExecutionException;
import java.util.concurrent.Future; import java.util.concurrent.Future;
import java.util.concurrent.atomic.AtomicInteger; import java.util.concurrent.atomic.AtomicInteger;
import org.apache.commons.io.IOUtils; import org.apache.commons.io.IOUtils;
import org.apache.hadoop.fs.FileSystem; import org.apache.hadoop.fs.FileSystem;
import org.apache.hadoop.fs.Path; import org.apache.hadoop.fs.Path;
@ -206,7 +208,7 @@ public class BoundedRecoveredHFilesOutputSink extends OutputSink {
.withFilePath(outputFile); .withFilePath(outputFile);
HFileContextBuilder hFileContextBuilder = new HFileContextBuilder(); HFileContextBuilder hFileContextBuilder = new HFileContextBuilder();
if (isMetaTable) { if (isMetaTable) {
hFileContextBuilder.withCellComparator(CellComparatorImpl.META_COMPARATOR); writerBuilder.withComparator(CellComparatorImpl.META_COMPARATOR);
} else { } else {
configContextForNonMetaWriter(tableName, familyName, hFileContextBuilder, writerBuilder); configContextForNonMetaWriter(tableName, familyName, hFileContextBuilder, writerBuilder);
} }
@ -222,9 +224,9 @@ public class BoundedRecoveredHFilesOutputSink extends OutputSink {
TableDescriptor tableDesc = tableDescCache.get(tableName); TableDescriptor tableDesc = tableDescCache.get(tableName);
ColumnFamilyDescriptor cfd = tableDesc.getColumnFamily(Bytes.toBytesBinary(familyName)); ColumnFamilyDescriptor cfd = tableDesc.getColumnFamily(Bytes.toBytesBinary(familyName));
hFileContextBuilder.withCompression(cfd.getCompressionType()).withBlockSize(cfd.getBlocksize()) hFileContextBuilder.withCompression(cfd.getCompressionType()).withBlockSize(cfd.getBlocksize())
.withCompressTags(cfd.isCompressTags()).withDataBlockEncoding(cfd.getDataBlockEncoding()) .withCompressTags(cfd.isCompressTags()).withDataBlockEncoding(cfd.getDataBlockEncoding());
.withCellComparator(CellComparatorImpl.COMPARATOR); writerBuilder.withBloomType(cfd.getBloomFilterType())
writerBuilder.withBloomType(cfd.getBloomFilterType()); .withComparator(CellComparatorImpl.COMPARATOR);
} }
private void checkPathValid(Path outputFile) throws IOException { private void checkPathValid(Path outputFile) throws IOException {

View File

@ -366,6 +366,7 @@ public class HFilePerformanceEvaluation {
writer = HFile.getWriterFactoryNoCache(conf) writer = HFile.getWriterFactoryNoCache(conf)
.withPath(fs, mf) .withPath(fs, mf)
.withFileContext(hFileContext) .withFileContext(hFileContext)
.withComparator(CellComparator.getInstance())
.create(); .create();
} }

View File

@ -1,4 +1,4 @@
/* /**
* Licensed to the Apache Software Foundation (ASF) under one * Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file * or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information * distributed with this work for additional information
@ -206,8 +206,8 @@ public class TestDataBlockEncoders {
.withIncludesTags(includesTags) .withIncludesTags(includesTags)
.withCompression(Compression.Algorithm.NONE) .withCompression(Compression.Algorithm.NONE)
.build(); .build();
DataBlockEncoder.EncodedSeeker seeker = DataBlockEncoder.EncodedSeeker seeker = encoder.createSeeker(CellComparatorImpl.COMPARATOR,
encoder.createSeeker(encoder.newDataBlockDecodingContext(meta)); encoder.newDataBlockDecodingContext(meta));
seeker.setCurrentBuffer(new SingleByteBuff(encodedBuffer)); seeker.setCurrentBuffer(new SingleByteBuff(encodedBuffer));
encodedSeekers.add(seeker); encodedSeekers.add(seeker);
} }
@ -279,8 +279,8 @@ public class TestDataBlockEncoders {
.withIncludesTags(includesTags) .withIncludesTags(includesTags)
.withCompression(Compression.Algorithm.NONE) .withCompression(Compression.Algorithm.NONE)
.build(); .build();
DataBlockEncoder.EncodedSeeker seeker = DataBlockEncoder.EncodedSeeker seeker = encoder.createSeeker(CellComparatorImpl.COMPARATOR,
encoder.createSeeker(encoder.newDataBlockDecodingContext(meta)); encoder.newDataBlockDecodingContext(meta));
seeker.setCurrentBuffer(new SingleByteBuff(encodedBuffer)); seeker.setCurrentBuffer(new SingleByteBuff(encodedBuffer));
int i = 0; int i = 0;
do { do {
@ -341,8 +341,8 @@ public class TestDataBlockEncoders {
HFileContext meta = HFileContext meta =
new HFileContextBuilder().withHBaseCheckSum(false).withIncludesMvcc(includesMemstoreTS) new HFileContextBuilder().withHBaseCheckSum(false).withIncludesMvcc(includesMemstoreTS)
.withIncludesTags(includesTags).withCompression(Compression.Algorithm.NONE).build(); .withIncludesTags(includesTags).withCompression(Compression.Algorithm.NONE).build();
DataBlockEncoder.EncodedSeeker seeker = DataBlockEncoder.EncodedSeeker seeker = encoder.createSeeker(CellComparatorImpl.COMPARATOR,
encoder.createSeeker(encoder.newDataBlockDecodingContext(meta)); encoder.newDataBlockDecodingContext(meta));
seeker.setCurrentBuffer(new SingleByteBuff(encodedBuffer)); seeker.setCurrentBuffer(new SingleByteBuff(encodedBuffer));
Cell cell = seeker.getCell(); Cell cell = seeker.getCell();
Assert.assertEquals(expectedKV.getLength(), ((KeyValue) cell).getLength()); Assert.assertEquals(expectedKV.getLength(), ((KeyValue) cell).getLength());

View File

@ -25,6 +25,7 @@ import java.util.ArrayList;
import java.util.Collection; import java.util.Collection;
import java.util.List; import java.util.List;
import org.apache.hadoop.hbase.Cell; import org.apache.hadoop.hbase.Cell;
import org.apache.hadoop.hbase.CellComparatorImpl;
import org.apache.hadoop.hbase.HBaseClassTestRule; import org.apache.hadoop.hbase.HBaseClassTestRule;
import org.apache.hadoop.hbase.HBaseCommonTestingUtility; import org.apache.hadoop.hbase.HBaseCommonTestingUtility;
import org.apache.hadoop.hbase.HConstants; import org.apache.hadoop.hbase.HConstants;
@ -289,8 +290,8 @@ public class TestSeekToBlockWithEncoders {
HFILEBLOCK_DUMMY_HEADER, meta); HFILEBLOCK_DUMMY_HEADER, meta);
ByteBuffer encodedBuffer = TestDataBlockEncoders.encodeKeyValues(encoding, kvs, ByteBuffer encodedBuffer = TestDataBlockEncoders.encodeKeyValues(encoding, kvs,
encodingContext, this.useOffheapData); encodingContext, this.useOffheapData);
DataBlockEncoder.EncodedSeeker seeker = DataBlockEncoder.EncodedSeeker seeker = encoder.createSeeker(CellComparatorImpl.COMPARATOR,
encoder.createSeeker(encoder.newDataBlockDecodingContext(meta)); encoder.newDataBlockDecodingContext(meta));
seeker.setCurrentBuffer(new SingleByteBuff(encodedBuffer)); seeker.setCurrentBuffer(new SingleByteBuff(encodedBuffer));
encodedSeekers.add(seeker); encodedSeekers.add(seeker);
} }

View File

@ -37,6 +37,7 @@ import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.FileSystem; import org.apache.hadoop.fs.FileSystem;
import org.apache.hadoop.fs.Path; import org.apache.hadoop.fs.Path;
import org.apache.hadoop.hbase.ArrayBackedTag; import org.apache.hadoop.hbase.ArrayBackedTag;
import org.apache.hadoop.hbase.CellComparatorImpl;
import org.apache.hadoop.hbase.HBaseClassTestRule; import org.apache.hadoop.hbase.HBaseClassTestRule;
import org.apache.hadoop.hbase.HBaseCommonTestingUtility; import org.apache.hadoop.hbase.HBaseCommonTestingUtility;
import org.apache.hadoop.hbase.HBaseTestingUtility; import org.apache.hadoop.hbase.HBaseTestingUtility;
@ -393,7 +394,7 @@ public class TestCacheOnWrite {
.withDataBlockEncoding(NoOpDataBlockEncoder.INSTANCE.getDataBlockEncoding()) .withDataBlockEncoding(NoOpDataBlockEncoder.INSTANCE.getDataBlockEncoding())
.withIncludesTags(useTags).build(); .withIncludesTags(useTags).build();
StoreFileWriter sfw = new StoreFileWriter.Builder(conf, cacheConf, fs) StoreFileWriter sfw = new StoreFileWriter.Builder(conf, cacheConf, fs)
.withOutputDir(storeFileParentDir) .withOutputDir(storeFileParentDir).withComparator(CellComparatorImpl.COMPARATOR)
.withFileContext(meta) .withFileContext(meta)
.withBloomType(BLOOM_TYPE).withMaxKeyCount(NUM_KV).build(); .withBloomType(BLOOM_TYPE).withMaxKeyCount(NUM_KV).build();
byte[] cf = Bytes.toBytes("fam"); byte[] cf = Bytes.toBytes("fam");

View File

@ -131,10 +131,6 @@ public class TestFixedFileTrailer {
t.createComparator(KeyValue.META_COMPARATOR.getClass().getName()).getClass()); t.createComparator(KeyValue.META_COMPARATOR.getClass().getName()).getClass());
assertEquals(CellComparatorImpl.MetaCellComparator.class, t.createComparator( assertEquals(CellComparatorImpl.MetaCellComparator.class, t.createComparator(
CellComparatorImpl.MetaCellComparator.META_COMPARATOR.getClass().getName()).getClass()); CellComparatorImpl.MetaCellComparator.META_COMPARATOR.getClass().getName()).getClass());
assertEquals(CellComparatorImpl.META_COMPARATOR.getClass(), t.createComparator(
CellComparatorImpl.MetaCellComparator.META_COMPARATOR.getClass().getName()).getClass());
assertEquals(CellComparatorImpl.COMPARATOR.getClass(), t.createComparator(
CellComparatorImpl.MetaCellComparator.COMPARATOR.getClass().getName()).getClass());
assertNull(t.createComparator(Bytes.BYTES_RAWCOMPARATOR.getClass().getName())); assertNull(t.createComparator(Bytes.BYTES_RAWCOMPARATOR.getClass().getName()));
assertNull(t.createComparator("org.apache.hadoop.hbase.KeyValue$RawBytesComparator")); assertNull(t.createComparator("org.apache.hadoop.hbase.KeyValue$RawBytesComparator"));
} catch (IOException e) { } catch (IOException e) {

View File

@ -50,6 +50,7 @@ import org.apache.hadoop.hbase.Cell;
import org.apache.hadoop.hbase.CellBuilder; import org.apache.hadoop.hbase.CellBuilder;
import org.apache.hadoop.hbase.CellBuilderFactory; import org.apache.hadoop.hbase.CellBuilderFactory;
import org.apache.hadoop.hbase.CellBuilderType; import org.apache.hadoop.hbase.CellBuilderType;
import org.apache.hadoop.hbase.CellComparator;
import org.apache.hadoop.hbase.CellComparatorImpl; import org.apache.hadoop.hbase.CellComparatorImpl;
import org.apache.hadoop.hbase.CellUtil; import org.apache.hadoop.hbase.CellUtil;
import org.apache.hadoop.hbase.HBaseClassTestRule; import org.apache.hadoop.hbase.HBaseClassTestRule;
@ -275,7 +276,7 @@ public class TestHFile {
HFileContext meta = new HFileContextBuilder().withBlockSize(64 * 1024).build(); HFileContext meta = new HFileContextBuilder().withBlockSize(64 * 1024).build();
StoreFileWriter sfw = StoreFileWriter sfw =
new StoreFileWriter.Builder(conf, fs).withOutputDir(storeFileParentDir) new StoreFileWriter.Builder(conf, fs).withOutputDir(storeFileParentDir)
.withFileContext(meta).build(); .withComparator(CellComparatorImpl.COMPARATOR).withFileContext(meta).build();
final int rowLen = 32; final int rowLen = 32;
Random RNG = new Random(); Random RNG = new Random();
@ -358,7 +359,7 @@ public class TestHFile {
.withCompressTags(false) .withCompressTags(false)
.build(); .build();
HFileWriterImpl writer = new HFileWriterImpl(conf, cacheConf, path, mockedOutputStream, HFileWriterImpl writer = new HFileWriterImpl(conf, cacheConf, path, mockedOutputStream,
fileContext); CellComparator.getInstance(), fileContext);
CellBuilder cellBuilder = CellBuilderFactory.create(CellBuilderType.SHALLOW_COPY); CellBuilder cellBuilder = CellBuilderFactory.create(CellBuilderType.SHALLOW_COPY);
byte[] row = Bytes.toBytes("foo"); byte[] row = Bytes.toBytes("foo");
byte[] qualifier = Bytes.toBytes("qualifier"); byte[] qualifier = Bytes.toBytes("qualifier");
@ -514,6 +515,7 @@ public class TestHFile {
Writer writer = HFile.getWriterFactory(conf, cacheConf) Writer writer = HFile.getWriterFactory(conf, cacheConf)
.withOutputStream(fout) .withOutputStream(fout)
.withFileContext(meta) .withFileContext(meta)
.withComparator(CellComparatorImpl.COMPARATOR)
.create(); .create();
LOG.info(Objects.toString(writer)); LOG.info(Objects.toString(writer));
writeRecords(writer, useTags); writeRecords(writer, useTags);

View File

@ -24,6 +24,7 @@ import org.apache.hadoop.fs.FSDataOutputStream;
import org.apache.hadoop.fs.FileSystem; import org.apache.hadoop.fs.FileSystem;
import org.apache.hadoop.fs.Path; import org.apache.hadoop.fs.Path;
import org.apache.hadoop.hbase.Cell; import org.apache.hadoop.hbase.Cell;
import org.apache.hadoop.hbase.CellComparatorImpl;
import org.apache.hadoop.hbase.HBaseClassTestRule; import org.apache.hadoop.hbase.HBaseClassTestRule;
import org.apache.hadoop.hbase.HBaseTestingUtility; import org.apache.hadoop.hbase.HBaseTestingUtility;
import org.apache.hadoop.hbase.KeyValue; import org.apache.hadoop.hbase.KeyValue;
@ -65,8 +66,9 @@ public class TestHFileReaderImpl {
HFileContext context = HFileContext context =
new HFileContextBuilder().withBlockSize(blocksize).withIncludesTags(true).build(); new HFileContextBuilder().withBlockSize(blocksize).withIncludesTags(true).build();
Configuration conf = TEST_UTIL.getConfiguration(); Configuration conf = TEST_UTIL.getConfiguration();
HFile.Writer writer = HFile.getWriterFactoryNoCache(conf) HFile.Writer writer =
.withOutputStream(fout).withFileContext(context).create(); HFile.getWriterFactoryNoCache(conf).withOutputStream(fout).withFileContext(context)
.withComparator(CellComparatorImpl.COMPARATOR).create();
// 4 bytes * 3 * 2 for each key/value + // 4 bytes * 3 * 2 for each key/value +
// 3 for keys, 15 for values = 42 (woot) // 3 for keys, 15 for values = 42 (woot)
writer.append(toKV("c")); writer.append(toKV("c"));

View File

@ -37,6 +37,7 @@ import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.FileSystem; import org.apache.hadoop.fs.FileSystem;
import org.apache.hadoop.fs.Path; import org.apache.hadoop.fs.Path;
import org.apache.hadoop.hbase.Cell; import org.apache.hadoop.hbase.Cell;
import org.apache.hadoop.hbase.CellComparatorImpl;
import org.apache.hadoop.hbase.HBaseClassTestRule; import org.apache.hadoop.hbase.HBaseClassTestRule;
import org.apache.hadoop.hbase.HBaseTestingUtility; import org.apache.hadoop.hbase.HBaseTestingUtility;
import org.apache.hadoop.hbase.HConstants; import org.apache.hadoop.hbase.HConstants;
@ -164,7 +165,7 @@ public class TestHFileScannerImplReferenceCount {
.withCompression(compression).withDataBlockEncoding(encoding).build(); .withCompression(compression).withDataBlockEncoding(encoding).build();
try (HFile.Writer writer = try (HFile.Writer writer =
new HFile.WriterFactory(conf, new CacheConfig(conf)).withPath(fs, hfilePath) new HFile.WriterFactory(conf, new CacheConfig(conf)).withPath(fs, hfilePath)
.withFileContext(context).create()) { .withFileContext(context).withComparator(CellComparatorImpl.COMPARATOR).create()) {
Random rand = new Random(9713312); // Just a fixed seed. Random rand = new Random(9713312); // Just a fixed seed.
for (int i = 0; i < cellCount; ++i) { for (int i = 0; i < cellCount; ++i) {
byte[] keyBytes = Bytes.add(Bytes.toBytes(i), SUFFIX); byte[] keyBytes = Bytes.add(Bytes.toBytes(i), SUFFIX);

View File

@ -27,6 +27,7 @@ import org.apache.hadoop.fs.FSDataOutputStream;
import org.apache.hadoop.fs.FileSystem; import org.apache.hadoop.fs.FileSystem;
import org.apache.hadoop.fs.Path; import org.apache.hadoop.fs.Path;
import org.apache.hadoop.fs.RawLocalFileSystem; import org.apache.hadoop.fs.RawLocalFileSystem;
import org.apache.hadoop.hbase.CellComparatorImpl;
import org.apache.hadoop.hbase.HBaseClassTestRule; import org.apache.hadoop.hbase.HBaseClassTestRule;
import org.apache.hadoop.hbase.HBaseTestingUtility; import org.apache.hadoop.hbase.HBaseTestingUtility;
import org.apache.hadoop.hbase.KeyValue; import org.apache.hadoop.hbase.KeyValue;
@ -140,6 +141,7 @@ public class TestHFileSeek extends TestCase {
Writer writer = HFile.getWriterFactoryNoCache(conf) Writer writer = HFile.getWriterFactoryNoCache(conf)
.withOutputStream(fout) .withOutputStream(fout)
.withFileContext(context) .withFileContext(context)
.withComparator(CellComparatorImpl.COMPARATOR)
.create(); .create();
try { try {
BytesWritable key = new BytesWritable(); BytesWritable key = new BytesWritable();

View File

@ -36,6 +36,7 @@ import org.apache.hadoop.fs.Path;
import org.apache.hadoop.hbase.ArrayBackedTag; import org.apache.hadoop.hbase.ArrayBackedTag;
import org.apache.hadoop.hbase.Cell; import org.apache.hadoop.hbase.Cell;
import org.apache.hadoop.hbase.CellComparator; import org.apache.hadoop.hbase.CellComparator;
import org.apache.hadoop.hbase.CellComparatorImpl;
import org.apache.hadoop.hbase.HBaseClassTestRule; import org.apache.hadoop.hbase.HBaseClassTestRule;
import org.apache.hadoop.hbase.HBaseCommonTestingUtility; import org.apache.hadoop.hbase.HBaseCommonTestingUtility;
import org.apache.hadoop.hbase.HBaseTestingUtility; import org.apache.hadoop.hbase.HBaseTestingUtility;
@ -131,6 +132,7 @@ public class TestHFileWriterV3 {
HFile.Writer writer = new HFile.WriterFactory(conf, cacheConfig) HFile.Writer writer = new HFile.WriterFactory(conf, cacheConfig)
.withPath(fs, hfilePath) .withPath(fs, hfilePath)
.withFileContext(context) .withFileContext(context)
.withComparator(CellComparatorImpl.COMPARATOR)
.create(); .create();
Random rand = new Random(9713312); // Just a fixed seed. Random rand = new Random(9713312); // Just a fixed seed.

View File

@ -26,6 +26,7 @@ import java.util.Random;
import org.apache.hadoop.conf.Configuration; import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.FileSystem; import org.apache.hadoop.fs.FileSystem;
import org.apache.hadoop.fs.Path; import org.apache.hadoop.fs.Path;
import org.apache.hadoop.hbase.CellComparatorImpl;
import org.apache.hadoop.hbase.HBaseClassTestRule; import org.apache.hadoop.hbase.HBaseClassTestRule;
import org.apache.hadoop.hbase.HBaseConfiguration; import org.apache.hadoop.hbase.HBaseConfiguration;
import org.apache.hadoop.hbase.HBaseTestingUtility; import org.apache.hadoop.hbase.HBaseTestingUtility;
@ -144,6 +145,7 @@ public class TestPrefetch {
.build(); .build();
StoreFileWriter sfw = new StoreFileWriter.Builder(conf, cacheConf, fs) StoreFileWriter sfw = new StoreFileWriter.Builder(conf, cacheConf, fs)
.withOutputDir(storeFileParentDir) .withOutputDir(storeFileParentDir)
.withComparator(CellComparatorImpl.COMPARATOR)
.withFileContext(meta) .withFileContext(meta)
.build(); .build();

View File

@ -25,6 +25,7 @@ import java.util.List;
import org.apache.hadoop.fs.FSDataOutputStream; import org.apache.hadoop.fs.FSDataOutputStream;
import org.apache.hadoop.fs.Path; import org.apache.hadoop.fs.Path;
import org.apache.hadoop.hbase.ArrayBackedTag; import org.apache.hadoop.hbase.ArrayBackedTag;
import org.apache.hadoop.hbase.CellComparatorImpl;
import org.apache.hadoop.hbase.HBaseClassTestRule; import org.apache.hadoop.hbase.HBaseClassTestRule;
import org.apache.hadoop.hbase.HBaseTestingUtility; import org.apache.hadoop.hbase.HBaseTestingUtility;
import org.apache.hadoop.hbase.HConstants; import org.apache.hadoop.hbase.HConstants;
@ -68,6 +69,8 @@ public class TestReseekTo {
TEST_UTIL.getConfiguration(), cacheConf) TEST_UTIL.getConfiguration(), cacheConf)
.withOutputStream(fout) .withOutputStream(fout)
.withFileContext(context) .withFileContext(context)
// NOTE: This test is dependent on this deprecated nonstandard comparator
.withComparator(CellComparatorImpl.COMPARATOR)
.create(); .create();
int numberOfKeys = 1000; int numberOfKeys = 1000;

View File

@ -33,6 +33,7 @@ import org.apache.hadoop.fs.Path;
import org.apache.hadoop.hbase.ArrayBackedTag; import org.apache.hadoop.hbase.ArrayBackedTag;
import org.apache.hadoop.hbase.ByteBufferKeyValue; import org.apache.hadoop.hbase.ByteBufferKeyValue;
import org.apache.hadoop.hbase.Cell; import org.apache.hadoop.hbase.Cell;
import org.apache.hadoop.hbase.CellComparatorImpl;
import org.apache.hadoop.hbase.HBaseClassTestRule; import org.apache.hadoop.hbase.HBaseClassTestRule;
import org.apache.hadoop.hbase.HBaseTestingUtility; import org.apache.hadoop.hbase.HBaseTestingUtility;
import org.apache.hadoop.hbase.HConstants; import org.apache.hadoop.hbase.HConstants;
@ -122,7 +123,8 @@ public class TestSeekTo {
.withIncludesTags(true).build(); .withIncludesTags(true).build();
Configuration conf = TEST_UTIL.getConfiguration(); Configuration conf = TEST_UTIL.getConfiguration();
HFile.Writer writer = HFile.getWriterFactoryNoCache(conf).withOutputStream(fout) HFile.Writer writer = HFile.getWriterFactoryNoCache(conf).withOutputStream(fout)
.withFileContext(context).create(); .withFileContext(context)
.withComparator(CellComparatorImpl.COMPARATOR).create();
// 4 bytes * 3 * 2 for each key/value + // 4 bytes * 3 * 2 for each key/value +
// 3 for keys, 15 for values = 42 (woot) // 3 for keys, 15 for values = 42 (woot)
writer.append(toKV("c", tagUsage)); writer.append(toKV("c", tagUsage));

View File

@ -23,7 +23,7 @@ import org.apache.hadoop.hbase.client.Admin;
import org.apache.hadoop.hbase.client.ColumnFamilyDescriptorBuilder; import org.apache.hadoop.hbase.client.ColumnFamilyDescriptorBuilder;
import org.apache.hadoop.hbase.client.RegionInfo; import org.apache.hadoop.hbase.client.RegionInfo;
import org.apache.hadoop.hbase.client.TableDescriptorBuilder; import org.apache.hadoop.hbase.client.TableDescriptorBuilder;
import org.apache.hadoop.hbase.io.hfile.HFileContextBuilder; import org.apache.hadoop.hbase.io.hfile.HFileContext;
import org.apache.hadoop.hbase.master.MasterFileSystem; import org.apache.hadoop.hbase.master.MasterFileSystem;
import org.apache.hadoop.hbase.regionserver.StoreFileWriter; import org.apache.hadoop.hbase.regionserver.StoreFileWriter;
import org.apache.hadoop.hbase.testclassification.MasterTests; import org.apache.hadoop.hbase.testclassification.MasterTests;
@ -84,7 +84,7 @@ public class TestIgnoreUnknownFamily {
Path familyDir = new Path(regionDir, Bytes.toString(UNKNOWN_FAMILY)); Path familyDir = new Path(regionDir, Bytes.toString(UNKNOWN_FAMILY));
StoreFileWriter writer = StoreFileWriter writer =
new StoreFileWriter.Builder(mfs.getConfiguration(), mfs.getFileSystem()) new StoreFileWriter.Builder(mfs.getConfiguration(), mfs.getFileSystem())
.withOutputDir(familyDir).withFileContext(new HFileContextBuilder().build()).build(); .withOutputDir(familyDir).withFileContext(new HFileContext()).build();
writer.close(); writer.close();
} }

View File

@ -50,7 +50,7 @@ import org.apache.hadoop.hbase.HTableDescriptor;
import org.apache.hadoop.hbase.KeyValue; import org.apache.hadoop.hbase.KeyValue;
import org.apache.hadoop.hbase.TableName; import org.apache.hadoop.hbase.TableName;
import org.apache.hadoop.hbase.io.hfile.HFile; import org.apache.hadoop.hbase.io.hfile.HFile;
import org.apache.hadoop.hbase.io.hfile.HFileContextBuilder; import org.apache.hadoop.hbase.io.hfile.HFileContext;
import org.apache.hadoop.hbase.testclassification.SmallTests; import org.apache.hadoop.hbase.testclassification.SmallTests;
import org.apache.hadoop.hbase.util.Bytes; import org.apache.hadoop.hbase.util.Bytes;
import org.apache.hadoop.hbase.util.Pair; import org.apache.hadoop.hbase.util.Pair;
@ -279,7 +279,7 @@ public class TestBulkLoad {
FSDataOutputStream out = new FSDataOutputStream(new FileOutputStream(hFileLocation), null); FSDataOutputStream out = new FSDataOutputStream(new FileOutputStream(hFileLocation), null);
try { try {
hFileFactory.withOutputStream(out); hFileFactory.withOutputStream(out);
hFileFactory.withFileContext(new HFileContextBuilder().build()); hFileFactory.withFileContext(new HFileContext());
HFile.Writer writer = hFileFactory.create(); HFile.Writer writer = hFileFactory.create();
try { try {
writer.append(new KeyValue(CellUtil.createCell(randomBytes, writer.append(new KeyValue(CellUtil.createCell(randomBytes,

View File

@ -335,7 +335,7 @@ public class TestBulkLoadReplication extends TestReplicationBase {
new FSDataOutputStream(new FileOutputStream(hFileLocation), null); new FSDataOutputStream(new FileOutputStream(hFileLocation), null);
try { try {
hFileFactory.withOutputStream(out); hFileFactory.withOutputStream(out);
hFileFactory.withFileContext(new HFileContextBuilder().build()); hFileFactory.withFileContext(new HFileContext());
HFile.Writer writer = hFileFactory.create(); HFile.Writer writer = hFileFactory.create();
try { try {
writer.append(new KeyValue(cellBuilder.build())); writer.append(new KeyValue(cellBuilder.build()));

View File

@ -24,7 +24,9 @@ import java.io.IOException;
import java.nio.charset.StandardCharsets; import java.nio.charset.StandardCharsets;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.Objects;
import org.apache.hadoop.conf.Configuration; import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.FileSystem;
import org.apache.hadoop.fs.Path; import org.apache.hadoop.fs.Path;
import org.apache.hadoop.hbase.Cell; import org.apache.hadoop.hbase.Cell;
import org.apache.hadoop.hbase.CellUtil; import org.apache.hadoop.hbase.CellUtil;
@ -38,8 +40,6 @@ import org.apache.hadoop.hbase.TableName;
import org.apache.hadoop.hbase.client.Delete; import org.apache.hadoop.hbase.client.Delete;
import org.apache.hadoop.hbase.client.Durability; import org.apache.hadoop.hbase.client.Durability;
import org.apache.hadoop.hbase.client.Put; import org.apache.hadoop.hbase.client.Put;
import org.apache.hadoop.hbase.client.RegionInfo;
import org.apache.hadoop.hbase.client.RegionInfoBuilder;
import org.apache.hadoop.hbase.client.Result; import org.apache.hadoop.hbase.client.Result;
import org.apache.hadoop.hbase.client.Scan; import org.apache.hadoop.hbase.client.Scan;
import org.apache.hadoop.hbase.client.TableDescriptorBuilder; import org.apache.hadoop.hbase.client.TableDescriptorBuilder;
@ -58,8 +58,7 @@ import org.slf4j.LoggerFactory;
/** /**
* TestGet is a medley of tests of get all done up as a single test. * TestGet is a medley of tests of get all done up as a single test.
* It was originally written to test a method since removed, getClosestAtOrBefore * This class
* but the test is retained because it runs some interesting exercises.
*/ */
@Category({RegionServerTests.class, MediumTests.class}) @Category({RegionServerTests.class, MediumTests.class})
public class TestGetClosestAtOrBefore { public class TestGetClosestAtOrBefore {
@ -86,6 +85,7 @@ public class TestGetClosestAtOrBefore {
@Test @Test
public void testUsingMetaAndBinary() throws IOException { public void testUsingMetaAndBinary() throws IOException {
FileSystem filesystem = FileSystem.get(conf);
Path rootdir = UTIL.getDataTestDirOnTestFS(); Path rootdir = UTIL.getDataTestDirOnTestFS();
// Up flush size else we bind up when we use default catalog flush of 16k. // Up flush size else we bind up when we use default catalog flush of 16k.
TableDescriptorBuilder metaBuilder = UTIL.getMetaTableDescriptorBuilder() TableDescriptorBuilder metaBuilder = UTIL.getMetaTableDescriptorBuilder()
@ -100,14 +100,13 @@ public class TestGetClosestAtOrBefore {
final int last = 128; final int last = 128;
final int interval = 2; final int interval = 2;
for (int i = 0; i <= last; i += interval) { for (int i = 0; i <= last; i += interval) {
RegionInfo hri = RegionInfoBuilder.newBuilder(htd.getTableName()) HRegionInfo hri = new HRegionInfo(htd.getTableName(),
.setStartKey(i == 0 ? HConstants.EMPTY_BYTE_ARRAY : Bytes.toBytes((byte)i)) i == 0 ? HConstants.EMPTY_BYTE_ARRAY : Bytes.toBytes((byte) i),
.setEndKey(i == last ? HConstants.EMPTY_BYTE_ARRAY : i == last ? HConstants.EMPTY_BYTE_ARRAY : Bytes.toBytes((byte) i + interval));
Bytes.toBytes((byte)i + interval)).build();
Put put = Put put =
MetaTableAccessor.makePutFromRegionInfo(hri, EnvironmentEdgeManager.currentTime()); MetaTableAccessor.makePutFromRegionInfo(hri, EnvironmentEdgeManager.currentTime());
put.setDurability(Durability.SKIP_WAL); put.setDurability(Durability.SKIP_WAL);
LOG.info("Put {}", put);
mr.put(put); mr.put(put);
} }
} }
@ -115,7 +114,7 @@ public class TestGetClosestAtOrBefore {
try { try {
List<Cell> keys = new ArrayList<>(); List<Cell> keys = new ArrayList<>();
while (s.next(keys)) { while (s.next(keys)) {
LOG.info("Scan {}", keys); LOG.info(Objects.toString(keys));
keys.clear(); keys.clear();
} }
} finally { } finally {
@ -131,14 +130,13 @@ public class TestGetClosestAtOrBefore {
findRow(mr, 'C', 46, 46); findRow(mr, 'C', 46, 46);
findRow(mr, 'C', 43, 42); findRow(mr, 'C', 43, 42);
// Now delete 'C' and make sure I don't get entries from 'B'. // Now delete 'C' and make sure I don't get entries from 'B'.
byte[] firstRowInC = RegionInfo.createRegionName(TableName.valueOf("" + 'C'), byte[] firstRowInC = HRegionInfo.createRegionName(TableName.valueOf("" + 'C'),
HConstants.EMPTY_BYTE_ARRAY, HConstants.ZEROES, false); HConstants.EMPTY_BYTE_ARRAY, HConstants.ZEROES, false);
Scan scan = new Scan().withStartRow(firstRowInC); Scan scan = new Scan(firstRowInC);
s = mr.getScanner(scan); s = mr.getScanner(scan);
try { try {
List<Cell> keys = new ArrayList<>(); List<Cell> keys = new ArrayList<>();
while (s.next(keys)) { while (s.next(keys)) {
LOG.info("Delete {}", keys);
mr.delete(new Delete(CellUtil.cloneRow(keys.get(0)))); mr.delete(new Delete(CellUtil.cloneRow(keys.get(0))));
keys.clear(); keys.clear();
} }

View File

@ -61,7 +61,7 @@ import org.apache.hadoop.hbase.client.TableDescriptor;
import org.apache.hadoop.hbase.client.TableDescriptorBuilder; import org.apache.hadoop.hbase.client.TableDescriptorBuilder;
import org.apache.hadoop.hbase.executor.ExecutorService; import org.apache.hadoop.hbase.executor.ExecutorService;
import org.apache.hadoop.hbase.io.hfile.HFile; import org.apache.hadoop.hbase.io.hfile.HFile;
import org.apache.hadoop.hbase.io.hfile.HFileContextBuilder; import org.apache.hadoop.hbase.io.hfile.HFileContext;
import org.apache.hadoop.hbase.regionserver.HRegion.FlushResultImpl; import org.apache.hadoop.hbase.regionserver.HRegion.FlushResultImpl;
import org.apache.hadoop.hbase.regionserver.HRegion.PrepareFlushResult; import org.apache.hadoop.hbase.regionserver.HRegion.PrepareFlushResult;
import org.apache.hadoop.hbase.regionserver.throttle.NoLimitThroughputController; import org.apache.hadoop.hbase.regionserver.throttle.NoLimitThroughputController;
@ -1655,7 +1655,7 @@ public class TestHRegionReplayEvents {
FSDataOutputStream out = TEST_UTIL.getTestFileSystem().create(testFile); FSDataOutputStream out = TEST_UTIL.getTestFileSystem().create(testFile);
try { try {
hFileFactory.withOutputStream(out); hFileFactory.withOutputStream(out);
hFileFactory.withFileContext(new HFileContextBuilder().build()); hFileFactory.withFileContext(new HFileContext());
HFile.Writer writer = hFileFactory.create(); HFile.Writer writer = hFileFactory.create();
try { try {
writer.append(new KeyValue(CellUtil.createCell(valueBytes, family, valueBytes, 0L, writer.append(new KeyValue(CellUtil.createCell(valueBytes, family, valueBytes, 0L,

View File

@ -43,7 +43,6 @@ import org.apache.hadoop.hbase.client.Scan;
import org.apache.hadoop.hbase.client.Table; import org.apache.hadoop.hbase.client.Table;
import org.apache.hadoop.hbase.io.hfile.HFile; import org.apache.hadoop.hbase.io.hfile.HFile;
import org.apache.hadoop.hbase.io.hfile.HFileContext; import org.apache.hadoop.hbase.io.hfile.HFileContext;
import org.apache.hadoop.hbase.io.hfile.HFileContextBuilder;
import org.apache.hadoop.hbase.testclassification.MediumTests; import org.apache.hadoop.hbase.testclassification.MediumTests;
import org.apache.hadoop.hbase.testclassification.RegionServerTests; import org.apache.hadoop.hbase.testclassification.RegionServerTests;
import org.apache.hadoop.hbase.tool.LoadIncrementalHFiles; import org.apache.hadoop.hbase.tool.LoadIncrementalHFiles;
@ -162,7 +161,7 @@ public class TestScannerWithBulkload {
Path path = new Path(pathStr); Path path = new Path(pathStr);
HFile.WriterFactory wf = HFile.getWriterFactoryNoCache(TEST_UTIL.getConfiguration()); HFile.WriterFactory wf = HFile.getWriterFactoryNoCache(TEST_UTIL.getConfiguration());
Assert.assertNotNull(wf); Assert.assertNotNull(wf);
HFileContext context = new HFileContextBuilder().build(); HFileContext context = new HFileContext();
HFile.Writer writer = wf.withPath(fs, path).withFileContext(context).create(); HFile.Writer writer = wf.withPath(fs, path).withFileContext(context).create();
KeyValue kv = new KeyValue(Bytes.toBytes("row1"), Bytes.toBytes("col"), Bytes.toBytes("q"), l, KeyValue kv = new KeyValue(Bytes.toBytes("row1"), Bytes.toBytes("col"), Bytes.toBytes("q"), l,
Bytes.toBytes("version2")); Bytes.toBytes("version2"));

View File

@ -35,6 +35,7 @@ import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.FileSystem; import org.apache.hadoop.fs.FileSystem;
import org.apache.hadoop.fs.Path; import org.apache.hadoop.fs.Path;
import org.apache.hadoop.hbase.CellComparator; import org.apache.hadoop.hbase.CellComparator;
import org.apache.hadoop.hbase.CellComparatorImpl;
import org.apache.hadoop.hbase.HBaseClassTestRule; import org.apache.hadoop.hbase.HBaseClassTestRule;
import org.apache.hadoop.hbase.HBaseConfiguration; import org.apache.hadoop.hbase.HBaseConfiguration;
import org.apache.hadoop.hbase.HBaseTestingUtility; import org.apache.hadoop.hbase.HBaseTestingUtility;
@ -183,7 +184,7 @@ public class TestStoreScannerClosure {
Path storeFileParentDir = new Path(TEST_UTIL.getDataTestDir(), "TestHFile"); Path storeFileParentDir = new Path(TEST_UTIL.getDataTestDir(), "TestHFile");
HFileContext meta = new HFileContextBuilder().withBlockSize(64 * 1024).build(); HFileContext meta = new HFileContextBuilder().withBlockSize(64 * 1024).build();
StoreFileWriter sfw = new StoreFileWriter.Builder(CONF, fs).withOutputDir(storeFileParentDir) StoreFileWriter sfw = new StoreFileWriter.Builder(CONF, fs).withOutputDir(storeFileParentDir)
.withFileContext(meta).build(); .withComparator(CellComparatorImpl.COMPARATOR).withFileContext(meta).build();
final int rowLen = 32; final int rowLen = 32;
Random RNG = new Random(); Random RNG = new Random();