diff --git hbase-server/src/main/java/org/apache/hadoop/hbase/regionserver/ScanQueryMatcher.java hbase-server/src/main/java/org/apache/hadoop/hbase/regionserver/ScanQueryMatcher.java index 0bb2f42..2844392 100644 --- hbase-server/src/main/java/org/apache/hadoop/hbase/regionserver/ScanQueryMatcher.java +++ hbase-server/src/main/java/org/apache/hadoop/hbase/regionserver/ScanQueryMatcher.java @@ -24,6 +24,7 @@ import java.util.NavigableSet; import org.apache.hadoop.classification.InterfaceAudience; import org.apache.hadoop.hbase.Cell; +import org.apache.hadoop.hbase.CellUtil; import org.apache.hadoop.hbase.HConstants; import org.apache.hadoop.hbase.KeyValue; import org.apache.hadoop.hbase.KeyValueUtil; @@ -80,7 +81,7 @@ public class ScanQueryMatcher { private final ColumnTracker columns; /** Key to seek to in memstore and StoreFiles */ - private final KeyValue startKey; + private final Cell startKey; /** Row comparator for the region this query is for */ private final KeyValue.KVComparator rowComparator; @@ -245,24 +246,12 @@ public class ScanQueryMatcher { * @throws IOException in case there is an internal consistency problem * caused by a data corruption. */ - public MatchCode match(KeyValue kv) throws IOException { + public MatchCode match(Cell kv) throws IOException { if (filter != null && filter.filterAllRemaining()) { return MatchCode.DONE_SCAN; } - - byte [] bytes = kv.getBuffer(); - int offset = kv.getOffset(); - - int keyLength = Bytes.toInt(bytes, offset, Bytes.SIZEOF_INT); - offset += KeyValue.ROW_OFFSET; - - int initialOffset = offset; - - short rowLength = Bytes.toShort(bytes, offset, Bytes.SIZEOF_SHORT); - offset += Bytes.SIZEOF_SHORT; - - int ret = this.rowComparator.compareRows(row, this.rowOffset, this.rowLength, - bytes, offset, rowLength); + int ret = this.rowComparator.compareRows(row, this.rowOffset, this.rowLength, kv.getRowArray(), + kv.getRowOffset(), kv.getRowLength()); if (!this.isReversed) { if (ret <= -1) { return MatchCode.DONE; @@ -280,30 +269,19 @@ public class ScanQueryMatcher { } } - // optimize case. if (this.stickyNextRow) - return MatchCode.SEEK_NEXT_ROW; + return MatchCode.SEEK_NEXT_ROW; if (this.columns.done()) { stickyNextRow = true; return MatchCode.SEEK_NEXT_ROW; } - //Passing rowLength - offset += rowLength; - - //Skipping family - byte familyLength = bytes [offset]; - offset += familyLength + 1; - - int qualLength = keyLength - - (offset - initialOffset) - KeyValue.TIMESTAMP_TYPE_SIZE; - - long timestamp = Bytes.toLong(bytes, initialOffset + keyLength - KeyValue.TIMESTAMP_TYPE_SIZE); // check for early out based on timestamp alone - if (columns.isDone(timestamp)) { - return columns.getNextRowOrNextColumn(bytes, offset, qualLength); + if (columns.isDone(kv.getTimestamp())) { + return columns.getNextRowOrNextColumn(kv.getQualifierArray(), kv.getQualifierOffset(), + kv.getQualifierLength()); } /* @@ -319,8 +297,7 @@ public class ScanQueryMatcher { * 7. Delete marker need to be version counted together with puts * they affect */ - byte type = bytes[initialOffset + keyLength - 1]; - if (kv.isDelete()) { + if (CellUtil.isDelete(kv)) { if (!keepDeletedCells) { // first ignore delete markers if the scanner can do so, and the // range does not include the marker @@ -329,18 +306,19 @@ public class ScanQueryMatcher { // than the readpoint of any open scanner, this prevents deleted // rows that could still be seen by a scanner from being collected boolean includeDeleteMarker = seePastDeleteMarkers ? - tr.withinTimeRange(timestamp) : - tr.withinOrAfterTimeRange(timestamp); + tr.withinTimeRange(kv.getTimestamp()) : + tr.withinOrAfterTimeRange(kv.getTimestamp()); if (includeDeleteMarker && kv.getMvccVersion() <= maxReadPointToTrackVersions) { - this.deletes.add(bytes, offset, qualLength, timestamp, type); + this.deletes.add(kv.getQualifierArray(), kv.getQualifierOffset(), + kv.getQualifierLength(), kv.getTimestamp(), kv.getTypeByte()); } // Can't early out now, because DelFam come before any other keys } if ((!isUserScan) && timeToPurgeDeletes > 0 - && (EnvironmentEdgeManager.currentTimeMillis() - timestamp) <= timeToPurgeDeletes) { + && (EnvironmentEdgeManager.currentTimeMillis() - kv.getTimestamp()) <= timeToPurgeDeletes) { return MatchCode.INCLUDE; } else if (retainDeletesInOutput || kv.getMvccVersion() > maxReadPointToTrackVersions) { // always include or it is not time yet to check whether it is OK @@ -351,10 +329,11 @@ public class ScanQueryMatcher { return MatchCode.INCLUDE; } } else if (keepDeletedCells) { - if (timestamp < earliestPutTs) { + if (kv.getTimestamp() < earliestPutTs) { // keeping delete rows, but there are no puts older than // this delete in the store files. - return columns.getNextRowOrNextColumn(bytes, offset, qualLength); + return columns.getNextRowOrNextColumn(kv.getQualifierArray(), kv.getQualifierOffset(), + kv.getQualifierLength()); } // else: fall through and do version counting on the // delete markers @@ -364,12 +343,13 @@ public class ScanQueryMatcher { // note the following next else if... // delete marker are not subject to other delete markers } else if (!this.deletes.isEmpty()) { - DeleteResult deleteResult = deletes.isDeleted(bytes, offset, qualLength, - timestamp); + DeleteResult deleteResult = deletes.isDeleted(kv.getQualifierArray(), + kv.getQualifierOffset(), kv.getQualifierLength(), kv.getTimestamp()); switch (deleteResult) { case FAMILY_DELETED: case COLUMN_DELETED: - return columns.getNextRowOrNextColumn(bytes, offset, qualLength); + return columns.getNextRowOrNextColumn(kv.getQualifierArray(), kv.getQualifierOffset(), + kv.getQualifierLength()); case VERSION_DELETED: case FAMILY_VERSION_DELETED: return MatchCode.SKIP; @@ -380,15 +360,17 @@ public class ScanQueryMatcher { } } - int timestampComparison = tr.compare(timestamp); + int timestampComparison = tr.compare(kv.getTimestamp()); if (timestampComparison >= 1) { return MatchCode.SKIP; } else if (timestampComparison <= -1) { - return columns.getNextRowOrNextColumn(bytes, offset, qualLength); + return columns.getNextRowOrNextColumn(kv.getQualifierArray(), kv.getQualifierOffset(), + kv.getQualifierLength()); } // STEP 1: Check if the column is part of the requested columns - MatchCode colChecker = columns.checkColumn(bytes, offset, qualLength, type); + MatchCode colChecker = columns.checkColumn(kv.getQualifierArray(), kv.getQualifierOffset(), + kv.getQualifierLength(), kv.getTypeByte()); if (colChecker == MatchCode.INCLUDE) { ReturnCode filterResponse = ReturnCode.SKIP; // STEP 2: Yes, the column is part of the requested columns. Check if filter is present @@ -399,7 +381,8 @@ public class ScanQueryMatcher { case SKIP: return MatchCode.SKIP; case NEXT_COL: - return columns.getNextRowOrNextColumn(bytes, offset, qualLength); + return columns.getNextRowOrNextColumn(kv.getQualifierArray(), kv.getQualifierOffset(), + kv.getQualifierLength()); case NEXT_ROW: stickyNextRow = true; return MatchCode.SEEK_NEXT_ROW; @@ -430,7 +413,8 @@ public class ScanQueryMatcher { * FilterResponse (INCLUDE_AND_SEEK_NEXT_COL) and ColumnChecker(INCLUDE) */ colChecker = - columns.checkVersions(bytes, offset, qualLength, timestamp, type, + columns.checkVersions(kv.getQualifierArray(), kv.getQualifierOffset(), + kv.getQualifierLength(), kv.getTimestamp(), kv.getTypeByte(), kv.getMvccVersion() > maxReadPointToTrackVersions); //Optimize with stickyNextRow stickyNextRow = colChecker == MatchCode.INCLUDE_AND_SEEK_NEXT_ROW ? true : stickyNextRow; @@ -470,7 +454,7 @@ public class ScanQueryMatcher { } } - public boolean moreRowsMayExistAfter(KeyValue kv) { + public boolean moreRowsMayExistAfter(Cell kv) { if (this.isReversed) { if (rowComparator.compareRows(kv.getRowArray(), kv.getRowOffset(), kv.getRowLength(), stopRow, 0, stopRow.length) <= 0) { @@ -513,7 +497,7 @@ public class ScanQueryMatcher { * * @return the start key */ - public KeyValue getStartKey() { + public Cell getStartKey() { return this.startKey; } @@ -533,7 +517,7 @@ public class ScanQueryMatcher { } } - public KeyValue getKeyForNextColumn(KeyValue kv) { + public Cell getKeyForNextColumn(Cell kv) { ColumnCount nextColumn = columns.getColumnHint(); if (nextColumn == null) { return KeyValueUtil.createLastOnRow( @@ -548,7 +532,7 @@ public class ScanQueryMatcher { } } - public KeyValue getKeyForNextRow(KeyValue kv) { + public Cell getKeyForNextRow(Cell kv) { return KeyValueUtil.createLastOnRow( kv.getRowArray(), kv.getRowOffset(), kv.getRowLength(), null, 0, 0, diff --git hbase-server/src/main/java/org/apache/hadoop/hbase/regionserver/StoreScanner.java hbase-server/src/main/java/org/apache/hadoop/hbase/regionserver/StoreScanner.java index 451e653..c75487b 100644 --- hbase-server/src/main/java/org/apache/hadoop/hbase/regionserver/StoreScanner.java +++ hbase-server/src/main/java/org/apache/hadoop/hbase/regionserver/StoreScanner.java @@ -502,7 +502,7 @@ public class StoreScanner extends NonReversedNonLazyKeyValueScanner } seekToNextRow(kv); } else if (qcode == ScanQueryMatcher.MatchCode.INCLUDE_AND_SEEK_NEXT_COL) { - seekAsDirection(matcher.getKeyForNextColumn(KeyValueUtil.ensureKeyValue(kv))); + seekAsDirection(matcher.getKeyForNextColumn(kv)); } else { this.heap.next(); } @@ -530,7 +530,7 @@ public class StoreScanner extends NonReversedNonLazyKeyValueScanner break; case SEEK_NEXT_COL: - seekAsDirection(matcher.getKeyForNextColumn(KeyValueUtil.ensureKeyValue(kv))); + seekAsDirection(matcher.getKeyForNextColumn(kv)); break; case SKIP: @@ -678,7 +678,7 @@ public class StoreScanner extends NonReversedNonLazyKeyValueScanner * @return true if scanner has values left, false if end of scanner * @throws IOException */ - protected boolean seekAsDirection(KeyValue kv) + protected boolean seekAsDirection(Cell kv) throws IOException { return reseek(kv); }