You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@trafodion.apache.org by db...@apache.org on 2017/08/17 16:45:19 UTC

[1/6] incubator-trafodion git commit: [TRAFODION-2617] Optionally push estimate row count logic into HBase coproc

Repository: incubator-trafodion
Updated Branches:
  refs/heads/master baa034f89 -> 548ff71b4


http://git-wip-us.apache.org/repos/asf/incubator-trafodion/blob/8b93ad50/core/sqf/src/seatrans/hbase-trx/src/main/protobuf/TrxRegion.proto
----------------------------------------------------------------------
diff --git a/core/sqf/src/seatrans/hbase-trx/src/main/protobuf/TrxRegion.proto b/core/sqf/src/seatrans/hbase-trx/src/main/protobuf/TrxRegion.proto
index a69e6b8..b3edbfa 100755
--- a/core/sqf/src/seatrans/hbase-trx/src/main/protobuf/TrxRegion.proto
+++ b/core/sqf/src/seatrans/hbase-trx/src/main/protobuf/TrxRegion.proto
@@ -404,6 +404,23 @@ message TlogTransactionStatesFromIntervalResponse {
   optional bool hasException = 4;
 }
 
+message TrafEstimateRowCountRequest {
+  // numCols = 1 for aligned tables; = # columns for non-aligned tables
+  required int32 numCols = 1;  
+}
+
+message TrafEstimateRowCountResponse {
+  required int64 totalEntries = 1;
+  required int64 totalSizeBytes = 2;
+  // the next three values will be non-zero only for the first region,
+  // and only when the format is non-aligned
+  required int32 putKVsSampled = 3;
+  required int32 nonPutKVsSampled = 4;
+  required int32 missingKVsCount = 5;
+  optional string exception = 6;
+  optional bool hasException = 7;
+}
+
 message TransactionalAggregateRequest {
   /** The request passed to the TransactionalAggregateService consists of three parts
    *  (1) the (canonical) classname of the ColumnInterpreter implementation
@@ -510,6 +527,8 @@ service TrxRegionService {
     returns(TlogWriteResponse);
   rpc getTransactionStatesPriorToAsn(TlogTransactionStatesFromIntervalRequest)
     returns(TlogTransactionStatesFromIntervalResponse);
+  rpc trafEstimateRowCount(TrafEstimateRowCountRequest)
+    returns(TrafEstimateRowCountResponse);
   rpc GetMax (TransactionalAggregateRequest)
     returns (TransactionalAggregateResponse);
   rpc GetMin (TransactionalAggregateRequest) 

http://git-wip-us.apache.org/repos/asf/incubator-trafodion/blob/8b93ad50/core/sql/executor/HBaseClient_JNI.cpp
----------------------------------------------------------------------
diff --git a/core/sql/executor/HBaseClient_JNI.cpp b/core/sql/executor/HBaseClient_JNI.cpp
index f5ca420..da05b6c 100644
--- a/core/sql/executor/HBaseClient_JNI.cpp
+++ b/core/sql/executor/HBaseClient_JNI.cpp
@@ -250,6 +250,8 @@ HBC_RetCode HBaseClient_JNI::init()
     JavaMethods_[JM_GET_HBLC   ].jm_signature = "()Lorg/trafodion/sql/HBulkLoadClient;";
     JavaMethods_[JM_EST_RC     ].jm_name      = "estimateRowCount";
     JavaMethods_[JM_EST_RC     ].jm_signature = "(Ljava/lang/String;III[J)Z";
+    JavaMethods_[JM_EST_RC_COPROC     ].jm_name      = "estimateRowCountViaCoprocessor";
+    JavaMethods_[JM_EST_RC_COPROC     ].jm_signature = "(Ljava/lang/String;III[J)Z";
     JavaMethods_[JM_REL_HBLC   ].jm_name      = "releaseHBulkLoadClient";
     JavaMethods_[JM_REL_HBLC   ].jm_signature = "(Lorg/trafodion/sql/HBulkLoadClient;)V";
     JavaMethods_[JM_GET_CAC_FRC].jm_name      = "getBlockCacheFraction";
@@ -1339,6 +1341,7 @@ HBC_RetCode HBaseClient_JNI::estimateRowCount(const char* tblName,
                                               Int32 partialRowSize,
                                               Int32 numCols,
                                               Int32 retryLimitMilliSeconds,
+                                              NABoolean useCoprocessor,
                                               Int64& rowCount,
                                               Int32& breadCrumb)
 {
@@ -1364,8 +1367,9 @@ HBC_RetCode HBaseClient_JNI::estimateRowCount(const char* tblName,
   jint jNumCols = numCols;
   jint jRetryLimitMilliSeconds = retryLimitMilliSeconds;
   jlongArray jRowCount = jenv_->NewLongArray(1);
-  tsRecentJMFromJNI = JavaMethods_[JM_EST_RC].jm_full_name;
-  jboolean jresult = jenv_->CallBooleanMethod(javaObj_, JavaMethods_[JM_EST_RC].methodID,
+  enum JAVA_METHODS method = (useCoprocessor ? JM_EST_RC_COPROC : JM_EST_RC);
+  tsRecentJMFromJNI = JavaMethods_[method].jm_full_name;
+  jboolean jresult = jenv_->CallBooleanMethod(javaObj_, JavaMethods_[method].methodID,
                                               js_tblName, jPartialRowSize,
                                               jNumCols, jRetryLimitMilliSeconds, jRowCount);
   jboolean isCopy;

http://git-wip-us.apache.org/repos/asf/incubator-trafodion/blob/8b93ad50/core/sql/executor/HBaseClient_JNI.h
----------------------------------------------------------------------
diff --git a/core/sql/executor/HBaseClient_JNI.h b/core/sql/executor/HBaseClient_JNI.h
index ea957e7..09e495a 100644
--- a/core/sql/executor/HBaseClient_JNI.h
+++ b/core/sql/executor/HBaseClient_JNI.h
@@ -458,7 +458,8 @@ public:
   HBC_RetCode grant(const Text& user, const Text& tableName, const TextVec& actionCodes); 
   HBC_RetCode revoke(const Text& user, const Text& tableName, const TextVec& actionCodes);
   HBC_RetCode estimateRowCount(const char* tblName, Int32 partialRowSize,
-                               Int32 numCols, Int32 retryLimitMilliSeconds, Int64& rowCount, Int32 & breadCrumb);
+                               Int32 numCols, Int32 retryLimitMilliSeconds, NABoolean useCoprocessor,
+                               Int64& rowCount, Int32 & breadCrumb);
   HBC_RetCode getLatestSnapshot(const char * tabname, char *& snapshotName, NAHeap * heap);
   HBC_RetCode cleanSnpTmpLocation(const char * path);
   HBC_RetCode setArchivePermissions(const char * path);
@@ -556,6 +557,7 @@ private:
    ,JM_REVOKE
    ,JM_GET_HBLC
    ,JM_EST_RC
+   ,JM_EST_RC_COPROC
    ,JM_REL_HBLC
    ,JM_GET_CAC_FRC
    ,JM_GET_LATEST_SNP

http://git-wip-us.apache.org/repos/asf/incubator-trafodion/blob/8b93ad50/core/sql/exp/ExpHbaseInterface.cpp
----------------------------------------------------------------------
diff --git a/core/sql/exp/ExpHbaseInterface.cpp b/core/sql/exp/ExpHbaseInterface.cpp
index 248e089..22b3c50 100644
--- a/core/sql/exp/ExpHbaseInterface.cpp
+++ b/core/sql/exp/ExpHbaseInterface.cpp
@@ -1490,6 +1490,7 @@ Lng32 ExpHbaseInterface_JNI::estimateRowCount(HbaseStr& tblName,
                                               Int32 partialRowSize,
                                               Int32 numCols,
                                               Int32 retryLimitMilliSeconds,
+                                              NABoolean useCoprocessor,
                                               Int64& estRC,
                                               Int32& breadCrumb)
 {
@@ -1503,7 +1504,8 @@ Lng32 ExpHbaseInterface_JNI::estimateRowCount(HbaseStr& tblName,
 
   estRC = 0;
   retCode_ = client_->estimateRowCount(tblName.val, partialRowSize, numCols, 
-                                       retryLimitMilliSeconds, estRC, breadCrumb /* out */);
+                                       retryLimitMilliSeconds, useCoprocessor,
+                                       estRC, breadCrumb /* out */);
   return retCode_;
 }
 

http://git-wip-us.apache.org/repos/asf/incubator-trafodion/blob/8b93ad50/core/sql/exp/ExpHbaseInterface.h
----------------------------------------------------------------------
diff --git a/core/sql/exp/ExpHbaseInterface.h b/core/sql/exp/ExpHbaseInterface.h
index 5f44e9c..daba401 100644
--- a/core/sql/exp/ExpHbaseInterface.h
+++ b/core/sql/exp/ExpHbaseInterface.h
@@ -356,6 +356,7 @@ class ExpHbaseInterface : public NABasicObject
                                  Int32 partialRowSize,
                                  Int32 numCols,
                                  Int32 retryLimitMilliSeconds,
+                                 NABoolean useCoprocessor,
                                  Int64& estRC,
                                  Int32& breadCrumb) = 0;
   virtual Lng32 getLatestSnapshot(const char * tableName, char *& snapshotName, NAHeap * heap) = 0;
@@ -670,6 +671,7 @@ virtual Lng32 initHFileParams(HbaseStr &tblName,
                                  Int32 partialRowSize,
                                  Int32 numCols,
                                  Int32 retryLimitMilliSeconds,
+                                 NABoolean useCoprocessor,
                                  Int64& estRC,
                                  Int32& breadCrumb);
 

