Author: larsh
Date: Thu Apr  4 06:01:10 2013
New Revision: 1464295

URL: http://svn.apache.org/r1464295
Log:
HBASE-7599  Port HBASE-6066 (low hanging read path improvements) to 0.94 - 
retry (Devaraj Das)

Modified:
    
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/HRegionServer.java

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=1464295&r1=1464294&r2=1464295&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 Apr  4 06:01:10 2013
@@ -3687,7 +3687,6 @@ public class HRegion implements HeapSize
     private final KeyValue KV_LIMIT = new KeyValue();
     private final byte [] stopRow;
     private Filter filter;
-    private List<KeyValue> results = new ArrayList<KeyValue>();
     private int batch;
     private int isScan;
     private boolean filterClosed = false;
@@ -3806,11 +3805,16 @@ public class HRegion implements HeapSize
     @Override
     public boolean nextRaw(List<KeyValue> outResults, int limit,
         String metric) throws IOException {
-      results.clear();
-
-      boolean returnResult = nextInternal(limit, metric);
-
-      outResults.addAll(results);
+      boolean returnResult;
+      if (outResults.isEmpty()) {
+        // Usually outResults is empty. This is true when next is called
+        // to handle scan or get operation.
+        returnResult = nextInternal(outResults, limit, metric);
+      } else {
+        List<KeyValue> tmpList = new ArrayList<KeyValue>();
+        returnResult = nextInternal(tmpList, limit, metric);
+        outResults.addAll(tmpList);
+      }
       resetFilters();
       if (isFilterDone()) {
         return false;
@@ -3832,10 +3836,12 @@ public class HRegion implements HeapSize
       return next(outResults, batch, metric);
     }
 
-    private void populateFromJoinedHeap(int limit, String metric) throws 
IOException {
+    private void populateFromJoinedHeap(List<KeyValue> results, int limit, 
String metric)
+        throws IOException {
       assert joinedContinuationRow != null;
-      KeyValue kv = populateResult(this.joinedHeap, limit, 
joinedContinuationRow.getBuffer(),
-        joinedContinuationRow.getRowOffset(), 
joinedContinuationRow.getRowLength(), metric);
+      KeyValue kv = populateResult(results, this.joinedHeap, limit,
+        joinedContinuationRow.getBuffer(), 
joinedContinuationRow.getRowOffset(),
+        joinedContinuationRow.getRowLength(), metric);
       if (kv != KV_LIMIT) {
         // We are done with this row, reset the continuation.
         joinedContinuationRow = null;
@@ -3847,6 +3853,7 @@ public class HRegion implements HeapSize
 
     /**
      * Fetches records with this row into result list, until next row or limit 
(if not -1).
+     * @param results
      * @param heap KeyValueHeap to fetch data from. It must be positioned on 
correct row before call.
      * @param limit Max amount of KVs to place in result list, -1 means no 
limit.
      * @param currentRow Byte array with key we are fetching.
@@ -3855,8 +3862,8 @@ public class HRegion implements HeapSize
      * @param metric Metric key to be passed into KeyValueHeap::next().
      * @return true if limit reached, false otherwise.
      */
-    private KeyValue populateResult(KeyValueHeap heap, int limit, byte[] 
currentRow, int offset,
-        short length, String metric) throws IOException {
+    private KeyValue populateResult(List<KeyValue> results, KeyValueHeap heap, 
int limit,
+        byte[] currentRow, int offset, short length, String metric) throws 
IOException {
       KeyValue nextKv;
       do {
         heap.next(results, limit - results.size(), metric);
@@ -3875,7 +3882,11 @@ public class HRegion implements HeapSize
       return this.filter != null && this.filter.filterAllRemaining();
     }
 
-    private boolean nextInternal(int limit, String metric) throws IOException {
+    private boolean nextInternal(List<KeyValue> results, int limit, String 
metric)
+    throws IOException {
+      if (!results.isEmpty()) {
+        throw new IllegalArgumentException("First parameter should be an empty 
list");
+      }
       RpcCallContext rpcCall = HBaseServer.getCurrentCall();
       // The loop here is used only when at some point during the next we 
determine
       // that due to effects of filters or otherwise, we have an empty row in 
the result.
@@ -3920,13 +3931,15 @@ public class HRegion implements HeapSize
           // Check if rowkey filter wants to exclude this row. If so, loop to 
next.
           // Techically, if we hit limits before on this row, we don't need 
this call.
           if (filterRowKey(currentRow, offset, length)) {
+            results.clear();
             boolean moreRows = nextRow(currentRow, offset, length);
             if (!moreRows) return false;
             continue;
           }
 
           // Ok, we are good, let's try to get some results from the main heap.
-          KeyValue nextKv = populateResult(this.storeHeap, limit, currentRow, 
offset, length, metric);
+          KeyValue nextKv = populateResult(results, this.storeHeap, limit, 
currentRow, offset,
+              length, metric);
           if (nextKv == KV_LIMIT) {
             if (this.filter != null && filter.hasFilterRow()) {
               throw new IncompatibleFilterException(
@@ -3934,7 +3947,8 @@ public class HRegion implements HeapSize
             }
             return true; // We hit the limit.
           }
-          stopRow = nextKv == null || isStopRow(nextKv.getBuffer(), 
nextKv.getRowOffset(), nextKv.getRowLength());
+          stopRow = nextKv == null
+              || isStopRow(nextKv.getBuffer(), nextKv.getRowOffset(), 
nextKv.getRowLength());
           // save that the row was empty before filters applied to it.
           final boolean isEmptyRow = results.isEmpty();
 
@@ -3945,11 +3959,7 @@ public class HRegion implements HeapSize
           }
 
           if (isEmptyRow || filterRow()) {
-            // this seems like a redundant step - we already consumed the row
-            // there're no left overs.
-            // the reasons for calling this method are:
-            // 1. reset the filters.
-            // 2. provide a hook to fast forward the row (used by subclasses)
+            results.clear();
             boolean moreRows = nextRow(currentRow, offset, length);
             if (!moreRows) return false;
 
@@ -3973,12 +3983,12 @@ public class HRegion implements HeapSize
                   && joinedHeap.peek().matchingRow(currentRow, offset, 
length));
             if (mayHaveData) {
               joinedContinuationRow = current;
-              populateFromJoinedHeap(limit, metric);
+              populateFromJoinedHeap(results, limit, metric);
             }
           }
         } else {
           // Populating from the joined map was stopped by limits, populate 
some more.
-          populateFromJoinedHeap(limit, metric);
+          populateFromJoinedHeap(results, limit, metric);
         }
 
         // We may have just called populateFromJoinedMap and hit the limits. 
If that is
@@ -4015,7 +4025,6 @@ public class HRegion implements HeapSize
       while((next = this.storeHeap.peek()) != null && 
next.matchingRow(currentRow, offset, length)) {
         this.storeHeap.next(MOCKED_LIST);       
       }
-      results.clear();
       resetFilters();
       // Calling the hook in CP which allows it to do a fast forward
       if (this.region.getCoprocessorHost() != null) {

Modified: 
hbase/branches/0.94/src/main/java/org/apache/hadoop/hbase/regionserver/HRegionServer.java
URL: 
http://svn.apache.org/viewvc/hbase/branches/0.94/src/main/java/org/apache/hadoop/hbase/regionserver/HRegionServer.java?rev=1464295&r1=1464294&r2=1464295&view=diff
==============================================================================
--- 
hbase/branches/0.94/src/main/java/org/apache/hadoop/hbase/regionserver/HRegionServer.java
 (original)
+++ 
hbase/branches/0.94/src/main/java/org/apache/hadoop/hbase/regionserver/HRegionServer.java
 Thu Apr  4 06:01:10 2013
@@ -2570,8 +2570,10 @@ public class HRegionServer implements HR
             results, nbRows);
         if (!results.isEmpty()) {
           for (Result r : results) {
-            for (KeyValue kv : r.raw()) {
-              currentScanResultSize += kv.heapSize();
+            if (maxScannerResultSize < Long.MAX_VALUE){
+              for (KeyValue kv : r.raw()) {
+                currentScanResultSize += kv.heapSize();
+              }
             }
           }
         }
@@ -2591,8 +2593,10 @@ public class HRegionServer implements HR
             // Collect values to be returned here
             boolean moreRows = s.nextRaw(values, 
SchemaMetrics.METRIC_NEXTSIZE);
             if (!values.isEmpty()) {
-              for (KeyValue kv : values) {
-                currentScanResultSize += kv.heapSize();
+              if (maxScannerResultSize < Long.MAX_VALUE){
+                for (KeyValue kv : values) {
+                  currentScanResultSize += kv.heapSize();
+                }
               }
               results.add(new Result(values));
             }


Reply via email to