.../java/org/apache/hadoop/hbase/CellUtil.java | 54 ++++++++++++++++++++++
.../java/org/apache/hadoop/hbase/KeyValueUtil.java | 15 ------
.../hbase/regionserver/ScanQueryMatcher.java | 2 +-
.../hadoop/hbase/regionserver/StoreFile.java | 13 ++----
.../hbase/io/encoding/TestPrefixTreeEncoding.java | 18 +++-----
5 files changed, 66 insertions(+), 36 deletions(-)
diff --git a/hbase-common/src/main/java/org/apache/hadoop/hbase/CellUtil.java b/hbase-common/src/main/java/org/apache/hadoop/hbase/CellUtil.java
index 207f275..63084c1 100644
--- a/hbase-common/src/main/java/org/apache/hadoop/hbase/CellUtil.java
+++ b/hbase-common/src/main/java/org/apache/hadoop/hbase/CellUtil.java
@@ -1287,6 +1287,19 @@ public final class CellUtil {
cell.getQualifierArray(), cell.getQualifierOffset(), cell.getQualifierLength());
}
+ /**
+ * Create a Delete Family Cell for the specified row and family that would
+ * be smaller than all other possible Delete Family KeyValues that have the
+ * same row and family.
+ * Used for seeking.
+ * @param row - row key (arbitrary byte array)
+ * @param family - family name
+ * @return First Delete Family possible key on passed row.
+ */
+ public static Cell createFirstDeleteFamilyCellOnRow(final byte[] row, final byte[] fam) {
+ return new FirstOnRowDeleteFamilyCell(row, fam);
+ }
+
@InterfaceAudience.Private
private static abstract class FakeCell implements Cell {
@@ -1565,4 +1578,45 @@ public final class CellUtil {
return this.qlength;
}
}
+
+ @InterfaceAudience.Private
+ private static class FirstOnRowDeleteFamilyCell extends FakeCell {
+ private final byte[] row;
+ private final byte[] fam;
+
+ public FirstOnRowDeleteFamilyCell(byte[] row, byte[] fam) {
+ this.row = row;
+ this.fam = fam;
+ }
+
+ @Override
+ public byte[] getRowArray() {
+ return this.row;
+ }
+
+ @Override
+ public short getRowLength() {
+ return (short) this.row.length;
+ }
+
+ @Override
+ public byte[] getFamilyArray() {
+ return this.fam;
+ }
+
+ @Override
+ public byte getFamilyLength() {
+ return (byte) this.fam.length;
+ }
+
+ @Override
+ public long getTimestamp() {
+ return HConstants.LATEST_TIMESTAMP;
+ }
+
+ @Override
+ public byte getTypeByte() {
+ return Type.DeleteFamily.getCode();
+ }
+ }
}
\ No newline at end of file
diff --git a/hbase-common/src/main/java/org/apache/hadoop/hbase/KeyValueUtil.java b/hbase-common/src/main/java/org/apache/hadoop/hbase/KeyValueUtil.java
index 59519e0..412c0ad 100644
--- a/hbase-common/src/main/java/org/apache/hadoop/hbase/KeyValueUtil.java
+++ b/hbase-common/src/main/java/org/apache/hadoop/hbase/KeyValueUtil.java
@@ -328,21 +328,6 @@ public class KeyValueUtil {
}
/**
- * Create a Delete Family KeyValue for the specified row and family that would
- * be smaller than all other possible Delete Family KeyValues that have the
- * same row and family.
- * Used for seeking.
- * @param row - row key (arbitrary byte array)
- * @param family - family name
- * @return First Delete Family possible key on passed row.
- */
- public static KeyValue createFirstDeleteFamilyOnRow(final byte [] row,
- final byte [] family) {
- return new KeyValue(row, family, null, HConstants.LATEST_TIMESTAMP,
- Type.DeleteFamily);
- }
-
- /**
* @param row - row key (arbitrary byte array)
* @param f - family name
* @param q - column qualifier
diff --git a/hbase-server/src/main/java/org/apache/hadoop/hbase/regionserver/ScanQueryMatcher.java b/hbase-server/src/main/java/org/apache/hadoop/hbase/regionserver/ScanQueryMatcher.java
index 02a73f8..19710a8 100644
--- a/hbase-server/src/main/java/org/apache/hadoop/hbase/regionserver/ScanQueryMatcher.java
+++ b/hbase-server/src/main/java/org/apache/hadoop/hbase/regionserver/ScanQueryMatcher.java
@@ -165,7 +165,7 @@ public class ScanQueryMatcher {
this.regionCoprocessorHost = regionCoprocessorHost;
this.deletes = instantiateDeleteTracker();
this.stopRow = scan.getStopRow();
- this.startKey = KeyValueUtil.createFirstDeleteFamilyOnRow(scan.getStartRow(),
+ this.startKey = CellUtil.createFirstDeleteFamilyCellOnRow(scan.getStartRow(),
scanInfo.getFamily());
this.filter = scan.getFilter();
this.earliestPutTs = earliestPutTs;
diff --git a/hbase-server/src/main/java/org/apache/hadoop/hbase/regionserver/StoreFile.java b/hbase-server/src/main/java/org/apache/hadoop/hbase/regionserver/StoreFile.java
index eb76440..daea870 100644
--- a/hbase-server/src/main/java/org/apache/hadoop/hbase/regionserver/StoreFile.java
+++ b/hbase-server/src/main/java/org/apache/hadoop/hbase/regionserver/StoreFile.java
@@ -1362,19 +1362,16 @@ public class StoreFile {
&& Bytes.equals(scan.getStopRow(), HConstants.EMPTY_END_ROW)) {
return true;
}
- KeyValue smallestScanKeyValue = scan.isReversed() ? KeyValueUtil
- .createFirstOnRow(scan.getStopRow()) : KeyValueUtil.createFirstOnRow(scan
- .getStartRow());
- KeyValue largestScanKeyValue = scan.isReversed() ? KeyValueUtil
- .createLastOnRow(scan.getStartRow()) : KeyValueUtil.createLastOnRow(scan
- .getStopRow());
+ byte[] smallestScanRow = scan.isReversed() ? scan.getStopRow() : scan.getStartRow();
+ byte[] largestScanRow = scan.isReversed() ? scan.getStartRow() : scan.getStopRow();
Cell firstKeyKV = this.getFirstKey();
Cell lastKeyKV = this.getLastKey();
- boolean nonOverLapping = ((getComparator().compare(firstKeyKV, largestScanKeyValue)) > 0
+ boolean nonOverLapping = (getComparator().compareRows(firstKeyKV,
+ largestScanRow, 0, largestScanRow.length) > 0
&& !Bytes
.equals(scan.isReversed() ? scan.getStartRow() : scan.getStopRow(),
HConstants.EMPTY_END_ROW))
- || (getComparator().compare(lastKeyKV, smallestScanKeyValue)) < 0;
+ || getComparator().compareRows(lastKeyKV, smallestScanRow, 0, smallestScanRow.length) < 0;
return !nonOverLapping;
}
diff --git a/hbase-server/src/test/java/org/apache/hadoop/hbase/io/encoding/TestPrefixTreeEncoding.java b/hbase-server/src/test/java/org/apache/hadoop/hbase/io/encoding/TestPrefixTreeEncoding.java
index 91115c1..7e9b5a8 100644
--- a/hbase-server/src/test/java/org/apache/hadoop/hbase/io/encoding/TestPrefixTreeEncoding.java
+++ b/hbase-server/src/test/java/org/apache/hadoop/hbase/io/encoding/TestPrefixTreeEncoding.java
@@ -120,27 +120,21 @@ public class TestPrefixTreeEncoding {
seeker.setCurrentBuffer(readBuffer);
// Seek before the first keyvalue;
- KeyValue seekKey = KeyValueUtil.createFirstDeleteFamilyOnRow(getRowKey(batchId, 0), CF_BYTES);
- seeker.seekToKeyInBlock(
- new KeyValue.KeyOnlyKeyValue(seekKey.getBuffer(), seekKey.getKeyOffset(), seekKey
- .getKeyLength()), true);
+ Cell seekKey = CellUtil.createFirstDeleteFamilyCellOnRow(getRowKey(batchId, 0), CF_BYTES);
+ seeker.seekToKeyInBlock(seekKey, true);
assertEquals(null, seeker.getKeyValue());
// Seek before the middle keyvalue;
- seekKey = KeyValueUtil.createFirstDeleteFamilyOnRow(getRowKey(batchId, NUM_ROWS_PER_BATCH / 3),
+ seekKey = CellUtil.createFirstDeleteFamilyCellOnRow(getRowKey(batchId, NUM_ROWS_PER_BATCH / 3),
CF_BYTES);
- seeker.seekToKeyInBlock(
- new KeyValue.KeyOnlyKeyValue(seekKey.getBuffer(), seekKey.getKeyOffset(), seekKey
- .getKeyLength()), true);
+ seeker.seekToKeyInBlock(seekKey, true);
assertNotNull(seeker.getKeyValue());
assertArrayEquals(getRowKey(batchId, NUM_ROWS_PER_BATCH / 3 - 1),
CellUtil.cloneRow(seeker.getKeyValue()));
// Seek before the last keyvalue;
- seekKey = KeyValueUtil.createFirstDeleteFamilyOnRow(Bytes.toBytes("zzzz"), CF_BYTES);
- seeker.seekToKeyInBlock(
- new KeyValue.KeyOnlyKeyValue(seekKey.getBuffer(), seekKey.getKeyOffset(), seekKey
- .getKeyLength()), true);
+ seekKey = CellUtil.createFirstDeleteFamilyCellOnRow(Bytes.toBytes("zzzz"), CF_BYTES);
+ seeker.seekToKeyInBlock(seekKey, true);
assertNotNull(seeker.getKeyValue());
assertArrayEquals(getRowKey(batchId, NUM_ROWS_PER_BATCH - 1),
CellUtil.cloneRow(seeker.getKeyValue()));