diff --git a/hbase-common/src/main/java/org/apache/hadoop/hbase/CellComparator.java b/hbase-common/src/main/java/org/apache/hadoop/hbase/CellComparator.java index 3ad717b..53dd8e0 100644 --- a/hbase-common/src/main/java/org/apache/hadoop/hbase/CellComparator.java +++ b/hbase-common/src/main/java/org/apache/hadoop/hbase/CellComparator.java @@ -178,11 +178,19 @@ public class CellComparator implements Comparator, Serializable { return compareWithoutRow(left, right); } + /** + * Do not use comparing rows from hbase:meta. Meta table Cells have schema (table,startrow,hash) + * so can't be treated as plain byte arrays as this method does. + */ public static int compareRows(final Cell left, final Cell right) { return Bytes.compareTo(left.getRowArray(), left.getRowOffset(), left.getRowLength(), right.getRowArray(), right.getRowOffset(), right.getRowLength()); } + /** + * Do not use comparing rows from hbase:meta. Meta table Cells have schema (table,startrow,hash) + * so can't be treated as plain byte arrays as this method does. + */ public static int compareRows(byte[] left, int loffset, int llength, byte[] right, int roffset, int rlength) { return Bytes.compareTo(left, loffset, llength, right, roffset, rlength); @@ -375,14 +383,16 @@ public class CellComparator implements Comparator, Serializable { /** * Try to return a Cell that falls between left and right but that is - * shorter; i.e. takes up less space. This is trick is used building HFile block index. + * shorter; i.e. takes up less space. This trick is used building HFile block index. * Its an optimization. It does not always work. In this case we'll just return the * right cell. + * @param comparator Comparator to use. * @param left * @param right * @return A cell that sorts between left and right. */ - public static Cell getMidpoint(final Cell left, final Cell right) { + public static Cell getMidpoint(final KeyValue.KVComparator comparator, final Cell left, + final Cell right) { // TODO: Redo so only a single pass over the arrays rather than one to compare and then a // second composing midpoint. if (right == null) { @@ -391,6 +401,12 @@ public class CellComparator implements Comparator, Serializable { if (left == null) { return right; } + // If Cells from meta table, don't mess around. meta table Cells have schema + // (table,startrow,hash) so can't be treated as plain byte arrays. Just skip out without + // trying to do this optimization. + if (comparator != null && comparator instanceof KeyValue.MetaComparator) { + return right; + } int diff = compareRows(left, right); if (diff > 0) { throw new IllegalArgumentException("Left row sorts after right row; left=" + @@ -481,4 +497,4 @@ public class CellComparator implements Comparator, Serializable { } return minimumMidpointArray; } -} +} \ No newline at end of file diff --git a/hbase-server/src/main/java/org/apache/hadoop/hbase/io/hfile/HFileWriterV2.java b/hbase-server/src/main/java/org/apache/hadoop/hbase/io/hfile/HFileWriterV2.java index 1df8bc2..28c4655 100644 --- a/hbase-server/src/main/java/org/apache/hadoop/hbase/io/hfile/HFileWriterV2.java +++ b/hbase-server/src/main/java/org/apache/hadoop/hbase/io/hfile/HFileWriterV2.java @@ -162,9 +162,8 @@ public class HFileWriterV2 extends AbstractHFileWriter { fsBlockWriter.writeHeaderAndData(outputStream); int onDiskSize = fsBlockWriter.getOnDiskSizeWithHeader(); - // Rather than CellComparator, we should be making use of an Interface here with the - // implementation class serialized out to the HFile metadata. TODO. - Cell indexEntry = CellComparator.getMidpoint(lastCellOfPreviousBlock, firstCellInBlock); + Cell indexEntry = + CellComparator.getMidpoint(this.comparator, lastCellOfPreviousBlock, firstCellInBlock); dataBlockIndexWriter.addEntry(CellUtil.getCellKeySerializedAsKeyValueKey(indexEntry), lastDataBlockOffset, onDiskSize); totalUncompressedBytes += fsBlockWriter.getUncompressedSizeWithHeader(); @@ -264,8 +263,9 @@ public class HFileWriterV2 extends AbstractHFileWriter { checkBlockBoundary(); } - if (!fsBlockWriter.isWriting()) + if (!fsBlockWriter.isWriting()) { newBlock(); + } fsBlockWriter.write(cell);