You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@hbase.apache.org by la...@apache.org on 2012/12/06 01:29:21 UTC
svn commit: r1417716 - in /hbase/branches/0.94/src:
main/java/org/apache/hadoop/hbase/ main/java/org/apache/hadoop/hbase/client/
main/java/org/apache/hadoop/hbase/regionserver/
test/java/org/apache/hadoop/hbase/regionserver/
Author: larsh
Date: Thu Dec 6 00:29:20 2012
New Revision: 1417716
URL: http://svn.apache.org/viewvc?rev=1417716&view=rev
Log:
HBASE-7279 Avoid copying the rowkey in RegionScanner, StoreScanner, and ScanQueryMatcher
Modified:
hbase/branches/0.94/src/main/java/org/apache/hadoop/hbase/KeyValue.java
hbase/branches/0.94/src/main/java/org/apache/hadoop/hbase/client/Result.java
hbase/branches/0.94/src/main/java/org/apache/hadoop/hbase/regionserver/HRegion.java
hbase/branches/0.94/src/main/java/org/apache/hadoop/hbase/regionserver/ScanQueryMatcher.java
hbase/branches/0.94/src/main/java/org/apache/hadoop/hbase/regionserver/StoreScanner.java
hbase/branches/0.94/src/test/java/org/apache/hadoop/hbase/regionserver/TestQueryMatcher.java
Modified: hbase/branches/0.94/src/main/java/org/apache/hadoop/hbase/KeyValue.java
URL: http://svn.apache.org/viewvc/hbase/branches/0.94/src/main/java/org/apache/hadoop/hbase/KeyValue.java?rev=1417716&r1=1417715&r2=1417716&view=diff
==============================================================================
--- hbase/branches/0.94/src/main/java/org/apache/hadoop/hbase/KeyValue.java (original)
+++ hbase/branches/0.94/src/main/java/org/apache/hadoop/hbase/KeyValue.java Thu Dec 6 00:29:20 2012
@@ -216,9 +216,6 @@ public class KeyValue implements Writabl
private int offset = 0;
private int length = 0;
- // the row cached
- private volatile byte [] rowCache = null;
-
/**
* @return True if a delete type, a {@link KeyValue.Type#Delete} or
* a {KeyValue.Type#DeleteFamily} or a {@link KeyValue.Type#DeleteColumn}
@@ -987,7 +984,6 @@ public class KeyValue implements Writabl
int tsOffset = getTimestampOffset();
System.arraycopy(now, 0, this.bytes, tsOffset, Bytes.SIZEOF_LONG);
// clear cache or else getTimestamp() possibly returns an old value
- timestampCache = -1L;
return true;
}
return false;
@@ -1037,28 +1033,19 @@ public class KeyValue implements Writabl
* @return Row in a new byte array.
*/
public byte [] getRow() {
- if (rowCache == null) {
- int o = getRowOffset();
- short l = getRowLength();
- // initialize and copy the data into a local variable
- // in case multiple threads race here.
- byte local[] = new byte[l];
- System.arraycopy(getBuffer(), o, local, 0, l);
- rowCache = local; // volatile assign
- }
- return rowCache;
+ int o = getRowOffset();
+ short l = getRowLength();
+ byte result[] = new byte[l];
+ System.arraycopy(getBuffer(), o, result, 0, l);
+ return result;
}
/**
*
* @return Timestamp
*/
- private long timestampCache = -1;
public long getTimestamp() {
- if (timestampCache == -1) {
- timestampCache = getTimestamp(getKeyLength());
- }
- return timestampCache;
+ return getTimestamp(getKeyLength());
}
/**
@@ -2260,21 +2247,17 @@ public class KeyValue implements Writabl
// HeapSize
public long heapSize() {
- return ClassSize.align(ClassSize.OBJECT + (2 * ClassSize.REFERENCE) +
- ClassSize.align(ClassSize.ARRAY) + ClassSize.align(length) +
- (3 * Bytes.SIZEOF_INT) +
- ClassSize.align(ClassSize.ARRAY) +
- (2 * Bytes.SIZEOF_LONG));
+ return ClassSize.align(ClassSize.OBJECT + ClassSize.REFERENCE
+ + ClassSize.align(ClassSize.ARRAY) + ClassSize.align(length)
+ + (3 * Bytes.SIZEOF_INT) + Bytes.SIZEOF_LONG);
}
// this overload assumes that the length bytes have already been read,
// and it expects the length of the KeyValue to be explicitly passed
// to it.
public void readFields(int length, final DataInput in) throws IOException {
- this.rowCache = null;
this.length = length;
this.offset = 0;
- this.timestampCache = -1;
this.keyLength = 0;
this.bytes = new byte[this.length];
in.readFully(this.bytes, 0, this.length);
Modified: hbase/branches/0.94/src/main/java/org/apache/hadoop/hbase/client/Result.java
URL: http://svn.apache.org/viewvc/hbase/branches/0.94/src/main/java/org/apache/hadoop/hbase/client/Result.java?rev=1417716&r1=1417715&r2=1417716&view=diff
==============================================================================
--- hbase/branches/0.94/src/main/java/org/apache/hadoop/hbase/client/Result.java (original)
+++ hbase/branches/0.94/src/main/java/org/apache/hadoop/hbase/client/Result.java Thu Dec 6 00:29:20 2012
@@ -96,7 +96,7 @@ public class Result implements Writable,
* @param kvs List of KeyValues
*/
public Result(List<KeyValue> kvs) {
- this(kvs.toArray(new KeyValue[0]));
+ this(kvs.toArray(new KeyValue[kvs.size()]));
}
/**
Modified: hbase/branches/0.94/src/main/java/org/apache/hadoop/hbase/regionserver/HRegion.java
URL: http://svn.apache.org/viewvc/hbase/branches/0.94/src/main/java/org/apache/hadoop/hbase/regionserver/HRegion.java?rev=1417716&r1=1417715&r2=1417716&view=diff
==============================================================================
--- hbase/branches/0.94/src/main/java/org/apache/hadoop/hbase/regionserver/HRegion.java (original)
+++ hbase/branches/0.94/src/main/java/org/apache/hadoop/hbase/regionserver/HRegion.java Thu Dec 6 00:29:20 2012
@@ -3567,8 +3567,16 @@ public class HRegion implements HeapSize
rpcCall.throwExceptionIfCallerDisconnected();
}
- byte [] currentRow = peekRow();
- if (isStopRow(currentRow)) {
+ KeyValue current = this.storeHeap.peek();
+ byte[] currentRow = null;
+ int offset = 0;
+ short length = 0;
+ if (current != null) {
+ currentRow = current.getBuffer();
+ offset = current.getRowOffset();
+ length = current.getRowLength();
+ }
+ if (isStopRow(currentRow, offset, length)) {
if (filter != null && filter.hasFilterRow()) {
filter.filterRow(results);
}
@@ -3577,10 +3585,10 @@ public class HRegion implements HeapSize
}
return false;
- } else if (filterRowKey(currentRow)) {
- nextRow(currentRow);
+ } else if (filterRowKey(currentRow, offset, length)) {
+ nextRow(currentRow, offset, length);
} else {
- byte [] nextRow;
+ KeyValue nextKv;
do {
this.storeHeap.next(results, limit - results.size(), metric);
if (limit > 0 && results.size() == limit) {
@@ -3590,9 +3598,10 @@ public class HRegion implements HeapSize
}
return true; // we are expecting more yes, but also limited to how many we can return.
}
- } while (Bytes.equals(currentRow, nextRow = peekRow()));
+ nextKv = this.storeHeap.peek();
+ } while (nextKv != null && nextKv.matchingRow(currentRow, offset, length));
- final boolean stopRow = isStopRow(nextRow);
+ final boolean stopRow = nextKv == null || isStopRow(nextKv.getBuffer(), nextKv.getRowOffset(), nextKv.getRowLength());
// now that we have an entire row, lets process with a filters:
@@ -3607,7 +3616,7 @@ public class HRegion implements HeapSize
// the reasons for calling this method are:
// 1. reset the filters.
// 2. provide a hook to fast forward the row (used by subclasses)
- nextRow(currentRow);
+ nextRow(currentRow, offset, length);
// This row was totally filtered out, if this is NOT the last row,
// we should continue on.
@@ -3623,29 +3632,25 @@ public class HRegion implements HeapSize
return filter != null
&& filter.filterRow();
}
- private boolean filterRowKey(byte[] row) {
+ private boolean filterRowKey(byte[] row, int offset, short length) {
return filter != null
- && filter.filterRowKey(row, 0, row.length);
+ && filter.filterRowKey(row, offset, length);
}
- protected void nextRow(byte [] currentRow) throws IOException {
- while (Bytes.equals(currentRow, peekRow())) {
- this.storeHeap.next(MOCKED_LIST);
+ protected void nextRow(byte [] currentRow, int offset, short length) throws IOException {
+ KeyValue next;
+ while((next = this.storeHeap.peek()) != null && next.matchingRow(currentRow, offset, length)) {
+ this.storeHeap.next(MOCKED_LIST);
}
results.clear();
resetFilters();
}
- private byte[] peekRow() {
- KeyValue kv = this.storeHeap.peek();
- return kv == null ? null : kv.getRow();
- }
-
- private boolean isStopRow(byte [] currentRow) {
+ private boolean isStopRow(byte [] currentRow, int offset, short length) {
return currentRow == null ||
(stopRow != null &&
comparator.compareRows(stopRow, 0, stopRow.length,
- currentRow, 0, currentRow.length) <= isScan);
+ currentRow, offset, length) <= isScan);
}
@Override
Modified: hbase/branches/0.94/src/main/java/org/apache/hadoop/hbase/regionserver/ScanQueryMatcher.java
URL: http://svn.apache.org/viewvc/hbase/branches/0.94/src/main/java/org/apache/hadoop/hbase/regionserver/ScanQueryMatcher.java?rev=1417716&r1=1417715&r2=1417716&view=diff
==============================================================================
--- hbase/branches/0.94/src/main/java/org/apache/hadoop/hbase/regionserver/ScanQueryMatcher.java (original)
+++ hbase/branches/0.94/src/main/java/org/apache/hadoop/hbase/regionserver/ScanQueryMatcher.java Thu Dec 6 00:29:20 2012
@@ -82,6 +82,8 @@ public class ScanQueryMatcher {
/* row is not private for tests */
/** Row the query is on */
byte [] row;
+ int rowOffset;
+ short rowLength;
/**
* Oldest put in any of the involved store files
@@ -222,7 +224,7 @@ public class ScanQueryMatcher {
short rowLength = Bytes.toShort(bytes, offset, Bytes.SIZEOF_SHORT);
offset += Bytes.SIZEOF_SHORT;
- int ret = this.rowComparator.compareRows(row, 0, row.length,
+ int ret = this.rowComparator.compareRows(row, this.rowOffset, this.rowLength,
bytes, offset, rowLength);
if (ret <= -1) {
return MatchCode.DONE;
@@ -385,8 +387,10 @@ public class ScanQueryMatcher {
* Set current row
* @param row
*/
- public void setRow(byte [] row) {
+ public void setRow(byte [] row, int offset, short length) {
this.row = row;
+ this.rowOffset = offset;
+ this.rowLength = length;
reset();
}
Modified: hbase/branches/0.94/src/main/java/org/apache/hadoop/hbase/regionserver/StoreScanner.java
URL: http://svn.apache.org/viewvc/hbase/branches/0.94/src/main/java/org/apache/hadoop/hbase/regionserver/StoreScanner.java?rev=1417716&r1=1417715&r2=1417716&view=diff
==============================================================================
--- hbase/branches/0.94/src/main/java/org/apache/hadoop/hbase/regionserver/StoreScanner.java (original)
+++ hbase/branches/0.94/src/main/java/org/apache/hadoop/hbase/regionserver/StoreScanner.java Thu Dec 6 00:29:20 2012
@@ -340,8 +340,11 @@ public class StoreScanner extends NonLaz
// only call setRow if the row changes; avoids confusing the query matcher
// if scanning intra-row
- if ((matcher.row == null) || !peeked.matchingRow(matcher.row)) {
- matcher.setRow(peeked.getRow());
+ byte[] row = peeked.getBuffer();
+ int offset = peeked.getRowOffset();
+ short length = peeked.getRowLength();
+ if ((matcher.row == null) || !Bytes.equals(row, offset, length, matcher.row, matcher.rowOffset, matcher.rowLength)) {
+ matcher.setRow(row, offset, length);
}
KeyValue kv;
@@ -521,9 +524,12 @@ public class StoreScanner extends NonLaz
if (kv == null) {
kv = lastTopKey;
}
- if ((matcher.row == null) || !kv.matchingRow(matcher.row)) {
+ byte[] row = kv.getBuffer();
+ int offset = kv.getRowOffset();
+ short length = kv.getRowLength();
+ if ((matcher.row == null) || !Bytes.equals(row, offset, length, matcher.row, matcher.rowOffset, matcher.rowLength)) {
matcher.reset();
- matcher.setRow(kv.getRow());
+ matcher.setRow(row, offset, length);
}
}
Modified: hbase/branches/0.94/src/test/java/org/apache/hadoop/hbase/regionserver/TestQueryMatcher.java
URL: http://svn.apache.org/viewvc/hbase/branches/0.94/src/test/java/org/apache/hadoop/hbase/regionserver/TestQueryMatcher.java?rev=1417716&r1=1417715&r2=1417716&view=diff
==============================================================================
--- hbase/branches/0.94/src/test/java/org/apache/hadoop/hbase/regionserver/TestQueryMatcher.java (original)
+++ hbase/branches/0.94/src/test/java/org/apache/hadoop/hbase/regionserver/TestQueryMatcher.java Thu Dec 6 00:29:20 2012
@@ -113,7 +113,8 @@ public class TestQueryMatcher extends HB
memstore.add(new KeyValue(row2, fam1, col1, data));
List<ScanQueryMatcher.MatchCode> actual = new ArrayList<ScanQueryMatcher.MatchCode>();
- qm.setRow(memstore.get(0).getRow());
+ KeyValue k = memstore.get(0);
+ qm.setRow(k.getBuffer(), k.getRowOffset(), k.getRowLength());
for (KeyValue kv : memstore){
actual.add(qm.match(kv));
@@ -158,7 +159,8 @@ public class TestQueryMatcher extends HB
List<ScanQueryMatcher.MatchCode> actual = new ArrayList<ScanQueryMatcher.MatchCode>();
- qm.setRow(memstore.get(0).getRow());
+ KeyValue k = memstore.get(0);
+ qm.setRow(k.getBuffer(), k.getRowOffset(), k.getRowLength());
for(KeyValue kv : memstore) {
actual.add(qm.match(kv));
@@ -210,7 +212,8 @@ public class TestQueryMatcher extends HB
new KeyValue(row2, fam1, col1, now-10, data)
};
- qm.setRow(kvs[0].getRow());
+ KeyValue k = kvs[0];
+ qm.setRow(k.getBuffer(), k.getRowOffset(), k.getRowLength());
List<MatchCode> actual = new ArrayList<MatchCode>(kvs.length);
for (KeyValue kv : kvs) {
@@ -262,7 +265,8 @@ public class TestQueryMatcher extends HB
new KeyValue(row1, fam2, col5, now-10000, data),
new KeyValue(row2, fam1, col1, now-10, data)
};
- qm.setRow(kvs[0].getRow());
+ KeyValue k = kvs[0];
+ qm.setRow(k.getBuffer(), k.getRowOffset(), k.getRowLength());
List<ScanQueryMatcher.MatchCode> actual =
new ArrayList<ScanQueryMatcher.MatchCode>(kvs.length);