http://git-wip-us.apache.org/repos/asf/incubator-trafodion/blob/8b93ad50/core/sql/optimizer/NATable.cpp
----------------------------------------------------------------------
diff --git a/core/sql/optimizer/NATable.cpp b/core/sql/optimizer/NATable.cpp
index 4b65ef4..0da775e 100644
--- a/core/sql/optimizer/NATable.cpp
+++ b/core/sql/optimizer/NATable.cpp
@@ -7883,11 +7883,21 @@ Int64 NATable::estimateHBaseRowCount(Int32 retryLimitMilliSeconds, Int32& errorC
       fqTblName.val[fqTblName.len] = '\0';
 
       Int32 partialRowSize = computeHBaseRowSizeFromMetaData();
+      NABoolean useCoprocessor = 
+        (CmpCommon::getDefault(HBASE_ESTIMATE_ROW_COUNT_VIA_COPROCESSOR) == DF_ON);
+
+      // Note: If in the future we support a hybrid parially aligned +
+      // partially non-aligned format, the following has to be revised.
+      CollIndex keyValueCountPerRow = 1;  // assume aligned format
+      if (!isAlignedFormat(NULL))
+        keyValueCountPerRow = colcount_;  // non-aligned; each column is a separate KV
+
       errorCode = ehi->estimateRowCount(fqTblName,
                                       partialRowSize,
-                                      colcount_,
+                                      keyValueCountPerRow,
                                       retryLimitMilliSeconds,
-                                      estRowCount,
+                                      useCoprocessor,
+                                      estRowCount /* out */,
                                       breadCrumb /* out */);
       NADELETEBASIC(fqTblName.val, STMTHEAP);
 

http://git-wip-us.apache.org/repos/asf/incubator-trafodion/blob/8b93ad50/core/sql/sqlcomp/DefaultConstants.h
----------------------------------------------------------------------
diff --git a/core/sql/sqlcomp/DefaultConstants.h b/core/sql/sqlcomp/DefaultConstants.h
index 34832fb..71176a6 100644
--- a/core/sql/sqlcomp/DefaultConstants.h
+++ b/core/sql/sqlcomp/DefaultConstants.h
@@ -3413,6 +3413,10 @@ enum DefaultConstants
   // if ON, hbase coprocessors could be used, if the query allows it.
   HBASE_COPROCESSORS,
 
+  // if ON, use an HBase coprocessor when estimating row counts; if OFF use
+  // client-side code (the latter does not work if HBase encryption is in use)
+  HBASE_ESTIMATE_ROW_COUNT_VIA_COPROCESSOR,
+
   // if OFF or '0' is disabled, ON or '1' is simple pushdown, '2' is for advance pushdown
   // It will depends on the query on which predicates or sub-predicates could be pushed.
   HBASE_FILTER_PREDS,

http://git-wip-us.apache.org/repos/asf/incubator-trafodion/blob/8b93ad50/core/sql/sqlcomp/nadefaults.cpp
----------------------------------------------------------------------
diff --git a/core/sql/sqlcomp/nadefaults.cpp b/core/sql/sqlcomp/nadefaults.cpp
index 431447b..5603ca3 100644
--- a/core/sql/sqlcomp/nadefaults.cpp
+++ b/core/sql/sqlcomp/nadefaults.cpp
@@ -1732,6 +1732,10 @@ SDDkwd__(EXE_DIAGNOSTIC_EVENTS,		"OFF"),
   // HBASE_CATALOG:                Catalog of "_ROW_" and "_CELL_" schemas
   // HBASE_COPROCESSORS:           Enable use of co-processors for aggregates.
   //                               need to set the coprocessor in HBase config file
+  // HBASE_ESTIMATE_ROW_COUNT_VIA_COPROCESSOR:  If ON, use a coprocessor when
+  //                               estimating row counts; if OFF, use client side
+  //                               code (the latter doesn't work if HBase encryption
+  //                               is being used)
   // HBASE_INTERFACE:              JNI or JNI_TRX (transactional interface)
   // HBASE_MAX_COLUMN_xxx_LENGTH:  Max length of some
   //                               string columns in the "_ROW_" and "_CELL_" schemas
@@ -1759,6 +1763,7 @@ SDDkwd__(EXE_DIAGNOSTIC_EVENTS,		"OFF"),
  // exposure.
  DDkwd__(HBASE_DELETE_COSTING,		             "ON"),
  DDflt0_(HBASE_DOP_PARALLEL_SCANNER,             "0."),
+ DDkwd__(HBASE_ESTIMATE_ROW_COUNT_VIA_COPROCESSOR,   "OFF"),
  DDkwd__(HBASE_FILTER_PREDS,		             "OFF"),
  DDkwd__(HBASE_HASH2_PARTITIONING,                   "ON"),
  DDui___(HBASE_INDEX_LEVEL,                          "0"),

http://git-wip-us.apache.org/repos/asf/incubator-trafodion/blob/8b93ad50/core/sql/src/main/java/org/trafodion/sql/HBaseClient.java
----------------------------------------------------------------------
diff --git a/core/sql/src/main/java/org/trafodion/sql/HBaseClient.java b/core/sql/src/main/java/org/trafodion/sql/HBaseClient.java
index f23dd70..72fa0af 100644
--- a/core/sql/src/main/java/org/trafodion/sql/HBaseClient.java
+++ b/core/sql/src/main/java/org/trafodion/sql/HBaseClient.java
@@ -41,6 +41,10 @@ import org.apache.hadoop.fs.FileSystem;
 import org.apache.hadoop.hbase.client.ConnectionFactory;
 import org.apache.hadoop.hbase.client.Connection;
 import org.apache.hadoop.hbase.client.Admin;
+import org.apache.hadoop.hbase.client.coprocessor.Batch;
+import org.apache.hadoop.hbase.client.HConnection;
+import org.apache.hadoop.hbase.client.HConnectionManager;
+import org.apache.hadoop.hbase.client.HTableInterface;
 import org.apache.hadoop.hbase.HTableDescriptor;
 import org.apache.hadoop.hbase.HColumnDescriptor;
 import org.apache.hadoop.hbase.KeyValue;
@@ -100,8 +104,22 @@ import org.apache.hadoop.hbase.client.DtmConst;
 import org.apache.commons.codec.binary.Hex;
 import org.apache.hadoop.hbase.util.CompressionTest;
 
+import com.google.protobuf.ByteString;
+import com.google.protobuf.Message;
+import com.google.protobuf.RpcCallback;
+import com.google.protobuf.RpcController;
+import com.google.protobuf.Service;
 import com.google.protobuf.ServiceException;
 
+import org.apache.hadoop.hbase.ipc.BlockingRpcCallback;
+import org.apache.hadoop.hbase.ipc.ServerRpcController;
+
+import org.apache.hadoop.hbase.coprocessor.transactional.generated.TrxRegionProtos;
+import org.apache.hadoop.hbase.coprocessor.transactional.generated.TrxRegionProtos.TrafEstimateRowCountRequest;
+import org.apache.hadoop.hbase.coprocessor.transactional.generated.TrxRegionProtos.TrafEstimateRowCountResponse;
+import org.apache.hadoop.hbase.coprocessor.transactional.generated.TrxRegionProtos.TrxRegionService;
+
+
 public class HBaseClient {
 
     static Logger logger = Logger.getLogger(HBaseClient.class.getName());
@@ -1051,6 +1069,8 @@ public class HBaseClient {
     // columns in the table) to the size of the HFile.
     private long estimateMemStoreRows(String tblName, int rowSize)
                  throws MasterNotRunningException, IOException {
+      if (logger.isDebugEnabled()) logger.debug("estimateMemStoreRows called for " + tblName + " with row size " + rowSize);
+
       if (rowSize == 0)
         return 0;
 
@@ -1086,6 +1106,12 @@ public class HBaseClient {
           }
         }
       }
+      catch (IOException e) {
+        if (logger.isDebugEnabled()) logger.debug("IOException caught in estimateMemStoreRows: " + e);
+      }
+      catch (Throwable e) {
+        if (logger.isDebugEnabled()) logger.debug("Throwable caught in estimateMemStoreRows: " + e);
+      }
       finally {
         admin.close();
       }
@@ -1255,6 +1281,7 @@ public class HBaseClient {
                                tblName + "/" + REGION_NAME_PATTERN +
                                "/#1/" + HFILE_NAME_PATTERN));
       for (FileStatus fs : fsArr) {
+        if (logger.isDebugEnabled()) logger.debug("Estimate row count is processing file " + fs.getPath());
         // Make sure the file name conforms to HFile name pattern.
         if (!StoreFileInfo.isHFile(fs.getPath())) {
           if (logger.isDebugEnabled()) logger.debug("Skipped file " + fs.getPath() + " -- not a valid HFile name.");
@@ -1395,6 +1422,169 @@ public class HBaseClient {
       return true;
     }
 
+    // Similar to estimateRowCount, except that the implementation
+    // uses a coprocessor. This is necessary when HBase encryption is
+    // in use, because the Trafodion ID does not have the proper 
+    // authorization to the KeyStore file used by HBase.
+    public boolean estimateRowCountViaCoprocessor(String tblName, int partialRowSize,
+                                    int numCols, int retryLimitMilliSeconds, long[] rc)
+                   throws ServiceException, IOException {
+      if (logger.isDebugEnabled()) {
+        logger.debug("HBaseClient.estimateRowCountViaCoprocessor(" + tblName + ") called.");
+        logger.debug("numCols = " + numCols + ", partialRowSize = " + partialRowSize);
+      }
+
+      boolean retcode = true; 
+      rc[0] = 0;
+
+      HConnection connection = null;
+      HTableInterface table = null; 
+      connection = HConnectionManager.createConnection(config);
+      table = connection.getTable(tblName);
+
+      int putKVsSampled = 0;
+      int nonPutKVsSampled = 0;
+      int missingKVsCount = 0;
+      long totalEntries = 0;   // KeyValues in all HFiles for table
+      long totalSizeBytes = 0; // Size of all HFiles for table 
+
+      final int finalNumCols = numCols;
+
+      Batch.Call<TrxRegionService, TrafEstimateRowCountResponse> callable = 
+        new Batch.Call<TrxRegionService, TrafEstimateRowCountResponse>() {
+          ServerRpcController controller = new ServerRpcController();
+          BlockingRpcCallback<TrafEstimateRowCountResponse> rpcCallback = 
+            new BlockingRpcCallback<TrafEstimateRowCountResponse>();         
+
+          @Override
+          public TrafEstimateRowCountResponse call(TrxRegionService instance) throws IOException {    
+            if (logger.isDebugEnabled()) logger.debug("call method for TrxRegionService was called");
+            
+            // one of these God-awful long type identifiers common in Java/Maven environments...
+            org.apache.hadoop.hbase.coprocessor.transactional.generated.TrxRegionProtos.TrafEstimateRowCountRequest.Builder
+              builder = TrafEstimateRowCountRequest.newBuilder();        
+            builder.setNumCols(finalNumCols);
+        
+            instance.trafEstimateRowCount(controller, builder.build(), rpcCallback);
+            TrafEstimateRowCountResponse response = rpcCallback.get();
+            if (logger.isDebugEnabled()) {
+              if (response == null)
+                logger.debug("response was null");
+              else
+                logger.debug("response was non-null");
+              if (controller.failed())
+                logger.debug("controller.failed() is true");
+              else
+                logger.debug("controller.failed() is false");
+              if (controller.errorText() != null)
+                logger.debug("controller.errorText() is " + controller.errorText());
+              else
+                logger.debug("controller.errorText() is null");
+              IOException ioe = controller.getFailedOn();
+              if (ioe != null)
+                logger.debug("controller.getFailedOn() returned " + ioe.getMessage());
+              else
+                logger.debug("controller.getFailedOn() returned null");
+            }
+            return response;        
+          }
+      };
+    
+      Map<byte[], TrafEstimateRowCountResponse> result = null;
+      try {
+        result = table.coprocessorService(TrxRegionService.class, null, null, callable);
+      } catch (Throwable e) {
+        throw new IOException("Exception from coprocessorService caught in estimateRowCountViaCoprocessor",e);
+      }      
+
+      for (TrafEstimateRowCountResponse response : result.values()) {
+        boolean hasException = response.getHasException();
+        String exception = response.getException();
+        if (hasException) {
+          if (logger.isDebugEnabled()) logger.debug("HBaseClient.estimateRowCountViaCoprocessor exception " + exception);
+          throw new IOException(exception);
+        }
+        totalEntries = totalEntries + response.getTotalEntries();
+        totalSizeBytes = totalSizeBytes + response.getTotalSizeBytes();
+        putKVsSampled = putKVsSampled + response.getPutKVsSampled();
+        nonPutKVsSampled = nonPutKVsSampled + response.getNonPutKVsSampled();
+        missingKVsCount = missingKVsCount + response.getMissingKVsCount();
+      }
+
+      if (logger.isDebugEnabled()) { 
+        logger.debug("The coprocessor service for estimating row count returned " + result.size() + " messages.");
+        logger.debug("totalEntries = " + totalEntries + ", totalSizeBytes = " + totalSizeBytes);
+        logger.debug("putKVsSampled = " + putKVsSampled + ", nonPutKVsSampled = " + nonPutKVsSampled +
+                     ", missingKVsCount = " + missingKVsCount);
+      }
+
+      final int ROWS_TO_SAMPLE = 500;
+      long estimatedEntries = ((ROWS_TO_SAMPLE > 0) && (numCols > 1)
+                                 ? 0               // get from sample data, below
+                                 : totalEntries);  // no sampling, use stored value
+      if (putKVsSampled > 0) // avoid div by 0 if no Put KVs in sample
+        {
+          long estimatedTotalPuts = (putKVsSampled * totalEntries) / 
+                               (putKVsSampled + nonPutKVsSampled);
+          estimatedEntries = ((putKVsSampled + missingKVsCount) * estimatedTotalPuts)
+                                   / putKVsSampled;
+        }
+
+      if (logger.isDebugEnabled()) { 
+        logger.debug("estimatedEntries = " + estimatedEntries + ", numCols = " + numCols);
+      } 
+
+      // Calculate estimate of rows in all HFiles of table.
+      rc[0] = (estimatedEntries + (numCols/2)) / numCols; // round instead of truncate
+
+      if (logger.isDebugEnabled()) { 
+        logger.debug("rc[0] = " + rc[0]);
+      }       
+
+      // Estimate # of rows in MemStores of all regions of table. Pass
+      // a value to divide the size of the MemStore by. Base this on the
+      // ratio of bytes-to-rows in the HFiles, or the actual row size if
+      // the HFiles were empty.
+      int rowSize;
+
+      if (rc[0] > 0)
+        rowSize = (int)(totalSizeBytes / rc[0]);
+      else {
+        // From Traf metadata we have calculated and passed in part of the row
+        // size, including size of column qualifiers (col names), which are not
+        // known to HBase.  Add to this the length of the fixed part of the
+        // KeyValue format, times the number of columns.
+        int fixedSizePartOfKV = KeyValue.KEYVALUE_INFRASTRUCTURE_SIZE // key len + value len
+                              + KeyValue.KEY_INFRASTRUCTURE_SIZE;     // rowkey & col family len, timestamp, key type
+        rowSize = partialRowSize   // for all cols: row key + col qualifiers + values
+                      + (fixedSizePartOfKV * numCols);
+
+
+        // Trafodion tables have a single col family at present, so we only look
+        // at the first family name, and multiply its length times the number of
+        // columns. Even if more than one family is used in the future, presumably
+        // they will all be the same short size.
+        Table htbl = getConnection().getTable(TableName.valueOf(tblName));
+        //HTable htbl = new HTable(config, tblName);
+        HTableDescriptor htblDesc = htbl.getTableDescriptor();
+        HColumnDescriptor[] families = htblDesc.getColumnFamilies();
+        rowSize += (families[0].getName().length * numCols);
+      }
+
+      // Get the estimate of MemStore rows
+      long memStoreRows = estimateMemStoreRows(tblName, rowSize);
+
+      if (logger.isDebugEnabled()) {
+        logger.debug("Estimated row count from HFiles = " + rc[0]);
+        logger.debug("Estimated row count from MemStores = " + memStoreRows);
+      }
+
+      rc[0] += memStoreRows;  // Add memstore estimate to total
+      if (logger.isDebugEnabled()) logger.debug("Total estimated row count for " + tblName + " = " + rc[0]);
+
+      return retcode;
+    }
+
 
     /**
     This method returns node names where Hbase Table regions reside


[2/6] incubator-trafodion git commit: [TRAFODION-2617] Optionally push estimate row count logic into HBase coproc

Posted by db...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-trafodion/blob/8b93ad50/core/sqf/src/seatrans/hbase-trx/src/main/java/org/apache/hadoop/hbase/coprocessor/transactional/generated/TrxRegionProtos.java
----------------------------------------------------------------------
diff --git a/core/sqf/src/seatrans/hbase-trx/src/main/java/org/apache/hadoop/hbase/coprocessor/transactional/generated/TrxRegionProtos.java b/core/sqf/src/seatrans/hbase-trx/src/main/java/org/apache/hadoop/hbase/coprocessor/transactional/generated/TrxRegionProtos.java
index bace23f..0b5af74 100755
--- a/core/sqf/src/seatrans/hbase-trx/src/main/java/org/apache/hadoop/hbase/coprocessor/transactional/generated/TrxRegionProtos.java
+++ b/core/sqf/src/seatrans/hbase-trx/src/main/java/org/apache/hadoop/hbase/coprocessor/transactional/generated/TrxRegionProtos.java
@@ -1,26 +1,3 @@
-/**
- * * @@@ START COPYRIGHT @@@
- * *
- * * Licensed to the Apache Software Foundation (ASF) under one
- * * or more contributor license agreements.  See the NOTICE file
- * * distributed with this work for additional information
- * * regarding copyright ownership.  The ASF licenses this file
- * * to you under the Apache License, Version 2.0 (the
- * * "License"); you may not use this file except in compliance
- * * with the License.  You may obtain a copy of the License at
- * *
- * *   http://www.apache.org/licenses/LICENSE-2.0
- * *
- * * Unless required by applicable law or agreed to in writing,
- * * software distributed under the License is distributed on an
- * * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * * KIND, either express or implied.  See the License for the
- * * specific language governing permissions and limitations
- * * under the License.
- * *
- * * @@@ END COPYRIGHT @@@
- * **/
-
 // Generated by the protocol buffer compiler.  DO NOT EDIT!
 // source: TrxRegion.proto
 
@@ -41635,113 +41612,549 @@ public final class TrxRegionProtos {
     // @@protoc_insertion_point(class_scope:TlogTransactionStatesFromIntervalResponse)
   }
 
-  public interface TransactionalAggregateRequestOrBuilder
+  public interface TrafEstimateRowCountRequestOrBuilder
       extends com.google.protobuf.MessageOrBuilder {
 
-    // required bytes regionName = 1;
+    // required int32 numCols = 1;
     /**
-     * <code>required bytes regionName = 1;</code>
+     * <code>required int32 numCols = 1;</code>
      *
      * <pre>
-     ** The request passed to the TransactionalAggregateService consists of three parts
-     *  (1) the (canonical) classname of the ColumnInterpreter implementation
-     *  (2) the Scan query
-     *  (3) any bytes required to construct the ColumnInterpreter object
-     *      properly
+     * numCols = 1 for aligned tables; = # columns for non-aligned tables
      * </pre>
      */
-    boolean hasRegionName();
+    boolean hasNumCols();
     /**
-     * <code>required bytes regionName = 1;</code>
+     * <code>required int32 numCols = 1;</code>
      *
      * <pre>
-     ** The request passed to the TransactionalAggregateService consists of three parts
-     *  (1) the (canonical) classname of the ColumnInterpreter implementation
-     *  (2) the Scan query
-     *  (3) any bytes required to construct the ColumnInterpreter object
-     *      properly
+     * numCols = 1 for aligned tables; = # columns for non-aligned tables
      * </pre>
      */
-    com.google.protobuf.ByteString getRegionName();
+    int getNumCols();
+  }
+  /**
+   * Protobuf type {@code TrafEstimateRowCountRequest}
+   */
+  public static final class TrafEstimateRowCountRequest extends
+      com.google.protobuf.GeneratedMessage
+      implements TrafEstimateRowCountRequestOrBuilder {
+    // Use TrafEstimateRowCountRequest.newBuilder() to construct.
+    private TrafEstimateRowCountRequest(com.google.protobuf.GeneratedMessage.Builder<?> builder) {
+      super(builder);
+      this.unknownFields = builder.getUnknownFields();
+    }
+    private TrafEstimateRowCountRequest(boolean noInit) { this.unknownFields = com.google.protobuf.UnknownFieldSet.getDefaultInstance(); }
 
-    // required int64 transactionId = 2;
+    private static final TrafEstimateRowCountRequest defaultInstance;
+    public static TrafEstimateRowCountRequest getDefaultInstance() {
+      return defaultInstance;
+    }
+
+    public TrafEstimateRowCountRequest getDefaultInstanceForType() {
+      return defaultInstance;
+    }
+
+    private final com.google.protobuf.UnknownFieldSet unknownFields;
+    @java.lang.Override
+    public final com.google.protobuf.UnknownFieldSet
+        getUnknownFields() {
+      return this.unknownFields;
+    }
+    private TrafEstimateRowCountRequest(
+        com.google.protobuf.CodedInputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      initFields();
+      int mutable_bitField0_ = 0;
+      com.google.protobuf.UnknownFieldSet.Builder unknownFields =
+          com.google.protobuf.UnknownFieldSet.newBuilder();
+      try {
+        boolean done = false;
+        while (!done) {
+          int tag = input.readTag();
+          switch (tag) {
+            case 0:
+              done = true;
+              break;
+            default: {
+              if (!parseUnknownField(input, unknownFields,
+                                     extensionRegistry, tag)) {
+                done = true;
+              }
+              break;
+            }
+            case 8: {
+              bitField0_ |= 0x00000001;
+              numCols_ = input.readInt32();
+              break;
+            }
+          }
+        }
+      } catch (com.google.protobuf.InvalidProtocolBufferException e) {
+        throw e.setUnfinishedMessage(this);
+      } catch (java.io.IOException e) {
+        throw new com.google.protobuf.InvalidProtocolBufferException(
+            e.getMessage()).setUnfinishedMessage(this);
+      } finally {
+        this.unknownFields = unknownFields.build();
+        makeExtensionsImmutable();
+      }
+    }
+    public static final com.google.protobuf.Descriptors.Descriptor
+        getDescriptor() {
+      return org.apache.hadoop.hbase.coprocessor.transactional.generated.TrxRegionProtos.internal_static_TrafEstimateRowCountRequest_descriptor;
+    }
+
+    protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
+        internalGetFieldAccessorTable() {
+      return org.apache.hadoop.hbase.coprocessor.transactional.generated.TrxRegionProtos.internal_static_TrafEstimateRowCountRequest_fieldAccessorTable
+          .ensureFieldAccessorsInitialized(
+              org.apache.hadoop.hbase.coprocessor.transactional.generated.TrxRegionProtos.TrafEstimateRowCountRequest.class, org.apache.hadoop.hbase.coprocessor.transactional.generated.TrxRegionProtos.TrafEstimateRowCountRequest.Builder.class);
+    }
+
+    public static com.google.protobuf.Parser<TrafEstimateRowCountRequest> PARSER =
+        new com.google.protobuf.AbstractParser<TrafEstimateRowCountRequest>() {
+      public TrafEstimateRowCountRequest parsePartialFrom(
+          com.google.protobuf.CodedInputStream input,
+          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+          throws com.google.protobuf.InvalidProtocolBufferException {
+        return new TrafEstimateRowCountRequest(input, extensionRegistry);
+      }
+    };
+
+    @java.lang.Override
+    public com.google.protobuf.Parser<TrafEstimateRowCountRequest> getParserForType() {
+      return PARSER;
+    }
+
+    private int bitField0_;
+    // required int32 numCols = 1;
+    public static final int NUMCOLS_FIELD_NUMBER = 1;
+    private int numCols_;
     /**
-     * <code>required int64 transactionId = 2;</code>
+     * <code>required int32 numCols = 1;</code>
+     *
+     * <pre>
+     * numCols = 1 for aligned tables; = # columns for non-aligned tables
+     * </pre>
      */
-    boolean hasTransactionId();
+    public boolean hasNumCols() {
+      return ((bitField0_ & 0x00000001) == 0x00000001);
+    }
     /**
-     * <code>required int64 transactionId = 2;</code>
+     * <code>required int32 numCols = 1;</code>
+     *
+     * <pre>
+     * numCols = 1 for aligned tables; = # columns for non-aligned tables
+     * </pre>
      */
-    long getTransactionId();
+    public int getNumCols() {
+      return numCols_;
+    }
 
-    // required int64 startId = 3;
+    private void initFields() {
+      numCols_ = 0;
+    }
+    private byte memoizedIsInitialized = -1;
+    public final boolean isInitialized() {
+      byte isInitialized = memoizedIsInitialized;
+      if (isInitialized != -1) return isInitialized == 1;
+
+      if (!hasNumCols()) {
+        memoizedIsInitialized = 0;
+        return false;
+      }
+      memoizedIsInitialized = 1;
+      return true;
+    }
+
+    public void writeTo(com.google.protobuf.CodedOutputStream output)
+                        throws java.io.IOException {
+      getSerializedSize();
+      if (((bitField0_ & 0x00000001) == 0x00000001)) {
+        output.writeInt32(1, numCols_);
+      }
+      getUnknownFields().writeTo(output);
+    }
+
+    private int memoizedSerializedSize = -1;
+    public int getSerializedSize() {
+      int size = memoizedSerializedSize;
+      if (size != -1) return size;
+
+      size = 0;
+      if (((bitField0_ & 0x00000001) == 0x00000001)) {
+        size += com.google.protobuf.CodedOutputStream
+          .computeInt32Size(1, numCols_);
+      }
+      size += getUnknownFields().getSerializedSize();
+      memoizedSerializedSize = size;
+      return size;
+    }
+
+    private static final long serialVersionUID = 0L;
+    @java.lang.Override
+    protected java.lang.Object writeReplace()
+        throws java.io.ObjectStreamException {
+      return super.writeReplace();
+    }
+
+    public static org.apache.hadoop.hbase.coprocessor.transactional.generated.TrxRegionProtos.TrafEstimateRowCountRequest parseFrom(
+        com.google.protobuf.ByteString data)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data);
+    }
+    public static org.apache.hadoop.hbase.coprocessor.transactional.generated.TrxRegionProtos.TrafEstimateRowCountRequest parseFrom(
+        com.google.protobuf.ByteString data,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data, extensionRegistry);
+    }
+    public static org.apache.hadoop.hbase.coprocessor.transactional.generated.TrxRegionProtos.TrafEstimateRowCountRequest parseFrom(byte[] data)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data);
+    }
+    public static org.apache.hadoop.hbase.coprocessor.transactional.generated.TrxRegionProtos.TrafEstimateRowCountRequest parseFrom(
+        byte[] data,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data, extensionRegistry);
+    }
+    public static org.apache.hadoop.hbase.coprocessor.transactional.generated.TrxRegionProtos.TrafEstimateRowCountRequest parseFrom(java.io.InputStream input)
+        throws java.io.IOException {
+      return PARSER.parseFrom(input);
+    }
+    public static org.apache.hadoop.hbase.coprocessor.transactional.generated.TrxRegionProtos.TrafEstimateRowCountRequest parseFrom(
+        java.io.InputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws java.io.IOException {
+      return PARSER.parseFrom(input, extensionRegistry);
+    }
+    public static org.apache.hadoop.hbase.coprocessor.transactional.generated.TrxRegionProtos.TrafEstimateRowCountRequest parseDelimitedFrom(java.io.InputStream input)
+        throws java.io.IOException {
+      return PARSER.parseDelimitedFrom(input);
+    }
+    public static org.apache.hadoop.hbase.coprocessor.transactional.generated.TrxRegionProtos.TrafEstimateRowCountRequest parseDelimitedFrom(
+        java.io.InputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws java.io.IOException {
+      return PARSER.parseDelimitedFrom(input, extensionRegistry);
+    }
+    public static org.apache.hadoop.hbase.coprocessor.transactional.generated.TrxRegionProtos.TrafEstimateRowCountRequest parseFrom(
+        com.google.protobuf.CodedInputStream input)
+        throws java.io.IOException {
+      return PARSER.parseFrom(input);
+    }
+    public static org.apache.hadoop.hbase.coprocessor.transactional.generated.TrxRegionProtos.TrafEstimateRowCountRequest parseFrom(
+        com.google.protobuf.CodedInputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws java.io.IOException {
+      return PARSER.parseFrom(input, extensionRegistry);
+    }
+
+    public static Builder newBuilder() { return Builder.create(); }
+    public Builder newBuilderForType() { return newBuilder(); }
+    public static Builder newBuilder(org.apache.hadoop.hbase.coprocessor.transactional.generated.TrxRegionProtos.TrafEstimateRowCountRequest prototype) {
+      return newBuilder().mergeFrom(prototype);
+    }
+    public Builder toBuilder() { return newBuilder(this); }
+
+    @java.lang.Override
+    protected Builder newBuilderForType(
+        com.google.protobuf.GeneratedMessage.BuilderParent parent) {
+      Builder builder = new Builder(parent);
+      return builder;
+    }
     /**
-     * <code>required int64 startId = 3;</code>
+     * Protobuf type {@code TrafEstimateRowCountRequest}
      */
-    boolean hasStartId();
+    public static final class Builder extends
+        com.google.protobuf.GeneratedMessage.Builder<Builder>
+       implements org.apache.hadoop.hbase.coprocessor.transactional.generated.TrxRegionProtos.TrafEstimateRowCountRequestOrBuilder {
+      public static final com.google.protobuf.Descriptors.Descriptor
+          getDescriptor() {
+        return org.apache.hadoop.hbase.coprocessor.transactional.generated.TrxRegionProtos.internal_static_TrafEstimateRowCountRequest_descriptor;
+      }
+
+      protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
+          internalGetFieldAccessorTable() {
+        return org.apache.hadoop.hbase.coprocessor.transactional.generated.TrxRegionProtos.internal_static_TrafEstimateRowCountRequest_fieldAccessorTable
+            .ensureFieldAccessorsInitialized(
+                org.apache.hadoop.hbase.coprocessor.transactional.generated.TrxRegionProtos.TrafEstimateRowCountRequest.class, org.apache.hadoop.hbase.coprocessor.transactional.generated.TrxRegionProtos.TrafEstimateRowCountRequest.Builder.class);
+      }
+
+      // Construct using org.apache.hadoop.hbase.coprocessor.transactional.generated.TrxRegionProtos.TrafEstimateRowCountRequest.newBuilder()
+      private Builder() {
+        maybeForceBuilderInitialization();
+      }
+
+      private Builder(
+          com.google.protobuf.GeneratedMessage.BuilderParent parent) {
+        super(parent);
+        maybeForceBuilderInitialization();
+      }
+      private void maybeForceBuilderInitialization() {
+        if (com.google.protobuf.GeneratedMessage.alwaysUseFieldBuilders) {
+        }
+      }
+      private static Builder create() {
+        return new Builder();
+      }
+
+      public Builder clear() {
+        super.clear();
+        numCols_ = 0;
+        bitField0_ = (bitField0_ & ~0x00000001);
+        return this;
+      }
+
+      public Builder clone() {
+        return create().mergeFrom(buildPartial());
+      }
+
+      public com.google.protobuf.Descriptors.Descriptor
+          getDescriptorForType() {
+        return org.apache.hadoop.hbase.coprocessor.transactional.generated.TrxRegionProtos.internal_static_TrafEstimateRowCountRequest_descriptor;
+      }
+
+      public org.apache.hadoop.hbase.coprocessor.transactional.generated.TrxRegionProtos.TrafEstimateRowCountRequest getDefaultInstanceForType() {
+        return org.apache.hadoop.hbase.coprocessor.transactional.generated.TrxRegionProtos.TrafEstimateRowCountRequest.getDefaultInstance();
+      }
+
+      public org.apache.hadoop.hbase.coprocessor.transactional.generated.TrxRegionProtos.TrafEstimateRowCountRequest build() {
+        org.apache.hadoop.hbase.coprocessor.transactional.generated.TrxRegionProtos.TrafEstimateRowCountRequest result = buildPartial();
+        if (!result.isInitialized()) {
+          throw newUninitializedMessageException(result);
+        }
+        return result;
+      }
+
+      public org.apache.hadoop.hbase.coprocessor.transactional.generated.TrxRegionProtos.TrafEstimateRowCountRequest buildPartial() {
+        org.apache.hadoop.hbase.coprocessor.transactional.generated.TrxRegionProtos.TrafEstimateRowCountRequest result = new org.apache.hadoop.hbase.coprocessor.transactional.generated.TrxRegionProtos.TrafEstimateRowCountRequest(this);
+        int from_bitField0_ = bitField0_;
+        int to_bitField0_ = 0;
+        if (((from_bitField0_ & 0x00000001) == 0x00000001)) {
+          to_bitField0_ |= 0x00000001;
+        }
+        result.numCols_ = numCols_;
+        result.bitField0_ = to_bitField0_;
+        onBuilt();
+        return result;
+      }
+
+      public Builder mergeFrom(com.google.protobuf.Message other) {
+        if (other instanceof org.apache.hadoop.hbase.coprocessor.transactional.generated.TrxRegionProtos.TrafEstimateRowCountRequest) {
+          return mergeFrom((org.apache.hadoop.hbase.coprocessor.transactional.generated.TrxRegionProtos.TrafEstimateRowCountRequest)other);
+        } else {
+          super.mergeFrom(other);
+          return this;
+        }
+      }
+
+      public Builder mergeFrom(org.apache.hadoop.hbase.coprocessor.transactional.generated.TrxRegionProtos.TrafEstimateRowCountRequest other) {
+        if (other == org.apache.hadoop.hbase.coprocessor.transactional.generated.TrxRegionProtos.TrafEstimateRowCountRequest.getDefaultInstance()) return this;
+        if (other.hasNumCols()) {
+          setNumCols(other.getNumCols());
+        }
+        this.mergeUnknownFields(other.getUnknownFields());
+        return this;
+      }
+
+      public final boolean isInitialized() {
+        if (!hasNumCols()) {
+          
+          return false;
+        }
+        return true;
+      }
+
+      public Builder mergeFrom(
+          com.google.protobuf.CodedInputStream input,
+          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+          throws java.io.IOException {
+        org.apache.hadoop.hbase.coprocessor.transactional.generated.TrxRegionProtos.TrafEstimateRowCountRequest parsedMessage = null;
+        try {
+          parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry);
+        } catch (com.google.protobuf.InvalidProtocolBufferException e) {
+          parsedMessage = (org.apache.hadoop.hbase.coprocessor.transactional.generated.TrxRegionProtos.TrafEstimateRowCountRequest) e.getUnfinishedMessage();
+          throw e;
+        } finally {
+          if (parsedMessage != null) {
+            mergeFrom(parsedMessage);
+          }
+        }
+        return this;
+      }
+      private int bitField0_;
+
+      // required int32 numCols = 1;
+      private int numCols_ ;
+      /**
+       * <code>required int32 numCols = 1;</code>
+       *
+       * <pre>
+       * numCols = 1 for aligned tables; = # columns for non-aligned tables
+       * </pre>
+       */
+      public boolean hasNumCols() {
+        return ((bitField0_ & 0x00000001) == 0x00000001);
+      }
+      /**
+       * <code>required int32 numCols = 1;</code>
+       *
+       * <pre>
+       * numCols = 1 for aligned tables; = # columns for non-aligned tables
+       * </pre>
+       */
+      public int getNumCols() {
+        return numCols_;
+      }
+      /**
+       * <code>required int32 numCols = 1;</code>
+       *
+       * <pre>
+       * numCols = 1 for aligned tables; = # columns for non-aligned tables
+       * </pre>
+       */
+      public Builder setNumCols(int value) {
+        bitField0_ |= 0x00000001;
+        numCols_ = value;
+        onChanged();
+        return this;
+      }
+      /**
+       * <code>required int32 numCols = 1;</code>
+       *
+       * <pre>
+       * numCols = 1 for aligned tables; = # columns for non-aligned tables
+       * </pre>
+       */
+      public Builder clearNumCols() {
+        bitField0_ = (bitField0_ & ~0x00000001);
+        numCols_ = 0;
+        onChanged();
+        return this;
+      }
+
+      // @@protoc_insertion_point(builder_scope:TrafEstimateRowCountRequest)
+    }
+
+    static {
+      defaultInstance = new TrafEstimateRowCountRequest(true);
+      defaultInstance.initFields();
+    }
+
+    // @@protoc_insertion_point(class_scope:TrafEstimateRowCountRequest)
+  }
+
+  public interface TrafEstimateRowCountResponseOrBuilder
+      extends com.google.protobuf.MessageOrBuilder {
+
+    // required int64 totalEntries = 1;
     /**
-     * <code>required int64 startId = 3;</code>
+     * <code>required int64 totalEntries = 1;</code>
      */
-    long getStartId();
+    boolean hasTotalEntries();
+    /**
+     * <code>required int64 totalEntries = 1;</code>
+     */
+    long getTotalEntries();
 
-    // required string interpreter_class_name = 4;
+    // required int64 totalSizeBytes = 2;
     /**
-     * <code>required string interpreter_class_name = 4;</code>
+     * <code>required int64 totalSizeBytes = 2;</code>
      */
-    boolean hasInterpreterClassName();
+    boolean hasTotalSizeBytes();
     /**
-     * <code>required string interpreter_class_name = 4;</code>
+     * <code>required int64 totalSizeBytes = 2;</code>
      */
-    java.lang.String getInterpreterClassName();
+    long getTotalSizeBytes();
+
+    // required int32 putKVsSampled = 3;
     /**
-     * <code>required string interpreter_class_name = 4;</code>
+     * <code>required int32 putKVsSampled = 3;</code>
+     *
+     * <pre>
+     * the next three values will be non-zero only for the first region,
+     * and only when the format is non-aligned
+     * </pre>
      */
-    com.google.protobuf.ByteString
-        getInterpreterClassNameBytes();
+    boolean hasPutKVsSampled();
+    /**
+     * <code>required int32 putKVsSampled = 3;</code>
+     *
+     * <pre>
+     * the next three values will be non-zero only for the first region,
+     * and only when the format is non-aligned
+     * </pre>
+     */
+    int getPutKVsSampled();
 
-    // required .Scan scan = 5;
+    // required int32 nonPutKVsSampled = 4;
     /**
-     * <code>required .Scan scan = 5;</code>
+     * <code>required int32 nonPutKVsSampled = 4;</code>
      */
-    boolean hasScan();
+    boolean hasNonPutKVsSampled();
     /**
-     * <code>required .Scan scan = 5;</code>
+     * <code>required int32 nonPutKVsSampled = 4;</code>
      */
-    org.apache.hadoop.hbase.protobuf.generated.ClientProtos.Scan getScan();
+    int getNonPutKVsSampled();
+
+    // required int32 missingKVsCount = 5;
     /**
-     * <code>required .Scan scan = 5;</code>
+     * <code>required int32 missingKVsCount = 5;</code>
      */
-    org.apache.hadoop.hbase.protobuf.generated.ClientProtos.ScanOrBuilder getScanOrBuilder();
+    boolean hasMissingKVsCount();
+    /**
+     * <code>required int32 missingKVsCount = 5;</code>
+     */
+    int getMissingKVsCount();
 
-    // optional bytes interpreter_specific_bytes = 6;
+    // optional string exception = 6;
     /**
-     * <code>optional bytes interpreter_specific_bytes = 6;</code>
+     * <code>optional string exception = 6;</code>
      */
-    boolean hasInterpreterSpecificBytes();
+    boolean hasException();
     /**
-     * <code>optional bytes interpreter_specific_bytes = 6;</code>
+     * <code>optional string exception = 6;</code>
      */
-    com.google.protobuf.ByteString getInterpreterSpecificBytes();
+    java.lang.String getException();
+    /**
+     * <code>optional string exception = 6;</code>
+     */
+    com.google.protobuf.ByteString
+        getExceptionBytes();
+
+    // optional bool hasException = 7;
+    /**
+     * <code>optional bool hasException = 7;</code>
+     */
+    boolean hasHasException();
+    /**
+     * <code>optional bool hasException = 7;</code>
+     */
+    boolean getHasException();
   }
   /**
-   * Protobuf type {@code TransactionalAggregateRequest}
+   * Protobuf type {@code TrafEstimateRowCountResponse}
    */
-  public static final class TransactionalAggregateRequest extends
+  public static final class TrafEstimateRowCountResponse extends
       com.google.protobuf.GeneratedMessage
-      implements TransactionalAggregateRequestOrBuilder {
-    // Use TransactionalAggregateRequest.newBuilder() to construct.
-    private TransactionalAggregateRequest(com.google.protobuf.GeneratedMessage.Builder<?> builder) {
+      implements TrafEstimateRowCountResponseOrBuilder {
+    // Use TrafEstimateRowCountResponse.newBuilder() to construct.
+    private TrafEstimateRowCountResponse(com.google.protobuf.GeneratedMessage.Builder<?> builder) {
       super(builder);
       this.unknownFields = builder.getUnknownFields();
     }
-    private TransactionalAggregateRequest(boolean noInit) { this.unknownFields = com.google.protobuf.UnknownFieldSet.getDefaultInstance(); }
+    private TrafEstimateRowCountResponse(boolean noInit) { this.unknownFields = com.google.protobuf.UnknownFieldSet.getDefaultInstance(); }
 
-    private static final TransactionalAggregateRequest defaultInstance;
-    public static TransactionalAggregateRequest getDefaultInstance() {
+    private static final TrafEstimateRowCountResponse defaultInstance;
+    public static TrafEstimateRowCountResponse getDefaultInstance() {
       return defaultInstance;
     }
 
-    public TransactionalAggregateRequest getDefaultInstanceForType() {
+    public TrafEstimateRowCountResponse getDefaultInstanceForType() {
       return defaultInstance;
     }
 
@@ -41751,7 +42164,1044 @@ public final class TrxRegionProtos {
         getUnknownFields() {
       return this.unknownFields;
     }
-    private TransactionalAggregateRequest(
+    private TrafEstimateRowCountResponse(
+        com.google.protobuf.CodedInputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      initFields();
+      int mutable_bitField0_ = 0;
+      com.google.protobuf.UnknownFieldSet.Builder unknownFields =
+          com.google.protobuf.UnknownFieldSet.newBuilder();
+      try {
+        boolean done = false;
+        while (!done) {
+          int tag = input.readTag();
+          switch (tag) {
+            case 0:
+              done = true;
+              break;
+            default: {
+              if (!parseUnknownField(input, unknownFields,
+                                     extensionRegistry, tag)) {
+                done = true;
+              }
+              break;
+            }
+            case 8: {
+              bitField0_ |= 0x00000001;
+              totalEntries_ = input.readInt64();
+              break;
+            }
+            case 16: {
+              bitField0_ |= 0x00000002;
+              totalSizeBytes_ = input.readInt64();
+              break;
+            }
+            case 24: {
+              bitField0_ |= 0x00000004;
+              putKVsSampled_ = input.readInt32();
+              break;
+            }
+            case 32: {
+              bitField0_ |= 0x00000008;
+              nonPutKVsSampled_ = input.readInt32();
+              break;
+            }
+            case 40: {
+              bitField0_ |= 0x00000010;
+              missingKVsCount_ = input.readInt32();
+              break;
+            }
+            case 50: {
+              bitField0_ |= 0x00000020;
+              exception_ = input.readBytes();
+              break;
+            }
+            case 56: {
+              bitField0_ |= 0x00000040;
+              hasException_ = input.readBool();
+              break;
+            }
+          }
+        }
+      } catch (com.google.protobuf.InvalidProtocolBufferException e) {
+        throw e.setUnfinishedMessage(this);
+      } catch (java.io.IOException e) {
+        throw new com.google.protobuf.InvalidProtocolBufferException(
+            e.getMessage()).setUnfinishedMessage(this);
+      } finally {
+        this.unknownFields = unknownFields.build();
+        makeExtensionsImmutable();
+      }
+    }
+    public static final com.google.protobuf.Descriptors.Descriptor
+        getDescriptor() {
+      return org.apache.hadoop.hbase.coprocessor.transactional.generated.TrxRegionProtos.internal_static_TrafEstimateRowCountResponse_descriptor;
+    }
+
+    protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
+        internalGetFieldAccessorTable() {
+      return org.apache.hadoop.hbase.coprocessor.transactional.generated.TrxRegionProtos.internal_static_TrafEstimateRowCountResponse_fieldAccessorTable
+          .ensureFieldAccessorsInitialized(
+              org.apache.hadoop.hbase.coprocessor.transactional.generated.TrxRegionProtos.TrafEstimateRowCountResponse.class, org.apache.hadoop.hbase.coprocessor.transactional.generated.TrxRegionProtos.TrafEstimateRowCountResponse.Builder.class);
+    }
+
+    public static com.google.protobuf.Parser<TrafEstimateRowCountResponse> PARSER =
+        new com.google.protobuf.AbstractParser<TrafEstimateRowCountResponse>() {
+      public TrafEstimateRowCountResponse parsePartialFrom(
+          com.google.protobuf.CodedInputStream input,
+          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+          throws com.google.protobuf.InvalidProtocolBufferException {
+        return new TrafEstimateRowCountResponse(input, extensionRegistry);
+      }
+    };
+
+    @java.lang.Override
+    public com.google.protobuf.Parser<TrafEstimateRowCountResponse> getParserForType() {
+      return PARSER;
+    }
+
+    private int bitField0_;
+    // required int64 totalEntries = 1;
+    public static final int TOTALENTRIES_FIELD_NUMBER = 1;
+    private long totalEntries_;
+    /**
+     * <code>required int64 totalEntries = 1;</code>
+     */
+    public boolean hasTotalEntries() {
+      return ((bitField0_ & 0x00000001) == 0x00000001);
+    }
+    /**
+     * <code>required int64 totalEntries = 1;</code>
+     */
+    public long getTotalEntries() {
+      return totalEntries_;
+    }
+
+    // required int64 totalSizeBytes = 2;
+    public static final int TOTALSIZEBYTES_FIELD_NUMBER = 2;
+    private long totalSizeBytes_;
+    /**
+     * <code>required int64 totalSizeBytes = 2;</code>
+     */
+    public boolean hasTotalSizeBytes() {
+      return ((bitField0_ & 0x00000002) == 0x00000002);
+    }
+    /**
+     * <code>required int64 totalSizeBytes = 2;</code>
+     */
+    public long getTotalSizeBytes() {
+      return totalSizeBytes_;
+    }
+
+    // required int32 putKVsSampled = 3;
+    public static final int PUTKVSSAMPLED_FIELD_NUMBER = 3;
+    private int putKVsSampled_;
+    /**
+     * <code>required int32 putKVsSampled = 3;</code>
+     *
+     * <pre>
+     * the next three values will be non-zero only for the first region,
+     * and only when the format is non-aligned
+     * </pre>
+     */
+    public boolean hasPutKVsSampled() {
+      return ((bitField0_ & 0x00000004) == 0x00000004);
+    }
+    /**
+     * <code>required int32 putKVsSampled = 3;</code>
+     *
+     * <pre>
+     * the next three values will be non-zero only for the first region,
+     * and only when the format is non-aligned
+     * </pre>
+     */
+    public int getPutKVsSampled() {
+      return putKVsSampled_;
+    }
+
+    // required int32 nonPutKVsSampled = 4;
+    public static final int NONPUTKVSSAMPLED_FIELD_NUMBER = 4;
+    private int nonPutKVsSampled_;
+    /**
+     * <code>required int32 nonPutKVsSampled = 4;</code>
+     */
+    public boolean hasNonPutKVsSampled() {
+      return ((bitField0_ & 0x00000008) == 0x00000008);
+    }
+    /**
+     * <code>required int32 nonPutKVsSampled = 4;</code>
+     */
+    public int getNonPutKVsSampled() {
+      return nonPutKVsSampled_;
+    }
+
+    // required int32 missingKVsCount = 5;
+    public static final int MISSINGKVSCOUNT_FIELD_NUMBER = 5;
+    private int missingKVsCount_;
+    /**
+     * <code>required int32 missingKVsCount = 5;</code>
+     */
+    public boolean hasMissingKVsCount() {
+      return ((bitField0_ & 0x00000010) == 0x00000010);
+    }
+    /**
+     * <code>required int32 missingKVsCount = 5;</code>
+     */
+    public int getMissingKVsCount() {
+      return missingKVsCount_;
+    }
+
+    // optional string exception = 6;
+    public static final int EXCEPTION_FIELD_NUMBER = 6;
+    private java.lang.Object exception_;
+    /**
+     * <code>optional string exception = 6;</code>
+     */
+    public boolean hasException() {
+      return ((bitField0_ & 0x00000020) == 0x00000020);
+    }
+    /**
+     * <code>optional string exception = 6;</code>
+     */
+    public java.lang.String getException() {
+      java.lang.Object ref = exception_;
+      if (ref instanceof java.lang.String) {
+        return (java.lang.String) ref;
+      } else {
+        com.google.protobuf.ByteString bs = 
+            (com.google.protobuf.ByteString) ref;
+        java.lang.String s = bs.toStringUtf8();
+        if (bs.isValidUtf8()) {
+          exception_ = s;
+        }
+        return s;
+      }
+    }
+    /**
+     * <code>optional string exception = 6;</code>
+     */
+    public com.google.protobuf.ByteString
+        getExceptionBytes() {
+      java.lang.Object ref = exception_;
+      if (ref instanceof java.lang.String) {
+        com.google.protobuf.ByteString b = 
+            com.google.protobuf.ByteString.copyFromUtf8(
+                (java.lang.String) ref);
+        exception_ = b;
+        return b;
+      } else {
+        return (com.google.protobuf.ByteString) ref;
+      }
+    }
+
+    // optional bool hasException = 7;
+    public static final int HASEXCEPTION_FIELD_NUMBER = 7;
+    private boolean hasException_;
+    /**
+     * <code>optional bool hasException = 7;</code>
+     */
+    public boolean hasHasException() {
+      return ((bitField0_ & 0x00000040) == 0x00000040);
+    }
+    /**
+     * <code>optional bool hasException = 7;</code>
+     */
+    public boolean getHasException() {
+      return hasException_;
+    }
+
+    private void initFields() {
+      totalEntries_ = 0L;
+      totalSizeBytes_ = 0L;
+      putKVsSampled_ = 0;
+      nonPutKVsSampled_ = 0;
+      missingKVsCount_ = 0;
+      exception_ = "";
+      hasException_ = false;
+    }
+    private byte memoizedIsInitialized = -1;
+    public final boolean isInitialized() {
+      byte isInitialized = memoizedIsInitialized;
+      if (isInitialized != -1) return isInitialized == 1;
+
+      if (!hasTotalEntries()) {
+        memoizedIsInitialized = 0;
+        return false;
+      }
+      if (!hasTotalSizeBytes()) {
+        memoizedIsInitialized = 0;
+        return false;
+      }
+      if (!hasPutKVsSampled()) {
+        memoizedIsInitialized = 0;
+        return false;
+      }
+      if (!hasNonPutKVsSampled()) {
+        memoizedIsInitialized = 0;
+        return false;
+      }
+      if (!hasMissingKVsCount()) {
+        memoizedIsInitialized = 0;
+        return false;
+      }
+      memoizedIsInitialized = 1;
+      return true;
+    }
+
+    public void writeTo(com.google.protobuf.CodedOutputStream output)
+                        throws java.io.IOException {
+      getSerializedSize();
+      if (((bitField0_ & 0x00000001) == 0x00000001)) {
+        output.writeInt64(1, totalEntries_);
+      }
+      if (((bitField0_ & 0x00000002) == 0x00000002)) {
+        output.writeInt64(2, totalSizeBytes_);
+      }
+      if (((bitField0_ & 0x00000004) == 0x00000004)) {
+        output.writeInt32(3, putKVsSampled_);
+      }
+      if (((bitField0_ & 0x00000008) == 0x00000008)) {
+        output.writeInt32(4, nonPutKVsSampled_);
+      }
+      if (((bitField0_ & 0x00000010) == 0x00000010)) {
+        output.writeInt32(5, missingKVsCount_);
+      }
+      if (((bitField0_ & 0x00000020) == 0x00000020)) {
+        output.writeBytes(6, getExceptionBytes());
+      }
+      if (((bitField0_ & 0x00000040) == 0x00000040)) {
+        output.writeBool(7, hasException_);
+      }
+      getUnknownFields().writeTo(output);
+    }
+
+    private int memoizedSerializedSize = -1;
+    public int getSerializedSize() {
+      int size = memoizedSerializedSize;
+      if (size != -1) return size;
+
+      size = 0;
+      if (((bitField0_ & 0x00000001) == 0x00000001)) {
+        size += com.google.protobuf.CodedOutputStream
+          .computeInt64Size(1, totalEntries_);
+      }
+      if (((bitField0_ & 0x00000002) == 0x00000002)) {
+        size += com.google.protobuf.CodedOutputStream
+          .computeInt64Size(2, totalSizeBytes_);
+      }
+      if (((bitField0_ & 0x00000004) == 0x00000004)) {
+        size += com.google.protobuf.CodedOutputStream
+          .computeInt32Size(3, putKVsSampled_);
+      }
+      if (((bitField0_ & 0x00000008) == 0x00000008)) {
+        size += com.google.protobuf.CodedOutputStream
+          .computeInt32Size(4, nonPutKVsSampled_);
+      }
+      if (((bitField0_ & 0x00000010) == 0x00000010)) {
+        size += com.google.protobuf.CodedOutputStream
+          .computeInt32Size(5, missingKVsCount_);
+      }
+      if (((bitField0_ & 0x00000020) == 0x00000020)) {
+        size += com.google.protobuf.CodedOutputStream
+          .computeBytesSize(6, getExceptionBytes());
+      }
+      if (((bitField0_ & 0x00000040) == 0x00000040)) {
+        size += com.google.protobuf.CodedOutputStream
+          .computeBoolSize(7, hasException_);
+      }
+      size += getUnknownFields().getSerializedSize();
+      memoizedSerializedSize = size;
+      return size;
+    }
+
+    private static final long serialVersionUID = 0L;
+    @java.lang.Override
+    protected java.lang.Object writeReplace()
+        throws java.io.ObjectStreamException {
+      return super.writeReplace();
+    }
+
+    public static org.apache.hadoop.hbase.coprocessor.transactional.generated.TrxRegionProtos.TrafEstimateRowCountResponse parseFrom(
+        com.google.protobuf.ByteString data)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data);
+    }
+    public static org.apache.hadoop.hbase.coprocessor.transactional.generated.TrxRegionProtos.TrafEstimateRowCountResponse parseFrom(
+        com.google.protobuf.ByteString data,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data, extensionRegistry);
+    }
+    public static org.apache.hadoop.hbase.coprocessor.transactional.generated.TrxRegionProtos.TrafEstimateRowCountResponse parseFrom(byte[] data)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data);
+    }
+    public static org.apache.hadoop.hbase.coprocessor.transactional.generated.TrxRegionProtos.TrafEstimateRowCountResponse parseFrom(
+        byte[] data,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data, extensionRegistry);
+    }
+    public static org.apache.hadoop.hbase.coprocessor.transactional.generated.TrxRegionProtos.TrafEstimateRowCountResponse parseFrom(java.io.InputStream input)
+        throws java.io.IOException {
+      return PARSER.parseFrom(input);
+    }
+    public static org.apache.hadoop.hbase.coprocessor.transactional.generated.TrxRegionProtos.TrafEstimateRowCountResponse parseFrom(
+        java.io.InputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws java.io.IOException {
+      return PARSER.parseFrom(input, extensionRegistry);
+    }
+    public static org.apache.hadoop.hbase.coprocessor.transactional.generated.TrxRegionProtos.TrafEstimateRowCountResponse parseDelimitedFrom(java.io.InputStream input)
+        throws java.io.IOException {
+      return PARSER.parseDelimitedFrom(input);
+    }
+    public static org.apache.hadoop.hbase.coprocessor.transactional.generated.TrxRegionProtos.TrafEstimateRowCountResponse parseDelimitedFrom(
+        java.io.InputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws java.io.IOException {
+      return PARSER.parseDelimitedFrom(input, extensionRegistry);
+    }
+    public static org.apache.hadoop.hbase.coprocessor.transactional.generated.TrxRegionProtos.TrafEstimateRowCountResponse parseFrom(
+        com.google.protobuf.CodedInputStream input)
+        throws java.io.IOException {
+      return PARSER.parseFrom(input);
+    }
+    public static org.apache.hadoop.hbase.coprocessor.transactional.generated.TrxRegionProtos.TrafEstimateRowCountResponse parseFrom(
+        com.google.protobuf.CodedInputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws java.io.IOException {
+      return PARSER.parseFrom(input, extensionRegistry);
+    }
+
+    public static Builder newBuilder() { return Builder.create(); }
+    public Builder newBuilderForType() { return newBuilder(); }
+    public static Builder newBuilder(org.apache.hadoop.hbase.coprocessor.transactional.generated.TrxRegionProtos.TrafEstimateRowCountResponse prototype) {
+      return newBuilder().mergeFrom(prototype);
+    }
+    public Builder toBuilder() { return newBuilder(this); }
+
+    @java.lang.Override
+    protected Builder newBuilderForType(
+        com.google.protobuf.GeneratedMessage.BuilderParent parent) {
+      Builder builder = new Builder(parent);
+      return builder;
+    }
+    /**
+     * Protobuf type {@code TrafEstimateRowCountResponse}
+     */
+    public static final class Builder extends
+        com.google.protobuf.GeneratedMessage.Builder<Builder>
+       implements org.apache.hadoop.hbase.coprocessor.transactional.generated.TrxRegionProtos.TrafEstimateRowCountResponseOrBuilder {
+      public static final com.google.protobuf.Descriptors.Descriptor
+          getDescriptor() {
+        return org.apache.hadoop.hbase.coprocessor.transactional.generated.TrxRegionProtos.internal_static_TrafEstimateRowCountResponse_descriptor;
+      }
+
+      protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
+          internalGetFieldAccessorTable() {
+        return org.apache.hadoop.hbase.coprocessor.transactional.generated.TrxRegionProtos.internal_static_TrafEstimateRowCountResponse_fieldAccessorTable
+            .ensureFieldAccessorsInitialized(
+                org.apache.hadoop.hbase.coprocessor.transactional.generated.TrxRegionProtos.TrafEstimateRowCountResponse.class, org.apache.hadoop.hbase.coprocessor.transactional.generated.TrxRegionProtos.TrafEstimateRowCountResponse.Builder.class);
+      }
+
+      // Construct using org.apache.hadoop.hbase.coprocessor.transactional.generated.TrxRegionProtos.TrafEstimateRowCountResponse.newBuilder()
+      private Builder() {
+        maybeForceBuilderInitialization();
+      }
+
+      private Builder(
+          com.google.protobuf.GeneratedMessage.BuilderParent parent) {
+        super(parent);
+        maybeForceBuilderInitialization();
+      }
+      private void maybeForceBuilderInitialization() {
+        if (com.google.protobuf.GeneratedMessage.alwaysUseFieldBuilders) {
+        }
+      }
+      private static Builder create() {
+        return new Builder();
+      }
+
+      public Builder clear() {
+        super.clear();
+        totalEntries_ = 0L;
+        bitField0_ = (bitField0_ & ~0x00000001);
+        totalSizeBytes_ = 0L;
+        bitField0_ = (bitField0_ & ~0x00000002);
+        putKVsSampled_ = 0;
+        bitField0_ = (bitField0_ & ~0x00000004);
+        nonPutKVsSampled_ = 0;
+        bitField0_ = (bitField0_ & ~0x00000008);
+        missingKVsCount_ = 0;
+        bitField0_ = (bitField0_ & ~0x00000010);
+        exception_ = "";
+        bitField0_ = (bitField0_ & ~0x00000020);
+        hasException_ = false;
+        bitField0_ = (bitField0_ & ~0x00000040);
+        return this;
+      }
+
+      public Builder clone() {
+        return create().mergeFrom(buildPartial());
+      }
+
+      public com.google.protobuf.Descriptors.Descriptor
+          getDescriptorForType() {
+        return org.apache.hadoop.hbase.coprocessor.transactional.generated.TrxRegionProtos.internal_static_TrafEstimateRowCountResponse_descriptor;
+      }
+
+      public org.apache.hadoop.hbase.coprocessor.transactional.generated.TrxRegionProtos.TrafEstimateRowCountResponse getDefaultInstanceForType() {
+        return org.apache.hadoop.hbase.coprocessor.transactional.generated.TrxRegionProtos.TrafEstimateRowCountResponse.getDefaultInstance();
+      }
+
+      public org.apache.hadoop.hbase.coprocessor.transactional.generated.TrxRegionProtos.TrafEstimateRowCountResponse build() {
+        org.apache.hadoop.hbase.coprocessor.transactional.generated.TrxRegionProtos.TrafEstimateRowCountResponse result = buildPartial();
+        if (!result.isInitialized()) {
+          throw newUninitializedMessageException(result);
+        }
+        return result;
+      }
+
+      public org.apache.hadoop.hbase.coprocessor.transactional.generated.TrxRegionProtos.TrafEstimateRowCountResponse buildPartial() {
+        org.apache.hadoop.hbase.coprocessor.transactional.generated.TrxRegionProtos.TrafEstimateRowCountResponse result = new org.apache.hadoop.hbase.coprocessor.transactional.generated.TrxRegionProtos.TrafEstimateRowCountResponse(this);
+        int from_bitField0_ = bitField0_;
+        int to_bitField0_ = 0;
+        if (((from_bitField0_ & 0x00000001) == 0x00000001)) {
+          to_bitField0_ |= 0x00000001;
+        }
+        result.totalEntries_ = totalEntries_;
+        if (((from_bitField0_ & 0x00000002) == 0x00000002)) {
+          to_bitField0_ |= 0x00000002;
+        }
+        result.totalSizeBytes_ = totalSizeBytes_;
+        if (((from_bitField0_ & 0x00000004) == 0x00000004)) {
+          to_bitField0_ |= 0x00000004;
+        }
+        result.putKVsSampled_ = putKVsSampled_;
+        if (((from_bitField0_ & 0x00000008) == 0x00000008)) {
+          to_bitField0_ |= 0x00000008;
+        }
+        result.nonPutKVsSampled_ = nonPutKVsSampled_;
+        if (((from_bitField0_ & 0x00000010) == 0x00000010)) {
+          to_bitField0_ |= 0x00000010;
+        }
+        result.missingKVsCount_ = missingKVsCount_;
+        if (((from_bitField0_ & 0x00000020) == 0x00000020)) {
+          to_bitField0_ |= 0x00000020;
+        }
+        result.exception_ = exception_;
+        if (((from_bitField0_ & 0x00000040) == 0x00000040)) {
+          to_bitField0_ |= 0x00000040;
+        }
+        result.hasException_ = hasException_;
+        result.bitField0_ = to_bitField0_;
+        onBuilt();
+        return result;
+      }
+
+      public Builder mergeFrom(com.google.protobuf.Message other) {
+        if (other instanceof org.apache.hadoop.hbase.coprocessor.transactional.generated.TrxRegionProtos.TrafEstimateRowCountResponse) {
+          return mergeFrom((org.apache.hadoop.hbase.coprocessor.transactional.generated.TrxRegionProtos.TrafEstimateRowCountResponse)other);
+        } else {
+          super.mergeFrom(other);
+          return this;
+        }
+      }
+
+      public Builder mergeFrom(org.apache.hadoop.hbase.coprocessor.transactional.generated.TrxRegionProtos.TrafEstimateRowCountResponse other) {
+        if (other == org.apache.hadoop.hbase.coprocessor.transactional.generated.TrxRegionProtos.TrafEstimateRowCountResponse.getDefaultInstance()) return this;
+        if (other.hasTotalEntries()) {
+          setTotalEntries(other.getTotalEntries());
+        }
+        if (other.hasTotalSizeBytes()) {
+          setTotalSizeBytes(other.getTotalSizeBytes());
+        }
+        if (other.hasPutKVsSampled()) {
+          setPutKVsSampled(other.getPutKVsSampled());
+        }
+        if (other.hasNonPutKVsSampled()) {
+          setNonPutKVsSampled(other.getNonPutKVsSampled());
+        }
+        if (other.hasMissingKVsCount()) {
+          setMissingKVsCount(other.getMissingKVsCount());
+        }
+        if (other.hasException()) {
+          bitField0_ |= 0x00000020;
+          exception_ = other.exception_;
+          onChanged();
+        }
+        if (other.hasHasException()) {
+          setHasException(other.getHasException());
+        }
+        this.mergeUnknownFields(other.getUnknownFields());
+        return this;
+      }
+
+      public final boolean isInitialized() {
+        if (!hasTotalEntries()) {
+          
+          return false;
+        }
+        if (!hasTotalSizeBytes()) {
+          
+          return false;
+        }
+        if (!hasPutKVsSampled()) {
+          
+          return false;
+        }
+        if (!hasNonPutKVsSampled()) {
+          
+          return false;
+        }
+        if (!hasMissingKVsCount()) {
+          
+          return false;
+        }
+        return true;
+      }
+
+      public Builder mergeFrom(
+          com.google.protobuf.CodedInputStream input,
+          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+          throws java.io.IOException {
+        org.apache.hadoop.hbase.coprocessor.transactional.generated.TrxRegionProtos.TrafEstimateRowCountResponse parsedMessage = null;
+        try {
+          parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry);
+        } catch (com.google.protobuf.InvalidProtocolBufferException e) {
+          parsedMessage = (org.apache.hadoop.hbase.coprocessor.transactional.generated.TrxRegionProtos.TrafEstimateRowCountResponse) e.getUnfinishedMessage();
+          throw e;
+        } finally {
+          if (parsedMessage != null) {
+            mergeFrom(parsedMessage);
+          }
+        }
+        return this;
+      }
+      private int bitField0_;
+
+      // required int64 totalEntries = 1;
+      private long totalEntries_ ;
+      /**
+       * <code>required int64 totalEntries = 1;</code>
+       */
+      public boolean hasTotalEntries() {
+        return ((bitField0_ & 0x00000001) == 0x00000001);
+      }
+      /**
+       * <code>required int64 totalEntries = 1;</code>
+       */
+      public long getTotalEntries() {
+        return totalEntries_;
+      }
+      /**
+       * <code>required int64 totalEntries = 1;</code>
+       */
+      public Builder setTotalEntries(long value) {
+        bitField0_ |= 0x00000001;
+        totalEntries_ = value;
+        onChanged();
+        return this;
+      }
+      /**
+       * <code>required int64 totalEntries = 1;</code>
+       */
+      public Builder clearTotalEntries() {
+        bitField0_ = (bitField0_ & ~0x00000001);
+        totalEntries_ = 0L;
+        onChanged();
+        return this;
+      }
+
+      // required int64 totalSizeBytes = 2;
+      private long totalSizeBytes_ ;
+      /**
+       * <code>required int64 totalSizeBytes = 2;</code>
+       */
+      public boolean hasTotalSizeBytes() {
+        return ((bitField0_ & 0x00000002) == 0x00000002);
+      }
+      /**
+       * <code>required int64 totalSizeBytes = 2;</code>
+       */
+      public long getTotalSizeBytes() {
+        return totalSizeBytes_;
+      }
+      /**
+       * <code>required int64 totalSizeBytes = 2;</code>
+       */
+      public Builder setTotalSizeBytes(long value) {
+        bitField0_ |= 0x00000002;
+        totalSizeBytes_ = value;
+        onChanged();
+        return this;
+      }
+      /**
+       * <code>required int64 totalSizeBytes = 2;</code>
+       */
+      public Builder clearTotalSizeBytes() {
+        bitField0_ = (bitField0_ & ~0x00000002);
+        totalSizeBytes_ = 0L;
+        onChanged();
+        return this;
+      }
+
+      // required int32 putKVsSampled = 3;
+      private int putKVsSampled_ ;
+      /**
+       * <code>required int32 putKVsSampled = 3;</code>
+       *
+       * <pre>
+       * the next three values will be non-zero only for the first region,
+       * and only when the format is non-aligned
+       * </pre>
+       */
+      public boolean hasPutKVsSampled() {
+        return ((bitField0_ & 0x00000004) == 0x00000004);
+      }
+      /**
+       * <code>required int32 putKVsSampled = 3;</code>
+       *
+       * <pre>
+       * the next three values will be non-zero only for the first region,
+       * and only when the format is non-aligned
+       * </pre>
+       */
+      public int getPutKVsSampled() {
+        return putKVsSampled_;
+      }
+      /**
+       * <code>required int32 putKVsSampled = 3;</code>
+       *
+       * <pre>
+       * the next three values will be non-zero only for the first region,
+       * and only when the format is non-aligned
+       * </pre>
+       */
+      public Builder setPutKVsSampled(int value) {
+        bitField0_ |= 0x00000004;
+        putKVsSampled_ = value;
+        onChanged();
+        return this;
+      }
+      /**
+       * <code>required int32 putKVsSampled = 3;</code>
+       *
+       * <pre>
+       * the next three values will be non-zero only for the first region,
+       * and only when the format is non-aligned
+       * </pre>
+       */
+      public Builder clearPutKVsSampled() {
+        bitField0_ = (bitField0_ & ~0x00000004);
+        putKVsSampled_ = 0;
+        onChanged();
+        return this;
+      }
+
+      // required int32 nonPutKVsSampled = 4;
+      private int nonPutKVsSampled_ ;
+      /**
+       * <code>required int32 nonPutKVsSampled = 4;</code>
+       */
+      public boolean hasNonPutKVsSampled() {
+        return ((bitField0_ & 0x00000008) == 0x00000008);
+      }
+      /**
+       * <code>required int32 nonPutKVsSampled = 4;</code>
+       */
+      public int getNonPutKVsSampled() {
+        return nonPutKVsSampled_;
+      }
+      /**
+       * <code>required int32 nonPutKVsSampled = 4;</code>
+       */
+      public Builder setNonPutKVsSampled(int value) {
+        bitField0_ |= 0x00000008;
+        nonPutKVsSampled_ = value;
+        onChanged();
+        return this;
+      }
+      /**
+       * <code>required int32 nonPutKVsSampled = 4;</code>
+       */
+      public Builder clearNonPutKVsSampled() {
+        bitField0_ = (bitField0_ & ~0x00000008);
+        nonPutKVsSampled_ = 0;
+        onChanged();
+        return this;
+      }
+
+      // required int32 missingKVsCount = 5;
+      private int missingKVsCount_ ;
+      /**
+       * <code>required int32 missingKVsCount = 5;</code>
+       */
+      public boolean hasMissingKVsCount() {
+        return ((bitField0_ & 0x00000010) == 0x00000010);
+      }
+      /**
+       * <code>required int32 missingKVsCount = 5;</code>
+       */
+      public int getMissingKVsCount() {
+        return missingKVsCount_;
+      }
+      /**
+       * <code>required int32 missingKVsCount = 5;</code>
+       */
+      public Builder setMissingKVsCount(int value) {
+        bitField0_ |= 0x00000010;
+        missingKVsCount_ = value;
+        onChanged();
+        return this;
+      }
+      /**
+       * <code>required int32 missingKVsCount = 5;</code>
+       */
+      public Builder clearMissingKVsCount() {
+        bitField0_ = (bitField0_ & ~0x00000010);
+        missingKVsCount_ = 0;
+        onChanged();
+        return this;
+      }
+
+      // optional string exception = 6;
+      private java.lang.Object exception_ = "";
+      /**
+       * <code>optional string exception = 6;</code>
+       */
+      public boolean hasException() {
+        return ((bitField0_ & 0x00000020) == 0x00000020);
+      }
+      /**
+       * <code>optional string exception = 6;</code>
+       */
+      public java.lang.String getException() {
+        java.lang.Object ref = exception_;
+        if (!(ref instanceof java.lang.String)) {
+          java.lang.String s = ((com.google.protobuf.ByteString) ref)
+              .toStringUtf8();
+          exception_ = s;
+          return s;
+        } else {
+          return (java.lang.String) ref;
+        }
+      }
+      /**
+       * <code>optional string exception = 6;</code>
+       */
+      public com.google.protobuf.ByteString
+          getExceptionBytes() {
+        java.lang.Object ref = exception_;
+        if (ref instanceof String) {
+          com.google.protobuf.ByteString b = 
+              com.google.protobuf.ByteString.copyFromUtf8(
+                  (java.lang.String) ref);
+          exception_ = b;
+          return b;
+        } else {
+          return (com.google.protobuf.ByteString) ref;
+        }
+      }
+      /**
+       * <code>optional string exception = 6;</code>
+       */
+      public Builder setException(
+          java.lang.String value) {
+        if (value == null) {
+    throw new NullPointerException();
+  }
+  bitField0_ |= 0x00000020;
+        exception_ = value;
+        onChanged();
+        return this;
+      }
+      /**
+       * <code>optional string exception = 6;</code>
+       */
+      public Builder clearException() {
+        bitField0_ = (bitField0_ & ~0x00000020);
+        exception_ = getDefaultInstance().getException();
+        onChanged();
+        return this;
+      }
+      /**
+       * <code>optional string exception = 6;</code>
+       */
+      public Builder setExceptionBytes(
+          com.google.protobuf.ByteString value) {
+        if (value == null) {
+    throw new NullPointerException();
+  }
+  bitField0_ |= 0x00000020;
+        exception_ = value;
+        onChanged();
+        return this;
+      }
+
+      // optional bool hasException = 7;
+      private boolean hasException_ ;
+      /**
+       * <code>optional bool hasException = 7;</code>
+       */
+      public boolean hasHasException() {
+        return ((bitField0_ & 0x00000040) == 0x00000040);
+      }
+      /**
+       * <code>optional bool hasException = 7;</code>
+       */
+      public boolean getHasException() {
+        return hasException_;
+      }
+      /**
+       * <code>optional bool hasException = 7;</code>
+       */
+      public Builder setHasException(boolean value) {
+        bitField0_ |= 0x00000040;
+        hasException_ = value;
+        onChanged();
+        return this;
+      }
+      /**
+       * <code>optional bool hasException = 7;</code>
+       */
+      public Builder clearHasException() {
+        bitField0_ = (bitField0_ & ~0x00000040);
+        hasException_ = false;
+        onChanged();
+        return this;
+      }
+
+      // @@protoc_insertion_point(builder_scope:TrafEstimateRowCountResponse)
+    }
+
+    static {
+      defaultInstance = new TrafEstimateRowCountResponse(true);
+      defaultInstance.initFields();
+    }
+
+    // @@protoc_insertion_point(class_scope:TrafEstimateRowCountResponse)
+  }
+
+  public interface TransactionalAggregateRequestOrBuilder
+      extends com.google.protobuf.MessageOrBuilder {
+
+    // required bytes regionName = 1;
+    /**
+     * <code>required bytes regionName = 1;</code>
+     *
+     * <pre>
+     ** The request passed to the TransactionalAggregateService consists of three parts
+     *  (1) the (canonical) classname of the ColumnInterpreter implementation
+     *  (2) the Scan query
+     *  (3) any bytes required to construct the ColumnInterpreter object
+     *      properly
+     * </pre>
+     */
+    boolean hasRegionName();
+    /**
+     * <code>required bytes regionName = 1;</code>
+     *
+     * <pre>
+     ** The request passed to the TransactionalAggregateService consists of three parts
+     *  (1) the (canonical) classname of the ColumnInterpreter implementation
+     *  (2) the Scan query
+     *  (3) any bytes required to construct the ColumnInterpreter object
+     *      properly
+     * </pre>
+     */
+    com.google.protobuf.ByteString getRegionName();
+
+    // required int64 transactionId = 2;
+    /**
+     * <code>required int64 transactionId = 2;</code>
+     */
+    boolean hasTransactionId();
+    /**
+     * <code>required int64 transactionId = 2;</code>
+     */
+    long getTransactionId();
+
+    // required int64 startId = 3;
+    /**
+     * <code>required int64 startId = 3;</code>
+     */
+    boolean hasStartId();
+    /**
+     * <code>required int64 startId = 3;</code>
+     */
+    long getStartId();
+
+    // required string interpreter_class_name = 4;
+    /**
+     * <code>required string interpreter_class_name = 4;</code>
+     */
+    boolean hasInterpreterClassName();
+    /**
+     * <code>required string interpreter_class_name = 4;</code>
+     */
+    java.lang.String getInterpreterClassName();
+    /**
+     * <code>required string interpreter_class_name = 4;</code>
+     */
+    com.google.protobuf.ByteString
+        getInterpreterClassNameBytes();
+
+    // required .Scan scan = 5;
+    /**
+     * <code>required .Scan scan = 5;</code>
+     */
+    boolean hasScan();
+    /**
+     * <code>required .Scan scan = 5;</code>
+     */
+    org.apache.hadoop.hbase.protobuf.generated.ClientProtos.Scan getScan();
+    /**
+     * <code>required .Scan scan = 5;</code>
+     */
+    org.apache.hadoop.hbase.protobuf.generated.ClientProtos.ScanOrBuilder getScanOrBuilder();
+
+    // optional bytes interpreter_specific_bytes = 6;
+    /**
+     * <code>optional bytes interpreter_specific_bytes = 6;</code>
+     */
+    boolean hasInterpreterSpecificBytes();
+    /**
+     * <code>optional bytes interpreter_specific_bytes = 6;</code>
+     */
+    com.google.protobuf.ByteString getInterpreterSpecificBytes();
+  }
+  /**
+   * Protobuf type {@code TransactionalAggregateRequest}
+   */
+  public static final class TransactionalAggregateRequest extends
+      com.google.protobuf.GeneratedMessage
+      implements TransactionalAggregateRequestOrBuilder {
+    // Use TransactionalAggregateRequest.newBuilder() to construct.
+    private TransactionalAggregateRequest(com.google.protobuf.GeneratedMessage.Builder<?> builder) {
+      super(builder);
+      this.unknownFields = builder.getUnknownFields();
+    }
+    private TransactionalAggregateRequest(boolean noInit) { this.unknownFields = com.google.protobuf.UnknownFieldSet.getDefaultInstance(); }
+
+    private static final TransactionalAggregateRequest defaultInstance;
+    public static TransactionalAggregateRequest getDefaultInstance() {
+      return defaultInstance;
+    }
+
+    public TransactionalAggregateRequest getDefaultInstanceForType() {
+      return defaultInstance;
+    }
+
+    private final com.google.protobuf.UnknownFieldSet unknownFields;
+    @java.lang.Override
+    public final com.google.protobuf.UnknownFieldSet
+        getUnknownFields() {
+      return this.unknownFields;
+    }
+    private TransactionalAggregateRequest(
         com.google.protobuf.CodedInputStream input,
         com.google.protobuf.ExtensionRegistryLite extensionRegistry)
         throws com.google.protobuf.InvalidProtocolBufferException {
@@ -46592,6 +48042,14 @@ public final class TrxRegionProtos {
           com.google.protobuf.RpcCallback<org.apache.hadoop.hbase.coprocessor.transactional.generated.TrxRegionProtos.TlogTransactionStatesFromIntervalResponse> done);
 
       /**
+       * <code>rpc trafEstimateRowCount(.TrafEstimateRowCountRequest) returns (.TrafEstimateRowCountResponse);</code>
+       */
+      public abstract void trafEstimateRowCount(
+          com.google.protobuf.RpcController controller,
+          org.apache.hadoop.hbase.coprocessor.transactional.generated.TrxRegionProtos.TrafEstimateRowCountRequest request,
+          com.google.protobuf.RpcCallback<org.apache.hadoop.hbase.coprocessor.transactional.generated.TrxRegionProtos.TrafEstimateRowCountResponse> done);
+
+      /**
        * <code>rpc GetMax(.TransactionalAggregateRequest) returns (.TransactionalAggregateResponse);</code>
        */
       public abstract void getMax(
@@ -46869,6 +48327,14 @@ public final class TrxRegionProtos {
         }
 
         @java.lang.Override
+        public  void trafEstimateRowCount(
+            com.google.protobuf.RpcController controller,
+            org.apache.hadoop.hbase.coprocessor.transactional.generated.TrxRegionProtos.TrafEstimateRowCountRequest request,
+            com.google.protobuf.RpcCallback<org.apache.hadoop.hbase.coprocessor.transactional.generated.TrxRegionProtos.TrafEstimateRowCountResponse> done) {
+          impl.trafEstimateRowCount(controller, request, done);
+        }
+
+        @java.lang.Override
         public  void getMax(
             com.google.protobuf.RpcController controller,
             org.apache.hadoop.hbase.coprocessor.transactional.generated.TrxRegionProtos.TransactionalAggregateRequest request,
@@ -47001,18 +48467,20 @@ public final class TrxRegionProtos {
             case 26:
               return impl.getTransactionStatesPriorToAsn(controller, (org.apache.hadoop.hbase.coprocessor.transactional.generated.TrxRegionProtos.TlogTransactionStatesFromIntervalRequest)request);
             case 27:
-              return impl.getMax(controller, (org.apache.hadoop.hbase.coprocessor.transactional.generated.TrxRegionProtos.TransactionalAggregateRequest)request);
+              return impl.trafEstimateRowCount(controller, (org.apache.hadoop.hbase.coprocessor.transactional.generated.TrxRegionProtos.TrafEstimateRowCountRequest)request);
             case 28:
-              return impl.getMin(controller, (org.apache.hadoop.hbase.coprocessor.transactional.generated.TrxRegionProtos.TransactionalAggregateRequest)request);
+              return impl.getMax(controller, (org.apache.hadoop.hbase.coprocessor.transactional.generated.TrxRegionProtos.TransactionalAggregateRequest)request);
             case 29:
-              return impl.getSum(controller, (org.apache.hadoop.hbase.coprocessor.transactional.generated.TrxRegionProtos.TransactionalAggregateRequest)request);
+              return impl.getMin(controller, (org.apache.hadoop.hbase.coprocessor.transactional.generated.TrxRegionProtos.TransactionalAggregateRequest)request);
             case 30:
-              return impl.getRowNum(controller, (org.apache.hadoop.hbase.coprocessor.transactional.generated.TrxRegionProtos.TransactionalAggregateRequest)request);
+              return impl.getSum(controller, (org.apache.hadoop.hbase.coprocessor.transactional.generated.TrxRegionProtos.TransactionalAggregateRequest)request);
             case 31:
-              return impl.getAvg(controller, (org.apache.hadoop.hbase.coprocessor.transactional.generated.TrxRegionProtos.TransactionalAggregateRequest)request);
+              return impl.getRowNum(controller, (org.apache.hadoop.hbase.coprocessor.transactional.generated.TrxRegionProtos.TransactionalAggregateRequest)request);
             case 32:
-              return impl.getStd(controller, (org.apache.hadoop.hbase.coprocessor.transactional.generated.TrxRegionProtos.TransactionalAggregateRequest)request);
+              return impl.getAvg(controller, (org.apache.hadoop.hbase.coprocessor.transactional.generated.TrxRegionProtos.TransactionalAggregateRequest)request);
             case 33:
+              return impl.getStd(controller, (org.apache.hadoop.hbase.coprocessor.transactional.generated.TrxRegionProtos.TransactionalAggregateRequest)request);
+            case 34:
               return impl.getMedian(controller, (org.apache.hadoop.hbase.coprocessor.transactional.generated.TrxRegionProtos.TransactionalAggregateRequest)request);
             default:
               throw new java.lang.AssertionError("Can't get here.");
@@ -47083,7 +48551,7 @@ public final class TrxRegionProtos {
             case 26:
               return org.apache.hadoop.hbase.coprocessor.transactional.generated.TrxRegionProtos.TlogTransactionStatesFromIntervalRequest.getDefaultInstance();
             case 27:
-              return org.apache.hadoop.hbase.coprocessor.transactional.generated.TrxRegionProtos.TransactionalAggregateRequest.getDefaultInstance();
+              return org.apache.hadoop.hbase.coprocessor.transactional.generated.TrxRegionProtos.TrafEstimateRowCountRequest.getDefaultInstance();
             case 28:
               return org.apache.hadoop.hbase.coprocessor.transactional.generated.TrxRegionProtos.TransactionalAggregateRequest.getDefaultInstance();
             case 29:
@@ -47096,6 +48564,8 @@ public final class TrxRegionProtos {
               return org.apache.hadoop.hbase.coprocessor.transactional.generated.TrxRegionProtos.TransactionalAggregateRequest.getDefaultInstance();
             case 33:
               return org.apache.hadoop.hbase.coprocessor.transactional.generated.TrxRegionProtos.TransactionalAggregateRequest.getDefaultInstance();
+            case 34:
+              return org.apache.hadoop.hbase.coprocessor.transactional.generated.TrxRegionProtos.TransactionalAggregateRequest.getDefaultInstance();
             default:
               throw new java.lang.AssertionError("Can't get here.");
           }
@@ -47165,7 +48635,7 @@ public final class TrxRegionProtos {
             case 26:
               return org.apache.hadoop.hbase.coprocessor.transactional.generated.TrxRegionProtos.TlogTransactionStatesFromIntervalResponse.getDefaultInstance();
             case 27:
-              return org.apache.hadoop.hbase.coprocessor.transactional.generated.TrxRegionProtos.TransactionalAggregateResponse.getDefaultInstance();
+              return org.apache.hadoop.hbase.coprocessor.transactional.generated.TrxRegionProtos.TrafEstimateRowCountResponse.getDefaultInstance();
             case 28:
               return org.apache.hadoop.hbase.coprocessor.transactional.generated.TrxRegionProtos.TransactionalAggregateResponse.getDefaultInstance();
             case 29:
@@ -47178,6 +48648,8 @@ public final class TrxRegionProtos {
               return org.apache.hadoop.hbase.coprocessor.transactional.generated.TrxRegionProtos.TransactionalAggregateResponse.getDefaultInstance();
             case 33:
               return org.apache.hadoop.hbase.coprocessor.transactional.generated.TrxRegionProtos.TransactionalAggregateResponse.getDefaultInstance();
+            case 34:
+              return org.apache.hadoop.hbase.coprocessor.transactional.generated.TrxRegionProtos.TransactionalAggregateResponse.getDefaultInstance();
             default:
               throw new java.lang.AssertionError("Can't get here.");
           }
@@ -47403,6 +48875,14 @@ public final class TrxRegionProtos {
         com.google.protobuf.RpcCallback<org.apache.hadoop.hbase.coprocessor.transactional.generated.TrxRegionProtos.TlogTransactionStatesFromIntervalResponse> done);
 
     /**
+     * <code>rpc trafEstimateRowCount(.TrafEstimateRowCountRequest) returns (.TrafEstimateRowCountResponse);</code>
+     */
+    public abstract void trafEstimateRowCount(
+        com.google.protobuf.RpcController controller,
+        org.apache.hadoop.hbase.coprocessor.transactional.generated.TrxRegionProtos.TrafEstimateRowCountRequest request,
+        com.google.protobuf.RpcCallback<org.apache.hadoop.hbase.coprocessor.transactional.generated.TrxRegionProtos.TrafEstimateRowCountResponse> done);
+
+    /**
      * <code>rpc GetMax(.TransactionalAggregateRequest) returns (.TransactionalAggregateResponse);</code>
      */
     public abstract void getMax(
@@ -47616,36 +49096,41 @@ public final class TrxRegionProtos {
               done));
           return;
         case 27:
+          this.trafEstimateRowCount(controller, (org.apache.hadoop.hbase.coprocessor.transactional.generated.TrxRegionProtos.TrafEstimateRowCountRequest)request,
+            com.google.protobuf.RpcUtil.<org.apache.hadoop.hbase.coprocessor.transactional.generated.TrxRegionProtos.TrafEstimateRowCountResponse>specializeCallback(
+              done));
+          return;
+        case 28:
           this.getMax(controller, (org.apache.hadoop.hbase.coprocessor.transactional.generated.TrxRegionProtos.TransactionalAggregateRequest)request,
             com.google.protobuf.RpcUtil.<org.apache.hadoop.hbase.coprocessor.transactional.generated.TrxRegionProtos.TransactionalAggregateResponse>specializeCallback(
               done));
           return;
-        case 28:
+        case 29:
           this.getMin(controller, (org.apache.hadoop.hbase.coprocessor.transactional.generated.TrxRegionProtos.TransactionalAggregateRequest)request,
             com.google.protobuf.RpcUtil.<org.apache.hadoop.hbase.coprocessor.transactional.generated.TrxRegionProtos.TransactionalAggregateResponse>specializeCallback(
               done));
           return;
-        case 29:
+        case 30:
           this.getSum(controller, (org.apache.hadoop.hbase.coprocessor.transactional.generated.TrxRegionProtos.TransactionalAggregateRequest)request,
             com.google.protobuf.RpcUtil.<org.apache.hadoop.hbase.coprocessor.transactional.generated.TrxRegionProtos.TransactionalAggregateResponse>specializeCallback(
               done));
           return;
-        case 30:
+        case 31:
           this.getRowNum(controller, (org.apache.hadoop.hbase.coprocessor.transactional.generated.TrxRegionProtos.TransactionalAggregateRequest)request,
             com.google.protobuf.RpcUtil.<org.apache.hadoop.hbase.coprocessor.transactional.generated.TrxRegionProtos.TransactionalAggregateResponse>specializeCallback(
               done));
           return;
-        case 31:
+        case 32:
           this.getAvg(controller, (org.apache.hadoop.hbase.coprocessor.transactional.generated.TrxRegionProtos.TransactionalAggregateRequest)request,
             com.google.protobuf.RpcUtil.<org.apache.hadoop.hbase.coprocessor.transactional.generated.TrxRegionProtos.TransactionalAggregateResponse>specializeCallback(
               done));
           return;
-        case 32:
+        case 33:
           this.getStd(controller, (org.apache.hadoop.hbase.coprocessor.transactional.generated.TrxRegionProtos.TransactionalAggregateRequest)request,
             com.google.protobuf.RpcUtil.<org.apache.hadoop.hbase.coprocessor.transactional.generated.TrxRegionProtos.TransactionalAggregateResponse>specializeCallback(
               done));
           return;
-        case 33:
+        case 34:
           this.getMedian(controller, (org.apache.hadoop.hbase.coprocessor.transactional.generated.TrxRegionProtos.TransactionalAggregateRequest)request,
             com.google.protobuf.RpcUtil.<org.apache.hadoop.hbase.coprocessor.transactional.generated.TrxRegionProtos.TransactionalAggregateResponse>specializeCallback(
               done));
@@ -47719,7 +49204,7 @@ public final class TrxRegionProtos {
         case 26:
           return org.apache.hadoop.hbase.coprocessor.transactional.generated.TrxRegionProtos.TlogTransactionStatesFromIntervalRequest.getDefaultInstance();
         case 27:
-          return org.apache.hadoop.hbase.coprocessor.transactional.generated.TrxRegionProtos.TransactionalAggregateRequest.getDefaultInstance();
+          return org.apache.hadoop.hbase.coprocessor.transactional.generated.TrxRegionProtos.TrafEstimateRowCountRequest.getDefaultInstance();
         case 28:
           return org.apache.hadoop.hbase.coprocessor.transactional.generated.TrxRegionProtos.TransactionalAggregateRequest.getDefaultInstance();
         case 29:
@@ -47732,6 +49217,8 @@ public final class TrxRegionProtos {
           return org.apache.hadoop.hbase.coprocessor.transactional.generated.TrxRegionProtos.TransactionalAggregateRequest.getDefaultInstance();
         case 33:
           return org.apache.hadoop.hbase.coprocessor.transactional.generated.TrxRegionProtos.TransactionalAggregateRequest.getDefaultInstance();
+        case 34:
+          return org.apache.hadoop.hbase.coprocessor.transactional.generated.TrxRegionProtos.TransactionalAggregateRequest.getDefaultInstance();
         default:
           throw new java.lang.AssertionError("Can't get here.");
       }
@@ -47801,7 +49288,7 @@ public final class TrxRegionProtos {
         case 26:
           return org.apache.hadoop.hbase.coprocessor.transactional.generated.TrxRegionProtos.TlogTransactionStatesFromIntervalResponse.getDefaultInstance();
         case 27:
-          return org.apache.hadoop.hbase.coprocessor.transactional.generated.TrxRegionProtos.TransactionalAggregateResponse.getDefaultInstance();
+          return org.apache.hadoop.hbase.coprocessor.transactional.generated.TrxRegionProtos.TrafEstimateRowCountResponse.getDefaultInstance();
         case 28:
           return org.apache.hadoop.hbase.coprocessor.transactional.generated.TrxRegionProtos.TransactionalAggregateResponse.getDefaultInstance();
         case 29:
@@ -47814,6 +49301,8 @@ public final class TrxRegionProtos {
           return org.apache.hadoop.hbase.coprocessor.transactional.generated.TrxRegionProtos.TransactionalAggregateResponse.getDefaultInstance();
         case 33:
           return org.apache.hadoop.hbase.coprocessor.transactional.generated.TrxRegionProtos.TransactionalAggregateResponse.getDefaultInstance();
+        case 34:
+          return org.apache.hadoop.hbase.coprocessor.transactional.generated.TrxRegionProtos.TransactionalAggregateResponse.getDefaultInstance();
         default:
           throw new java.lang.AssertionError("Can't get here.");
       }
@@ -48240,12 +49729,27 @@ public final class TrxRegionProtos {
             org.apache.hadoop.hbase.coprocessor.transactional.generated.TrxRegionProtos.TlogTransactionStatesFromIntervalResponse.getDefaultInstance()));
       }
 
+      public  void trafEstimateRowCount(
+          com.google.protobuf.RpcController controller,
+          org.apache.hadoop.hbase.coprocessor.transactional.generated.TrxRegionProtos.TrafEstimateRowCountRequest request,
+          com.google.protobuf.RpcCallback<org.apache.hadoop.hbase.coprocessor.transactional.generated.TrxRegionProtos.TrafEstimateRowCountResponse> done) {
+        channel.callMethod(
+          getDescriptor().getMethods().get(27),
+          controller,
+          request,
+          org.apache.hadoop.hbase.coprocessor.transactional.generated.TrxRegionProtos.TrafEstimateRowCountResponse.getDefaultInstance(),
+          com.google.protobuf.RpcUtil.generalizeCallback(
+            done,
+            org.apache.hadoop.hbase.coprocessor.transactional.generated.TrxRegionProtos.TrafEstimateRowCountResponse.class,
+            org.apache.hadoop.hbase.coprocessor.transactional.generated.TrxRegionProtos.TrafEstimateRowCountResponse.getDefaultInstance()));
+      }
+
       public  void getMax(
           com.google.protobuf.RpcController controller,
           org.apache.hadoop.hbase.coprocessor.transactional.generated.TrxRegionProtos.TransactionalAggregateRequest request,
           com.google.protobuf.RpcCallback<org.apache.hadoop.hbase.coprocessor.transactional.generated.TrxRegionProtos.TransactionalAggregateResponse> done) {
         channel.callMethod(
-          getDescriptor().getMethods().get(27),
+          getDescriptor().getMethods().get(28),
           controller,
           request,
           org.apache.hadoop.hbase.coprocessor.transactional.generated.TrxRegionProtos.TransactionalAggregateResponse.getDefaultInstance(),
@@ -48260,7 +49764,7 @@ public final class TrxRegionProtos {
           org.apache.hadoop.hbase.coprocessor.transactional.generated.TrxRegionProtos.TransactionalAggregateRequest request,
           com.google.protobuf.RpcCallback<org.apache.hadoop.hbase.coprocessor.transactional.generated.TrxRegionProtos.TransactionalAggregateResponse> done) {
         channel.callMethod(
-          getDescriptor().getMethods().get(28),
+          getDescriptor().getMethods().get(29),
           controller,
           request,
           org.apache.hadoop.hbase.coprocessor.transactional.generated.TrxRegionProtos.TransactionalAggregateResponse.getDefaultInstance(),
@@ -48275,7 +49779,7 @@ public final class TrxRegionProtos {
           org.apache.hadoop.hbase.coprocessor.transactional.generated.TrxRegionProtos.TransactionalAggregateRequest request,
           com.google.protobuf.RpcCallback<org.apache.hadoop.hbase.coprocessor.transactional.generated.TrxRegionProtos.TransactionalAggregateResponse> done) {
         channel.callMethod(
-          getDescriptor().getMethods().get(29),
+          getDescriptor().getMethods().get(30),
           controller,
           request,
           org.apache.hadoop.hbase.coprocessor.transactional.generated.TrxRegionProtos.TransactionalAggregateResponse.getDefaultInstance(),
@@ -48290,7 +49794,7 @@ public final class TrxRegionProtos {
           org.apache.hadoop.hbase.coprocessor.transactional.generated.TrxRegionProtos.TransactionalAggregateRequest request,
           com.google.protobuf.RpcCallback<org.apache.hadoop.hbase.coprocessor.transactional.generated.TrxRegionProtos.TransactionalAggregateResponse> done) {
         channel.callMethod(
-          getDescriptor().getMethods().get(30),
+          getDescriptor().getMethods().get(31),
           controller,
           request,
           org.apache.hadoop.hbase.coprocessor.transactional.generated.TrxRegionProtos.TransactionalAggregateResponse.getDefaultInstance(),
@@ -48305,7 +49809,7 @@ public final class TrxRegionProtos {
           org.apache.hadoop.hbase.coprocessor.transactional.generated.TrxRegionProtos.TransactionalAggregateRequest request,
           com.google.protobuf.RpcCallback<org.apache.hadoop.hbase.coprocessor.transactional.generated.TrxRegionProtos.TransactionalAggregateResponse> done) {
         channel.callMethod(
-          getDescriptor().getMethods().get(31),
+          getDescriptor().getMethods().get(32),
           controller,
           request,
           org.apache.hadoop.hbase.coprocessor.transactional.generated.TrxRegionProtos.TransactionalAggregateResponse.getDefaultInstance(),
@@ -48320,7 +49824,7 @@ public final class TrxRegionProtos {
           org.apache.hadoop.hbase.coprocessor.transactional.generated.TrxRegionProtos.TransactionalAggregateRequest request,
           com.google.protobuf.RpcCallback<org.apache.hadoop.hbase.coprocessor.transactional.generated.TrxRegionProtos.TransactionalAggregateResponse> done) {
         channel.callMethod(
-          getDescriptor().getMethods().get(32),
+          getDescriptor().getMethods().get(33),
           controller,
           request,
           org.apache.hadoop.hbase.coprocessor.transactional.generated.TrxRegionProtos.TransactionalAggregateResponse.getDefaultInstance(),
@@ -48335,7 +49839,7 @@ public final class TrxRegionProtos {
           org.apache.hadoop.hbase.coprocessor.transactional.generated.TrxRegionProtos.TransactionalAggregateRequest request,
           com.google.protobuf.RpcCallback<org.apache.hadoop.hbase.coprocessor.transactional.generated.TrxRegionProtos.TransactionalAggregateResponse> done) {
         channel.callMethod(
-          getDescriptor().getMethods().get(33),
+          getDescriptor().getMethods().get(34),
           controller,
           request,
           org.apache.hadoop.hbase.coprocessor.transactional.generated.TrxRegionProtos.TransactionalAggregateResponse.getDefaultInstance(),
@@ -48487,6 +49991,11 @@ public final class TrxRegionProtos {
           org.apache.hadoop.hbase.coprocessor.transactional.generated.TrxRegionProtos.TlogTransactionStatesFromIntervalRequest request)
           throws com.google.protobuf.ServiceException;
 
+      public org.apache.hadoop.hbase.coprocessor.transactional.generated.TrxRegionProtos.TrafEstimateRowCountResponse trafEstimateRowCount(
+          com.google.protobuf.RpcController controller,
+          org.apache.hadoop.hbase.coprocessor.transactional.generated.TrxRegionProtos.TrafEstimateRowCountRequest request)
+          throws com.google.protobuf.ServiceException;
+
       public org.apache.hadoop.hbase.coprocessor.transactional.generated.TrxRegionProtos.TransactionalAggregateResponse getMax(
           com.google.protobuf.RpcController controller,
           org.apache.hadoop.hbase.coprocessor.transactional.generated.TrxRegionProtos.TransactionalAggregateRequest request)
@@ -48854,12 +50363,24 @@ public final class TrxRegionProtos {
       }
 
 
+      public org.apache.hadoop.hbase.coprocessor.transactional.generated.TrxRegionProtos.TrafEstimateRowCountResponse trafEstimateRowCount(
+          com.google.protobuf.RpcController controller,
+          org.apache.hadoop.hbase.coprocessor.transactional.generated.TrxRegionProtos.TrafEstimateRowCountRequest request)
+          throws com.google.protobuf.ServiceException {
+        return (org.apache.hadoop.hbase.coprocessor.transactional.generated.TrxRegionProtos.TrafEstimateRowCountResponse) channel.callBlockingMethod(
+          getDescriptor().getMethods().get(27),
+          controller,
+          request,
+          org.apache.hadoop.hbase.coprocessor.transactional.generated.TrxRegionProtos.TrafEstimateRowCountResponse.getDefaultInstance());
+      }
+
+
       public org.apache.hadoop.hbase.coprocessor.transactional.generated.TrxRegionProtos.TransactionalAggregateResponse getMax(
           com.google.protobuf.RpcController controller,
           org.apache.hadoop.hbase.coprocessor.transactional.generated.TrxRegionProtos.TransactionalAggregateRequest request)
           throws com.google.protobuf.ServiceException {
         return (org.apache.hadoop.hbase.coprocessor.transactional.generated.TrxRegionProtos.TransactionalAggregateResponse) channel.callBlockingMethod(
-          getDescriptor().getMethods().get(27),
+          getDescriptor().getMethods().get(28),
           controller,
           request,
           org.apache.hadoop.hbase.coprocessor.transactional.generated.TrxRegionProtos.TransactionalAggregateResponse.getDefaultInstance());
@@ -48871,7 +50392,7 @@ public final class TrxRegionProtos {
           org.apache.hadoop.hbase.coprocessor.transactional.generated.TrxRegionProtos.TransactionalAggregateRequest request)
           throws com.google.protobuf.ServiceException {
         return (org.apache.hadoop.hbase.coprocessor.transactional.generated.TrxRegionProtos.TransactionalAggregateResponse) channel.callBlockingMethod(
-          getDescriptor().getMethods().get(28),
+          getDescriptor().getMethods().get(29),
           controller,
           request,
           org.apache.hadoop.hbase.coprocessor.transactional.generated.TrxRegionProtos.TransactionalAggregateResponse.getDefaultInstance());
@@ -48883,7 +50404,7 @@ public final class TrxRegionProtos {
           org.apache.hadoop.hbase.coprocessor.transactional.generated.TrxRegionProtos.TransactionalAggregateRequest request)
           throws com.google.protobuf.ServiceException {
         return (org.apache.hadoop.hbase.coprocessor.transactional.generated.TrxRegionProtos.TransactionalAggregateResponse) channel.callBlockingMethod(
-          getDescriptor().getMethods().get(29),
+          getDescriptor().getMethods().get(30),
           controller,
           request,
           org.apache.hadoop.hbase.coprocessor.transactional.generated.TrxRegionProtos.TransactionalAggregateResponse.getDefaultInstance());
@@ -48895,7 +50416,7 @@ public final class TrxRegionProtos {
           org.apache.hadoop.hbase.coprocessor.transactional.generated.TrxRegionProtos.TransactionalAggregateRequest request)
           throws com.google.protobuf.ServiceException {
         return (org.apache.hadoop.hbase.coprocessor.transactional.generated.TrxRegionProtos.TransactionalAggregateResponse) channel.callBlockingMethod(
-          getDescriptor().getMethods().get(30),
+          getDescriptor().getMethods().get(31),
           controller,
           request,
           org.apache.hadoop.hbase.coprocessor.transactional.generated.TrxRegionProtos.TransactionalAggregateResponse.getDefaultInstance());
@@ -48907,7 +50428,7 @@ public final class TrxRegionProtos {
           org.apache.hadoop.hbase.coprocessor.transactional.generated.TrxRegionProtos.TransactionalAggregateRequest request)
           throws com.google.protobuf.ServiceException {
         return (org.apache.hadoop.hbase.coprocessor.transactional.generated.TrxRegionProtos.TransactionalAggregateResponse) channel.callBlockingMethod(
-          getDescriptor().getMethods().get(31),
+          getDescriptor().getMethods().get(32),
           controller,
           request,
           org.apache.hadoop.hbase.coprocessor.transactional.generated.TrxRegionProtos.TransactionalAggregateResponse.getDefaultInstance());
@@ -48919,7 +50440,7 @@ public final class TrxRegionProtos {
           org.apache.hadoop.hbase.coprocessor.transactional.generated.TrxRegionProtos.TransactionalAggregateRequest request)
           throws com.google.protobuf.ServiceException {
         return (org.apache.hadoop.hbase.coprocessor.transactional.generated.TrxRegionProtos.TransactionalAggregateResponse) channel.callBlockingMethod(
-          getDescriptor().getMethods().get(32),
+          getDescriptor().getMethods().get(33),
           controller,
           request,
           org.apache.hadoop.hbase.c

<TRUNCATED>


[3/6] incubator-trafodion git commit: [TRAFODION-2617] Optionally push estimate row count logic into HBase coproc

Posted by db...@apache.org.
[TRAFODION-2617] Optionally push estimate row count logic into HBase coproc


Project: http://git-wip-us.apache.org/repos/asf/incubator-trafodion/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-trafodion/commit/8b93ad50
Tree: http://git-wip-us.apache.org/repos/asf/incubator-trafodion/tree/8b93ad50
Diff: http://git-wip-us.apache.org/repos/asf/incubator-trafodion/diff/8b93ad50

Branch: refs/heads/master
Commit: 8b93ad50673a1be3ca9ae0e21eb00bb5627cc03a
Parents: d538162
Author: Dave Birdsall <db...@apache.org>
Authored: Mon Aug 14 18:17:53 2017 +0000
Committer: Dave Birdsall <db...@apache.org>
Committed: Mon Aug 14 18:17:53 2017 +0000

----------------------------------------------------------------------
 .../transactional/TrxRegionEndpoint.java.tmpl   |  242 +++
 .../generated/TrxRegionProtos.java              | 1935 ++++++++++++++++--
 .../hbase-trx/src/main/protobuf/TrxRegion.proto |   19 +
 core/sql/executor/HBaseClient_JNI.cpp           |    8 +-
 core/sql/executor/HBaseClient_JNI.h             |    4 +-
 core/sql/exp/ExpHbaseInterface.cpp              |    4 +-
 core/sql/exp/ExpHbaseInterface.h                |    2 +
 core/sql/optimizer/NATable.cpp                  |   14 +-
 core/sql/sqlcomp/DefaultConstants.h             |    4 +
 core/sql/sqlcomp/nadefaults.cpp                 |    5 +
 .../java/org/trafodion/sql/HBaseClient.java     |  190 ++
 11 files changed, 2229 insertions(+), 198 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-trafodion/blob/8b93ad50/core/sqf/src/seatrans/hbase-trx/src/main/java/org/apache/hadoop/hbase/coprocessor/transactional/TrxRegionEndpoint.java.tmpl
----------------------------------------------------------------------
diff --git a/core/sqf/src/seatrans/hbase-trx/src/main/java/org/apache/hadoop/hbase/coprocessor/transactional/TrxRegionEndpoint.java.tmpl b/core/sqf/src/seatrans/hbase-trx/src/main/java/org/apache/hadoop/hbase/coprocessor/transactional/TrxRegionEndpoint.java.tmpl
index 9baa5e7..5c5c5ab 100644
--- a/core/sqf/src/seatrans/hbase-trx/src/main/java/org/apache/hadoop/hbase/coprocessor/transactional/TrxRegionEndpoint.java.tmpl
+++ b/core/sqf/src/seatrans/hbase-trx/src/main/java/org/apache/hadoop/hbase/coprocessor/transactional/TrxRegionEndpoint.java.tmpl
@@ -151,6 +151,7 @@ import org.apache.hadoop.hbase.HTableDescriptor;
 import org.apache.hadoop.hbase.ServerName;
 import org.apache.hadoop.hbase.Tag;
 import org.apache.hadoop.hbase.regionserver.RegionServerServices;
+import org.apache.hadoop.hbase.regionserver.StoreFileInfo;
 import org.apache.hadoop.hbase.Stoppable;
 import org.apache.hadoop.hbase.NotServingRegionException;
 import org.apache.hadoop.hbase.UnknownScannerException;
@@ -243,6 +244,8 @@ import org.apache.hadoop.hbase.coprocessor.transactional.generated.TrxRegionProt
 import org.apache.hadoop.hbase.coprocessor.transactional.generated.TrxRegionProtos.TlogTransactionStatesFromIntervalResponse;
 import org.apache.hadoop.hbase.coprocessor.transactional.generated.TrxRegionProtos.TlogWriteRequest;
 import org.apache.hadoop.hbase.coprocessor.transactional.generated.TrxRegionProtos.TlogWriteResponse;
+import org.apache.hadoop.hbase.coprocessor.transactional.generated.TrxRegionProtos.TrafEstimateRowCountRequest;
+import org.apache.hadoop.hbase.coprocessor.transactional.generated.TrxRegionProtos.TrafEstimateRowCountResponse;
 import org.apache.hadoop.hbase.coprocessor.transactional.generated.TrxRegionProtos.TransactionalAggregateRequest;
 import org.apache.hadoop.hbase.coprocessor.transactional.generated.TrxRegionProtos.TransactionalAggregateResponse;
 import org.apache.hadoop.hbase.coprocessor.transactional.generated.TrxRegionProtos.TrxRegionService;
@@ -7335,6 +7338,245 @@ TrxTransactionState isTransactionOnCommittedList(final long transactionId)
   public void setClosing(boolean value) {
     closing.set(value);
   }
+
+  // The following are methods for the Trafodion SQL coprocessors.
+
+  // compares two qualifiers as unsigned, lexicographically ordered byte strings
+
+  static private boolean isQualifierLessThanOrEqual(Cell nextKv, Cell currKv) {
+    int currLength = currKv.getQualifierLength(); 
+    int currOffset = currKv.getQualifierOffset();
+    byte [] currQual = currKv.getQualifierArray();
+    int nextLength = nextKv.getQualifierLength(); 
+    int nextOffset = nextKv.getQualifierOffset();
+    byte [] nextQual = nextKv.getQualifierArray();   
+
+    int minLength = nextLength;
+    if (currLength < nextLength)
+      minLength = currLength;
+
+    for (int i = 0; i < minLength; i++) {
+      // ugh... have to do some gymnastics to make this an
+      // unsigned comparison
+      int nextQualI = nextQual[i+nextOffset];
+      if (nextQualI < 0)
+        nextQualI = nextQualI + 256;
+      int currQualI = currQual[i+currOffset];
+      if (currQualI < 0)
+        currQualI = currQualI + 256;
+
+      if (nextQualI < currQualI)
+        return true;
+      else if (nextQualI > currQualI)
+        return false;
+      // else equal, move on to next byte
+    }
+
+    // the first minLength bytes are the same; the shorter array
+    // is regarded as less
+
+    boolean rc = (nextLength <= currLength);      
+
+    return rc;
+  }
+
+  
+  // debugging function
+
+  private static String bytesToHex(byte[] in) {
+    final StringBuilder builder = new StringBuilder();
+    for(byte b : in) {
+        builder.append(String.format("%02x", b));
+    }
+    return builder.toString();
+  }
+
+  // Returns data needed to estimate the row count in the table.
+  // Entry counts and total size in bytes are extracted from HFiles.
+  // For non-aligned tables (numCols > 1), sampling is done in order
+  // to estimate how many entries make up a row on average.
+
+  @Override
+  public void trafEstimateRowCount(RpcController controller,
+			           TrafEstimateRowCountRequest request,
+			           RpcCallback<TrafEstimateRowCountResponse> done) {
+
+    TrafEstimateRowCountResponse response = null;
+    Throwable t = null;
+
+    int numCols = request.getNumCols();
+
+    // To estimate incidence of nulls, read the first 500 rows worth
+    // of KeyValues.
+    final int ROWS_TO_SAMPLE = 500;
+    int putKVsSampled = 0;
+    int nonPutKVsSampled = 0;
+    int missingKVsCount = 0;
+    int sampleRowCount = 0;
+    long totalEntries = 0;   // KeyValues in all HFiles for table
+    long totalSizeBytes = 0; // Size of all HFiles for table 
+    long estimatedTotalPuts = 0;
+    boolean more = true;
+    long estimatedRowCount = 0;
+
+    // Access the file system to go directly to the table's HFiles.
+    // Create a reader for the file to access the KV entry count and
+    // size in bytes stored in the trailer block.
+    
+    // For aligned format tables, the number of rows equals the
+    // number of KeyValue entries. For non-aligned format, it's
+    // more complicated. There is a KeyValue entry for each 
+    // column value, except the KeyValue may be missing because
+    // the column has a null value or because the column has a
+    // default value that has not been materialized.
+
+    // For non-aligned format tables, we sample some rows and
+    // count how many entries there are per row, so our caller
+    // can estimate the average number of missing values per row.
+    // Once our caller has that estimate, it can estimate the
+    // number of rows.
+
+    // We only do the sampling for non-aligned tables (numCols > 1),
+    // and we only do it on the first HFile of the first Region.
+    // The first Region is detected by having a null start key.
+
+    CacheConfig cacheConf = new CacheConfig(config);
+    byte[] startKey = regionInfo.getStartKey();
+
+    // Get the list of store files in column family '#1'. There might
+    // not be any. For example, a new Trafodion table might be entirely
+    // in memstore with nothing written out yet. Or we may be accessing
+    // a native HBase table which lacks the '#1' colum family.
+    List<String> storeFileList = null;
+    try {
+      byte[] familyName = "#1".getBytes();
+      byte[][] familyNames = { familyName };
+      storeFileList = m_Region.getStoreFileList(familyNames);
+    }
+    catch (IllegalArgumentException iae) {
+      // this gets thrown when the column family doesn't exist;
+      // we'll just use an empty list instead
+      storeFileList = new ArrayList<String>();
+    }
+
+    if (LOG.isDebugEnabled()) {
+      LOG.debug("Trafodion estimate row count sees " + storeFileList.size() + " files.");
+      for (String sfn : storeFileList) {
+        LOG.debug("*** " + sfn);
+      }
+      if (startKey == null)
+        LOG.debug("startKey is null.");
+      else
+        LOG.debug("startKey.length is " + startKey.length + ", startKey is hex " + bytesToHex(startKey));
+    }
+ 
+    try {
+      FileSystem fileSystem = FileSystem.get(config);
+
+      for (String storeFileName : storeFileList) {
+        Path path = new Path(storeFileName);
+        // Make sure the file name conforms to HFile name pattern.
+        if (!StoreFileInfo.isHFile(path)) {
+          if (LOG.isDebugEnabled()) LOG.debug("Trafodion estimate row count file name " + path + " is not an HFile.");
+          continue;
+        }
+        HFile.Reader reader = HFile.createReader(fileSystem, path, cacheConf, config);
+        try {
+          totalEntries += reader.getEntries();
+          totalSizeBytes += reader.length();        
+          if (ROWS_TO_SAMPLE > 0 &&
+              numCols > 1 &&  // only need to do this for non-aligned format
+              (startKey == null || startKey.length == 0) &&  // first region only
+              totalEntries == reader.getEntries()) {  // first file only
+
+            // Trafodion column qualifiers are ordinal numbers, but are represented
+            // as varying length unsigned little-endian integers in lexicographical
+            // order. So, for example, in a table with 260 columns, the column
+            // qualifiers (if present) will be read in this order: 
+            // 1 (x'01'), 257 (x'0101'), 2 (x'02'), 258 (x'0201'), 3 (x'03'),
+            // 259 (x'0301'), 4 (x'04'), 260 (x'0401'), 5 (x'05'), 6 (x'06'), 
+            // 7 (x'07'), ...
+            // We have crossed the boundary to the next row if and only if the
+            // next qualifier read is less than or equal to the previous, 
+            // compared unsigned, lexicographically.
+
+            HFileScanner scanner = reader.getScanner(false, false, false);
+            scanner.seekTo();  //position at beginning of first data block
+
+            // the next line should succeed, as we know the HFile is non-empty
+            Cell currKv = scanner.getKeyValue();
+            while ((more) && (currKv.getTypeByte() != KeyValue.Type.Put.getCode())) {
+              nonPutKVsSampled++;
+              more = scanner.next();
+              currKv = scanner.getKeyValue();
+            }
+            if (more) {
+              // now we have the first KeyValue in the HFile
+
+              int putKVsThisRow = 1;
+              putKVsSampled++;
+              sampleRowCount++;  // we have at least one row
+              more = scanner.next();
+    
+              while ((more) && (sampleRowCount <= ROWS_TO_SAMPLE)) {
+                Cell nextKv = scanner.getKeyValue();
+                if (nextKv.getTypeByte() == KeyValue.Type.Put.getCode()) {
+                  if (isQualifierLessThanOrEqual(nextKv,currKv)) {
+                    // we have crossed a row boundary
+                    sampleRowCount++;
+                    missingKVsCount += (numCols - putKVsThisRow);
+                    putKVsThisRow = 1;
+                  } else {
+                    putKVsThisRow++;
+                  }
+                  currKv = nextKv;
+                  putKVsSampled++;
+                } else {
+                  nonPutKVsSampled++;  // don't count these toward the number
+                } 
+              more = scanner.next();
+              }
+            }   
+  
+            if (sampleRowCount > ROWS_TO_SAMPLE) {
+              // we read one KeyValue beyond the ROWS_TO_SAMPLE-eth row, so
+              // adjust counts for that
+              putKVsSampled--;
+              sampleRowCount--;
+            }
+          }  // code for first file
+        } catch (IOException exp1) {
+          if (LOG.isErrorEnabled()) LOG.error("Trafodion estimate row count encountered exception ", exp1);
+          t = exp1;
+        } finally {
+          reader.close(false);
+        }
+      } // for
+
+    } catch (IOException exp2) {
+      if (LOG.isErrorEnabled()) LOG.error("Trafodion estimate row count encountered exception ", exp2);
+      t = exp2;  
+    }
+
+    // don't you just love Java + Maven? it takes 112 characters to specify the type of the next variable :-)
+    org.apache.hadoop.hbase.coprocessor.transactional.generated.TrxRegionProtos.TrafEstimateRowCountResponse.Builder
+      responseBuilder = TrafEstimateRowCountResponse.newBuilder();
+    responseBuilder.setTotalEntries(totalEntries).
+      setTotalSizeBytes(totalSizeBytes).
+      setPutKVsSampled(putKVsSampled).
+      setNonPutKVsSampled(nonPutKVsSampled).
+      setMissingKVsCount(missingKVsCount);
+
+    if (t != null)
+    {
+      responseBuilder.setHasException(true);
+      responseBuilder.setException(t.toString());
+    }
+
+    response = responseBuilder.build();
+    done.run(response);
+  }
+
   
 }
 


[4/6] incubator-trafodion git commit: Put back Apache license in generated file

Posted by db...@apache.org.
Put back Apache license in generated file


Project: http://git-wip-us.apache.org/repos/asf/incubator-trafodion/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-trafodion/commit/de124fc2
Tree: http://git-wip-us.apache.org/repos/asf/incubator-trafodion/tree/de124fc2
Diff: http://git-wip-us.apache.org/repos/asf/incubator-trafodion/diff/de124fc2

Branch: refs/heads/master
Commit: de124fc24369d21300e2b392500962c55f5c5ae3
Parents: 8b93ad5
Author: Dave Birdsall <db...@apache.org>
Authored: Mon Aug 14 18:51:57 2017 +0000
Committer: Dave Birdsall <db...@apache.org>
Committed: Mon Aug 14 18:51:57 2017 +0000

----------------------------------------------------------------------
 .../generated/TrxRegionProtos.java              | 23 ++++++++++++++++++++
 1 file changed, 23 insertions(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-trafodion/blob/de124fc2/core/sqf/src/seatrans/hbase-trx/src/main/java/org/apache/hadoop/hbase/coprocessor/transactional/generated/TrxRegionProtos.java
----------------------------------------------------------------------
diff --git a/core/sqf/src/seatrans/hbase-trx/src/main/java/org/apache/hadoop/hbase/coprocessor/transactional/generated/TrxRegionProtos.java b/core/sqf/src/seatrans/hbase-trx/src/main/java/org/apache/hadoop/hbase/coprocessor/transactional/generated/TrxRegionProtos.java
index 0b5af74..ea96915 100755
--- a/core/sqf/src/seatrans/hbase-trx/src/main/java/org/apache/hadoop/hbase/coprocessor/transactional/generated/TrxRegionProtos.java
+++ b/core/sqf/src/seatrans/hbase-trx/src/main/java/org/apache/hadoop/hbase/coprocessor/transactional/generated/TrxRegionProtos.java
@@ -1,3 +1,26 @@
+/**
+* @@@ START COPYRIGHT @@@
+*
+* Licensed to the Apache Software Foundation (ASF) under one
+* or more contributor license agreements.  See the NOTICE file
+* distributed with this work for additional information
+* regarding copyright ownership.  The ASF licenses this file
+* to you under the Apache License, Version 2.0 (the
+* "License"); you may not use this file except in compliance
+* with the License.  You may obtain a copy of the License at
+*
+*   http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing,
+* software distributed under the License is distributed on an
+* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+* KIND, either express or implied.  See the License for the
+* specific language governing permissions and limitations
+* under the License.
+*
+* @@@ END COPYRIGHT @@@
+**/
+
 // Generated by the protocol buffer compiler.  DO NOT EDIT!
 // source: TrxRegion.proto
 


[6/6] incubator-trafodion git commit: Merge [TRAFODION-2617] PR 1206 Optionally push estimate row count into coproc

Posted by db...@apache.org.
Merge [TRAFODION-2617] PR 1206 Optionally push estimate row count into coproc


Project: http://git-wip-us.apache.org/repos/asf/incubator-trafodion/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-trafodion/commit/548ff71b
Tree: http://git-wip-us.apache.org/repos/asf/incubator-trafodion/tree/548ff71b
Diff: http://git-wip-us.apache.org/repos/asf/incubator-trafodion/diff/548ff71b

Branch: refs/heads/master
Commit: 548ff71b4d8027bb499c9e9e3df578720c5e75e3
Parents: baa034f 669efea
Author: Dave Birdsall <db...@apache.org>
Authored: Thu Aug 17 16:43:19 2017 +0000
Committer: Dave Birdsall <db...@apache.org>
Committed: Thu Aug 17 16:43:19 2017 +0000

----------------------------------------------------------------------
 .../transactional/TrxRegionEndpoint.java.tmpl   |  244 +++
 .../generated/TrxRegionProtos.java              | 1842 ++++++++++++++++--
 .../hbase-trx/src/main/protobuf/TrxRegion.proto |   19 +
 core/sql/executor/HBaseClient_JNI.cpp           |    8 +-
 core/sql/executor/HBaseClient_JNI.h             |    4 +-
 core/sql/exp/ExpHbaseInterface.cpp              |    4 +-
 core/sql/exp/ExpHbaseInterface.h                |    2 +
 core/sql/optimizer/NATable.cpp                  |   14 +-
 core/sql/sqlcomp/DefaultConstants.h             |    4 +
 core/sql/sqlcomp/nadefaults.cpp                 |    5 +
 .../java/org/trafodion/sql/HBaseClient.java     |  185 ++
 11 files changed, 2191 insertions(+), 140 deletions(-)
----------------------------------------------------------------------



[5/6] incubator-trafodion git commit: Reworks, addressing Sean's and Selva's comments

Posted by db...@apache.org.
Reworks, addressing Sean's and Selva's comments


Project: http://git-wip-us.apache.org/repos/asf/incubator-trafodion/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-trafodion/commit/669efea7
Tree: http://git-wip-us.apache.org/repos/asf/incubator-trafodion/tree/669efea7
Diff: http://git-wip-us.apache.org/repos/asf/incubator-trafodion/diff/669efea7

Branch: refs/heads/master
Commit: 669efea73181f9c003e4e36c561824412eb5d75a
Parents: de124fc
Author: Dave Birdsall <db...@apache.org>
Authored: Tue Aug 15 22:21:44 2017 +0000
Committer: Dave Birdsall <db...@apache.org>
Committed: Tue Aug 15 22:21:44 2017 +0000

----------------------------------------------------------------------
 .../coprocessor/transactional/TrxRegionEndpoint.java.tmpl   | 6 ++++--
 core/sql/src/main/java/org/trafodion/sql/HBaseClient.java   | 9 ++-------
 2 files changed, 6 insertions(+), 9 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-trafodion/blob/669efea7/core/sqf/src/seatrans/hbase-trx/src/main/java/org/apache/hadoop/hbase/coprocessor/transactional/TrxRegionEndpoint.java.tmpl
----------------------------------------------------------------------
diff --git a/core/sqf/src/seatrans/hbase-trx/src/main/java/org/apache/hadoop/hbase/coprocessor/transactional/TrxRegionEndpoint.java.tmpl b/core/sqf/src/seatrans/hbase-trx/src/main/java/org/apache/hadoop/hbase/coprocessor/transactional/TrxRegionEndpoint.java.tmpl
index 5c5c5ab..430378d 100644
--- a/core/sqf/src/seatrans/hbase-trx/src/main/java/org/apache/hadoop/hbase/coprocessor/transactional/TrxRegionEndpoint.java.tmpl
+++ b/core/sqf/src/seatrans/hbase-trx/src/main/java/org/apache/hadoop/hbase/coprocessor/transactional/TrxRegionEndpoint.java.tmpl
@@ -7536,7 +7536,8 @@ TrxTransactionState isTransactionOnCommittedList(final long transactionId)
                 } 
               more = scanner.next();
               }
-            }   
+            }
+            //scanner.close();  This API is not available until HBase 2.0
   
             if (sampleRowCount > ROWS_TO_SAMPLE) {
               // we read one KeyValue beyond the ROWS_TO_SAMPLE-eth row, so
@@ -7555,7 +7556,8 @@ TrxTransactionState isTransactionOnCommittedList(final long transactionId)
 
     } catch (IOException exp2) {
       if (LOG.isErrorEnabled()) LOG.error("Trafodion estimate row count encountered exception ", exp2);
-      t = exp2;  
+      if (t == null)  // don't bury the root cause if an exception also occurred in the for loop
+        t = exp2;  
     }
 
     // don't you just love Java + Maven? it takes 112 characters to specify the type of the next variable :-)

http://git-wip-us.apache.org/repos/asf/incubator-trafodion/blob/669efea7/core/sql/src/main/java/org/trafodion/sql/HBaseClient.java
----------------------------------------------------------------------
diff --git a/core/sql/src/main/java/org/trafodion/sql/HBaseClient.java b/core/sql/src/main/java/org/trafodion/sql/HBaseClient.java
index 72fa0af..a9e3d3a 100644
--- a/core/sql/src/main/java/org/trafodion/sql/HBaseClient.java
+++ b/core/sql/src/main/java/org/trafodion/sql/HBaseClient.java
@@ -1437,10 +1437,7 @@ public class HBaseClient {
       boolean retcode = true; 
       rc[0] = 0;
 
-      HConnection connection = null;
-      HTableInterface table = null; 
-      connection = HConnectionManager.createConnection(config);
-      table = connection.getTable(tblName);
+      Table table = getConnection().getTable(TableName.valueOf(tblName));
 
       int putKVsSampled = 0;
       int nonPutKVsSampled = 0;
@@ -1564,9 +1561,7 @@ public class HBaseClient {
         // at the first family name, and multiply its length times the number of
         // columns. Even if more than one family is used in the future, presumably
         // they will all be the same short size.
-        Table htbl = getConnection().getTable(TableName.valueOf(tblName));
-        //HTable htbl = new HTable(config, tblName);
-        HTableDescriptor htblDesc = htbl.getTableDescriptor();
+        HTableDescriptor htblDesc = table.getTableDescriptor();
         HColumnDescriptor[] families = htblDesc.getColumnFamilies();
         rowSize += (families[0].getName().length * numCols);
       }