Repository: kylin
Updated Branches:
  refs/heads/master dd0edffc7 -> 422b362ee


Enhance custom measure type extensibility


Project: http://git-wip-us.apache.org/repos/asf/kylin/repo
Commit: http://git-wip-us.apache.org/repos/asf/kylin/commit/422b362e
Tree: http://git-wip-us.apache.org/repos/asf/kylin/tree/422b362e
Diff: http://git-wip-us.apache.org/repos/asf/kylin/diff/422b362e

Branch: refs/heads/master
Commit: 422b362ee7fcb8411c6e2891083e03fd5a2f7a2e
Parents: dd0edff
Author: lidongsjtu <lid...@apache.org>
Authored: Sun May 22 19:11:25 2016 +0800
Committer: lidongsjtu <lid...@apache.org>
Committed: Mon May 23 09:44:07 2016 +0800

----------------------------------------------------------------------
 .../apache/kylin/common/KylinConfigBase.java    |   7 +
 .../kylin/measure/MeasureTypeFactory.java       |  43 ++-
 .../kylin/query/relnode/OLAPAggregateRel.java   |  20 +-
 .../kylin/query/schema/OLAPSchemaFactory.java   |  28 +-
 .../hbase/cube/v2/CubeHBaseEndpointRPC.java     |   2 +
 .../coprocessor/endpoint/CubeVisitService.java  |   8 +
 .../endpoint/generated/CubeVisitProtos.java     | 292 ++++++++++++++++++-
 .../endpoint/protobuf/CubeVisit.proto           |   1 +
 8 files changed, 363 insertions(+), 38 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/kylin/blob/422b362e/core-common/src/main/java/org/apache/kylin/common/KylinConfigBase.java
----------------------------------------------------------------------
diff --git 
a/core-common/src/main/java/org/apache/kylin/common/KylinConfigBase.java 
b/core-common/src/main/java/org/apache/kylin/common/KylinConfigBase.java
index 5355086..2bf4363 100644
--- a/core-common/src/main/java/org/apache/kylin/common/KylinConfigBase.java
+++ b/core-common/src/main/java/org/apache/kylin/common/KylinConfigBase.java
@@ -684,4 +684,11 @@ abstract public class KylinConfigBase implements 
Serializable {
         return 
Boolean.parseBoolean(getOptional("kylin.query.endpoint.compression.result", 
"true"));
     }
 
+    public Map<String, String> getCubeCustomMeasureTypes() {
+        return getPropertiesByPrefix("kylin.cube.measure.customMeasureType.");
+    }
+
+    public Map<String, String> getUDFs() {
+        return getPropertiesByPrefix("kylin.query.udf.");
+    }
 }

http://git-wip-us.apache.org/repos/asf/kylin/blob/422b362e/core-metadata/src/main/java/org/apache/kylin/measure/MeasureTypeFactory.java
----------------------------------------------------------------------
diff --git 
a/core-metadata/src/main/java/org/apache/kylin/measure/MeasureTypeFactory.java 
b/core-metadata/src/main/java/org/apache/kylin/measure/MeasureTypeFactory.java
index 1d264e1..b07490a 100644
--- 
a/core-metadata/src/main/java/org/apache/kylin/measure/MeasureTypeFactory.java
+++ 
b/core-metadata/src/main/java/org/apache/kylin/measure/MeasureTypeFactory.java
@@ -18,9 +18,11 @@
 
 package org.apache.kylin.measure;
 
+import java.util.Collection;
 import java.util.List;
 import java.util.Map;
 
+import org.apache.kylin.common.KylinConfig;
 import org.apache.kylin.measure.basic.BasicMeasureType;
 import org.apache.kylin.measure.bitmap.BitmapMeasureType;
 import org.apache.kylin.measure.dim.DimCountDistinctMeasureType;
@@ -83,30 +85,51 @@ abstract public class MeasureTypeFactory<T> {
     private static Map<String, List<MeasureTypeFactory<?>>> factories = 
Maps.newHashMap();
     private static List<MeasureTypeFactory<?>> defaultFactory = 
Lists.newArrayListWithCapacity(2);
 
+    public static String[] customFactories = null;
+
     static {
         init();
     }
 
+    public static void forceInit() {
+        factories.clear();
+        defaultFactory.clear();
+
+        init();
+    }
+
     public static synchronized void init() {
-        if (factories.isEmpty() == false)
+        if (!factories.isEmpty()) {
             return;
+        }
+
+        if (customFactories == null) {
+            try {
+                Collection<String> customMeasureTypeFactories = 
KylinConfig.getInstanceFromEnv().getCubeCustomMeasureTypes().values();
+                customFactories = customMeasureTypeFactories.toArray(new 
String[customMeasureTypeFactories.size()]);
+            } catch (Exception e) {
+                customFactories = null;
+            }
+        }
 
         List<MeasureTypeFactory<?>> factoryInsts = Lists.newArrayList();
 
-        // two built-in advanced measure types
+        // five built-in advanced measure types
         factoryInsts.add(new HLLCMeasureType.Factory());
         factoryInsts.add(new BitmapMeasureType.Factory());
         factoryInsts.add(new TopNMeasureType.Factory());
         factoryInsts.add(new RawMeasureType.Factory());
         factoryInsts.add(new ExtendedColumnMeasureType.Factory());
 
-        /*
-         * Maybe do classpath search for more custom measure types?
-         * More MeasureType cannot be configured via kylin.properties alone,
-         * because used in coprocessor, the new classes must be on classpath
-         * and be packaged into coprocessor jar. This inevitably involves
-         * rebuild Kylin from code.
-         */
+        if (customFactories != null) {
+            for (String customFactory : customFactories) {
+                try {
+                    factoryInsts.add((MeasureTypeFactory<?>) 
Class.forName(customFactory).newInstance());
+                } catch (Exception e) {
+                    throw new IllegalArgumentException("Unrecognized 
MeasureTypeFactory classname: " + customFactory, e);
+                }
+            }
+        }
 
         // register factories & data type serializers
         for (MeasureTypeFactory<?> factory : factoryInsts) {
@@ -201,6 +224,6 @@ abstract public class MeasureTypeFactory<T> {
         public Class getRewriteCalciteAggrFunctionClass() {
             throw new UnsupportedOperationException();
         }
-        
+
     }
 }

http://git-wip-us.apache.org/repos/asf/kylin/blob/422b362e/query/src/main/java/org/apache/kylin/query/relnode/OLAPAggregateRel.java
----------------------------------------------------------------------
diff --git 
a/query/src/main/java/org/apache/kylin/query/relnode/OLAPAggregateRel.java 
b/query/src/main/java/org/apache/kylin/query/relnode/OLAPAggregateRel.java
index 9a2fa5f..16277e1 100644
--- a/query/src/main/java/org/apache/kylin/query/relnode/OLAPAggregateRel.java
+++ b/query/src/main/java/org/apache/kylin/query/relnode/OLAPAggregateRel.java
@@ -55,6 +55,7 @@ import org.apache.calcite.sql.type.SqlTypeFamily;
 import org.apache.calcite.sql.validate.SqlUserDefinedAggFunction;
 import org.apache.calcite.util.ImmutableBitSet;
 import org.apache.calcite.util.Util;
+import org.apache.kylin.common.KylinConfig;
 import org.apache.kylin.metadata.model.ColumnDesc;
 import org.apache.kylin.metadata.model.FunctionDesc;
 import org.apache.kylin.metadata.model.MeasureDesc;
@@ -79,6 +80,10 @@ public class OLAPAggregateRel extends Aggregate implements 
OLAPRel {
         AGGR_FUNC_MAP.put("COUNT_DISTINCT", "COUNT_DISTINCT");
         AGGR_FUNC_MAP.put("MAX", "MAX");
         AGGR_FUNC_MAP.put("MIN", "MIN");
+
+        for (String customAggrFunc : 
KylinConfig.getInstanceFromEnv().getCubeCustomMeasureTypes().keySet()) {
+            AGGR_FUNC_MAP.put(customAggrFunc.trim().toUpperCase(), 
customAggrFunc.trim().toUpperCase());
+        }
     }
 
     private static String getFuncName(AggregateCall aggCall) {
@@ -206,6 +211,7 @@ public class OLAPAggregateRel extends Aggregate implements 
OLAPRel {
         for (AggregateCall aggCall : this.rewriteAggCalls) {
             ParameterDesc parameter = null;
             if (!aggCall.getArgList().isEmpty()) {
+                // TODO: Currently only get the column of first param
                 int index = aggCall.getArgList().get(0);
                 TblColRef column = inputColumnRowType.getColumnByIndex(index);
                 if (!column.isInnerColumn()) {
@@ -318,7 +324,8 @@ public class OLAPAggregateRel extends Aggregate implements 
OLAPRel {
         if (inputAggRow.getFieldCount() != outputAggRow.getFieldCount()) {
             for (RelDataTypeField inputField : inputAggRow.getFieldList()) {
                 String inputFieldName = inputField.getName();
-                if (outputAggRow.getField(inputFieldName, true, false) == 
null) {
+                // constant columns(starts with $) should not be added to 
context.
+                if (!inputFieldName.startsWith("$") && 
outputAggRow.getField(inputFieldName, true, false) == null) {
                     TblColRef column = 
this.columnRowType.getColumnByIndex(inputField.getIndex());
                     this.context.metricsColumns.add(column);
                 }
@@ -328,12 +335,15 @@ public class OLAPAggregateRel extends Aggregate 
implements OLAPRel {
 
     private AggregateCall rewriteAggregateCall(AggregateCall aggCall, 
FunctionDesc func) {
         // rebuild parameters
-        List<Integer> newArgList = Lists.newArrayListWithCapacity(1);
+        List<Integer> newArgList = Lists.newArrayList(aggCall.getArgList());
         if (func.needRewriteField()) {
             RelDataTypeField field = 
getInput().getRowType().getField(func.getRewriteFieldName(), true, false);
-            newArgList.add(field.getIndex());
-        } else {
-            newArgList = aggCall.getArgList();
+            if (newArgList.isEmpty()) {
+                newArgList.add(field.getIndex());
+            } else {
+                // only the first column got overwritten
+                newArgList.set(0, field.getIndex());
+            }
         }
 
         // rebuild function

http://git-wip-us.apache.org/repos/asf/kylin/blob/422b362e/query/src/main/java/org/apache/kylin/query/schema/OLAPSchemaFactory.java
----------------------------------------------------------------------
diff --git 
a/query/src/main/java/org/apache/kylin/query/schema/OLAPSchemaFactory.java 
b/query/src/main/java/org/apache/kylin/query/schema/OLAPSchemaFactory.java
index 44e9e47..de2daf3 100644
--- a/query/src/main/java/org/apache/kylin/query/schema/OLAPSchemaFactory.java
+++ b/query/src/main/java/org/apache/kylin/query/schema/OLAPSchemaFactory.java
@@ -21,6 +21,7 @@ package org.apache.kylin.query.schema;
 import java.io.File;
 import java.io.FileWriter;
 import java.io.IOException;
+import java.io.Writer;
 import java.util.HashMap;
 import java.util.Map;
 import java.util.Set;
@@ -44,7 +45,6 @@ import org.slf4j.LoggerFactory;
 public class OLAPSchemaFactory implements SchemaFactory {
     public static final Logger logger = 
LoggerFactory.getLogger(OLAPSchemaFactory.class);
 
-
     static {
         /*
          * Tricks Optiq to work with Unicode.
@@ -114,12 +114,7 @@ public class OLAPSchemaFactory implements SchemaFactory {
                 out.write("            \"operand\": {\n");
                 out.write("                \"" + SCHEMA_PROJECT + "\": \"" + 
project + "\"\n");
                 out.write("            },\n");
-                out.write("            \"functions\": [\n");
-                out.write("               {\n");
-                out.write("                   name: 'MASSIN',\n");
-                out.write("                   className: 
'org.apache.kylin.query.udf.MassInUDF'\n");
-                out.write("               }\n");
-                out.write("              ]\n");
+                createOLAPSchemaFunctions(out);
                 out.write("        }\n");
 
                 if (++counter != schemaCounts.size()) {
@@ -141,4 +136,23 @@ public class OLAPSchemaFactory implements SchemaFactory {
         }
     }
 
+    private static void createOLAPSchemaFunctions(Writer out) throws 
IOException {
+        out.write("            \"functions\": [\n");
+        Map<String, String> udfs = KylinConfig.getInstanceFromEnv().getUDFs();
+        int index = 0;
+        for (Map.Entry<String, String> udf : udfs.entrySet()) {
+            String udfName = udf.getKey().trim().toUpperCase();
+            String udfClassName = udf.getValue().trim();
+            out.write("               {\n");
+            out.write("                   name: '" + udfName + "',\n");
+            out.write("                   className: '" + udfClassName + 
"'\n");
+            if (index < udfs.size() - 1) {
+                out.write("               },\n");
+            } else {
+                out.write("               }\n");
+            }
+            index++;
+        }
+        out.write("              ]\n");
+    }
 }

http://git-wip-us.apache.org/repos/asf/kylin/blob/422b362e/storage-hbase/src/main/java/org/apache/kylin/storage/hbase/cube/v2/CubeHBaseEndpointRPC.java
----------------------------------------------------------------------
diff --git 
a/storage-hbase/src/main/java/org/apache/kylin/storage/hbase/cube/v2/CubeHBaseEndpointRPC.java
 
b/storage-hbase/src/main/java/org/apache/kylin/storage/hbase/cube/v2/CubeHBaseEndpointRPC.java
index 8e37361..6d2254b 100644
--- 
a/storage-hbase/src/main/java/org/apache/kylin/storage/hbase/cube/v2/CubeHBaseEndpointRPC.java
+++ 
b/storage-hbase/src/main/java/org/apache/kylin/storage/hbase/cube/v2/CubeHBaseEndpointRPC.java
@@ -21,6 +21,7 @@ package org.apache.kylin.storage.hbase.cube.v2;
 import java.io.IOException;
 import java.nio.BufferOverflowException;
 import java.nio.ByteBuffer;
+import java.util.Arrays;
 import java.util.Iterator;
 import java.util.List;
 import java.util.Map;
@@ -331,6 +332,7 @@ public class CubeHBaseEndpointRPC extends CubeHBaseRPC {
         builder.setStartTime(System.currentTimeMillis());
         builder.setTimeout(epResultItr.getTimeout());
         builder.setUseCompression(compressionResult);
+        
builder.addAllCustomMeasureTypeFactories(KylinConfig.getInstanceFromEnv().getCubeCustomMeasureTypes().values());
 
         for (final Pair<byte[], byte[]> epRange : 
getEPKeyRanges(cuboidBaseShard, shardNum, totalShards)) {
             executorService.submit(new Runnable() {

http://git-wip-us.apache.org/repos/asf/kylin/blob/422b362e/storage-hbase/src/main/java/org/apache/kylin/storage/hbase/cube/v2/coprocessor/endpoint/CubeVisitService.java
----------------------------------------------------------------------
diff --git 
a/storage-hbase/src/main/java/org/apache/kylin/storage/hbase/cube/v2/coprocessor/endpoint/CubeVisitService.java
 
b/storage-hbase/src/main/java/org/apache/kylin/storage/hbase/cube/v2/coprocessor/endpoint/CubeVisitService.java
index 3ccf7cf..156d56b 100644
--- 
a/storage-hbase/src/main/java/org/apache/kylin/storage/hbase/cube/v2/coprocessor/endpoint/CubeVisitService.java
+++ 
b/storage-hbase/src/main/java/org/apache/kylin/storage/hbase/cube/v2/coprocessor/endpoint/CubeVisitService.java
@@ -50,6 +50,7 @@ import org.apache.kylin.gridtable.GTScanRequest;
 import org.apache.kylin.gridtable.IGTScanner;
 import org.apache.kylin.gridtable.IGTStore;
 import org.apache.kylin.measure.BufferedMeasureEncoder;
+import org.apache.kylin.measure.MeasureTypeFactory;
 import org.apache.kylin.metadata.filter.UDF.MassInTupleFilter;
 import org.apache.kylin.metadata.model.TblColRef;
 import org.apache.kylin.metadata.realization.IRealizationConstants;
@@ -163,6 +164,11 @@ public class CubeVisitService extends 
CubeVisitProtos.CubeVisitService implement
         sb.append(",");
     }
 
+    private void initCustomArtifacts(CubeVisitProtos.CubeVisitRequest request) 
{
+        MeasureTypeFactory.customFactories = 
request.getCustomMeasureTypeFactoriesList().toArray(new 
String[request.getCustomMeasureTypeFactoriesCount()]);
+        MeasureTypeFactory.forceInit();
+    }
+
     @Override
     public void visitCube(final RpcController controller, 
CubeVisitProtos.CubeVisitRequest request, 
RpcCallback<CubeVisitProtos.CubeVisitResponse> done) {
 
@@ -176,6 +182,8 @@ public class CubeVisitService extends 
CubeVisitProtos.CubeVisitService implement
         try {
             this.serviceStartTime = System.currentTimeMillis();
 
+            initCustomArtifacts(request);
+
             region = env.getRegion();
             region.startRegionOperation();
             debugGitTag = 
region.getTableDesc().getValue(IRealizationConstants.HTableGitTag);

http://git-wip-us.apache.org/repos/asf/kylin/blob/422b362e/storage-hbase/src/main/java/org/apache/kylin/storage/hbase/cube/v2/coprocessor/endpoint/generated/CubeVisitProtos.java
----------------------------------------------------------------------
diff --git 
a/storage-hbase/src/main/java/org/apache/kylin/storage/hbase/cube/v2/coprocessor/endpoint/generated/CubeVisitProtos.java
 
b/storage-hbase/src/main/java/org/apache/kylin/storage/hbase/cube/v2/coprocessor/endpoint/generated/CubeVisitProtos.java
index 1a9bf05..9c06fb2 100644
--- 
a/storage-hbase/src/main/java/org/apache/kylin/storage/hbase/cube/v2/coprocessor/endpoint/generated/CubeVisitProtos.java
+++ 
b/storage-hbase/src/main/java/org/apache/kylin/storage/hbase/cube/v2/coprocessor/endpoint/generated/CubeVisitProtos.java
@@ -134,6 +134,42 @@ public final class CubeVisitProtos {
      * </pre>
      */
     boolean getUseCompression();
+
+    // repeated string customMeasureTypeFactories = 9;
+    /**
+     * <code>repeated string customMeasureTypeFactories = 9;</code>
+     *
+     * <pre>
+     * customization
+     * </pre>
+     */
+    java.util.List<java.lang.String>
+    getCustomMeasureTypeFactoriesList();
+    /**
+     * <code>repeated string customMeasureTypeFactories = 9;</code>
+     *
+     * <pre>
+     * customization
+     * </pre>
+     */
+    int getCustomMeasureTypeFactoriesCount();
+    /**
+     * <code>repeated string customMeasureTypeFactories = 9;</code>
+     *
+     * <pre>
+     * customization
+     * </pre>
+     */
+    java.lang.String getCustomMeasureTypeFactories(int index);
+    /**
+     * <code>repeated string customMeasureTypeFactories = 9;</code>
+     *
+     * <pre>
+     * customization
+     * </pre>
+     */
+    com.google.protobuf.ByteString
+        getCustomMeasureTypeFactoriesBytes(int index);
   }
   /**
    * Protobuf type {@code CubeVisitRequest}
@@ -229,6 +265,14 @@ public final class CubeVisitProtos {
               useCompression_ = input.readBool();
               break;
             }
+            case 74: {
+              if (!((mutable_bitField0_ & 0x00000100) == 0x00000100)) {
+                customMeasureTypeFactories_ = new 
com.google.protobuf.LazyStringArrayList();
+                mutable_bitField0_ |= 0x00000100;
+              }
+              customMeasureTypeFactories_.add(input.readBytes());
+              break;
+            }
           }
         }
       } catch (com.google.protobuf.InvalidProtocolBufferException e) {
@@ -240,6 +284,9 @@ public final class CubeVisitProtos {
         if (((mutable_bitField0_ & 0x00000010) == 0x00000010)) {
           hbaseColumnsToGT_ = 
java.util.Collections.unmodifiableList(hbaseColumnsToGT_);
         }
+        if (((mutable_bitField0_ & 0x00000100) == 0x00000100)) {
+          customMeasureTypeFactories_ = new 
com.google.protobuf.UnmodifiableLazyStringList(customMeasureTypeFactories_);
+        }
         this.unknownFields = unknownFields.build();
         makeExtensionsImmutable();
       }
@@ -975,6 +1022,52 @@ public final class CubeVisitProtos {
       return useCompression_;
     }
 
+    // repeated string customMeasureTypeFactories = 9;
+    public static final int CUSTOMMEASURETYPEFACTORIES_FIELD_NUMBER = 9;
+    private com.google.protobuf.LazyStringList customMeasureTypeFactories_;
+    /**
+     * <code>repeated string customMeasureTypeFactories = 9;</code>
+     *
+     * <pre>
+     * customization
+     * </pre>
+     */
+    public java.util.List<java.lang.String>
+        getCustomMeasureTypeFactoriesList() {
+      return customMeasureTypeFactories_;
+    }
+    /**
+     * <code>repeated string customMeasureTypeFactories = 9;</code>
+     *
+     * <pre>
+     * customization
+     * </pre>
+     */
+    public int getCustomMeasureTypeFactoriesCount() {
+      return customMeasureTypeFactories_.size();
+    }
+    /**
+     * <code>repeated string customMeasureTypeFactories = 9;</code>
+     *
+     * <pre>
+     * customization
+     * </pre>
+     */
+    public java.lang.String getCustomMeasureTypeFactories(int index) {
+      return customMeasureTypeFactories_.get(index);
+    }
+    /**
+     * <code>repeated string customMeasureTypeFactories = 9;</code>
+     *
+     * <pre>
+     * customization
+     * </pre>
+     */
+    public com.google.protobuf.ByteString
+        getCustomMeasureTypeFactoriesBytes(int index) {
+      return customMeasureTypeFactories_.getByteString(index);
+    }
+
     private void initFields() {
       behavior_ = "";
       gtScanRequest_ = com.google.protobuf.ByteString.EMPTY;
@@ -984,6 +1077,7 @@ public final class CubeVisitProtos {
       startTime_ = 0L;
       timeout_ = 0L;
       useCompression_ = false;
+      customMeasureTypeFactories_ = 
com.google.protobuf.LazyStringArrayList.EMPTY;
     }
     private byte memoizedIsInitialized = -1;
     public final boolean isInitialized() {
@@ -1045,6 +1139,9 @@ public final class CubeVisitProtos {
       if (((bitField0_ & 0x00000040) == 0x00000040)) {
         output.writeBool(8, useCompression_);
       }
+      for (int i = 0; i < customMeasureTypeFactories_.size(); i++) {
+        output.writeBytes(9, customMeasureTypeFactories_.getByteString(i));
+      }
       getUnknownFields().writeTo(output);
     }
 
@@ -1086,6 +1183,15 @@ public final class CubeVisitProtos {
         size += com.google.protobuf.CodedOutputStream
           .computeBoolSize(8, useCompression_);
       }
+      {
+        int dataSize = 0;
+        for (int i = 0; i < customMeasureTypeFactories_.size(); i++) {
+          dataSize += com.google.protobuf.CodedOutputStream
+            
.computeBytesSizeNoTag(customMeasureTypeFactories_.getByteString(i));
+        }
+        size += dataSize;
+        size += 1 * getCustomMeasureTypeFactoriesList().size();
+      }
       size += getUnknownFields().getSerializedSize();
       memoizedSerializedSize = size;
       return size;
@@ -1146,6 +1252,8 @@ public final class CubeVisitProtos {
         result = result && (getUseCompression()
             == other.getUseCompression());
       }
+      result = result && getCustomMeasureTypeFactoriesList()
+          .equals(other.getCustomMeasureTypeFactoriesList());
       result = result &&
           getUnknownFields().equals(other.getUnknownFields());
       return result;
@@ -1191,6 +1299,10 @@ public final class CubeVisitProtos {
         hash = (37 * hash) + USECOMPRESSION_FIELD_NUMBER;
         hash = (53 * hash) + hashBoolean(getUseCompression());
       }
+      if (getCustomMeasureTypeFactoriesCount() > 0) {
+        hash = (37 * hash) + CUSTOMMEASURETYPEFACTORIES_FIELD_NUMBER;
+        hash = (53 * hash) + getCustomMeasureTypeFactoriesList().hashCode();
+      }
       hash = (29 * hash) + getUnknownFields().hashCode();
       memoizedHashCode = hash;
       return hash;
@@ -1321,6 +1433,8 @@ public final class CubeVisitProtos {
         bitField0_ = (bitField0_ & ~0x00000040);
         useCompression_ = false;
         bitField0_ = (bitField0_ & ~0x00000080);
+        customMeasureTypeFactories_ = 
com.google.protobuf.LazyStringArrayList.EMPTY;
+        bitField0_ = (bitField0_ & ~0x00000100);
         return this;
       }
 
@@ -1386,6 +1500,12 @@ public final class CubeVisitProtos {
           to_bitField0_ |= 0x00000040;
         }
         result.useCompression_ = useCompression_;
+        if (((bitField0_ & 0x00000100) == 0x00000100)) {
+          customMeasureTypeFactories_ = new 
com.google.protobuf.UnmodifiableLazyStringList(
+              customMeasureTypeFactories_);
+          bitField0_ = (bitField0_ & ~0x00000100);
+        }
+        result.customMeasureTypeFactories_ = customMeasureTypeFactories_;
         result.bitField0_ = to_bitField0_;
         onBuilt();
         return result;
@@ -1451,6 +1571,16 @@ public final class CubeVisitProtos {
         if (other.hasUseCompression()) {
           setUseCompression(other.getUseCompression());
         }
+        if (!other.customMeasureTypeFactories_.isEmpty()) {
+          if (customMeasureTypeFactories_.isEmpty()) {
+            customMeasureTypeFactories_ = other.customMeasureTypeFactories_;
+            bitField0_ = (bitField0_ & ~0x00000100);
+          } else {
+            ensureCustomMeasureTypeFactoriesIsMutable();
+            
customMeasureTypeFactories_.addAll(other.customMeasureTypeFactories_);
+          }
+          onChanged();
+        }
         this.mergeUnknownFields(other.getUnknownFields());
         return this;
       }
@@ -2068,6 +2198,135 @@ public final class CubeVisitProtos {
         return this;
       }
 
+      // repeated string customMeasureTypeFactories = 9;
+      private com.google.protobuf.LazyStringList customMeasureTypeFactories_ = 
com.google.protobuf.LazyStringArrayList.EMPTY;
+      private void ensureCustomMeasureTypeFactoriesIsMutable() {
+        if (!((bitField0_ & 0x00000100) == 0x00000100)) {
+          customMeasureTypeFactories_ = new 
com.google.protobuf.LazyStringArrayList(customMeasureTypeFactories_);
+          bitField0_ |= 0x00000100;
+         }
+      }
+      /**
+       * <code>repeated string customMeasureTypeFactories = 9;</code>
+       *
+       * <pre>
+       * customization
+       * </pre>
+       */
+      public java.util.List<java.lang.String>
+          getCustomMeasureTypeFactoriesList() {
+        return 
java.util.Collections.unmodifiableList(customMeasureTypeFactories_);
+      }
+      /**
+       * <code>repeated string customMeasureTypeFactories = 9;</code>
+       *
+       * <pre>
+       * customization
+       * </pre>
+       */
+      public int getCustomMeasureTypeFactoriesCount() {
+        return customMeasureTypeFactories_.size();
+      }
+      /**
+       * <code>repeated string customMeasureTypeFactories = 9;</code>
+       *
+       * <pre>
+       * customization
+       * </pre>
+       */
+      public java.lang.String getCustomMeasureTypeFactories(int index) {
+        return customMeasureTypeFactories_.get(index);
+      }
+      /**
+       * <code>repeated string customMeasureTypeFactories = 9;</code>
+       *
+       * <pre>
+       * customization
+       * </pre>
+       */
+      public com.google.protobuf.ByteString
+          getCustomMeasureTypeFactoriesBytes(int index) {
+        return customMeasureTypeFactories_.getByteString(index);
+      }
+      /**
+       * <code>repeated string customMeasureTypeFactories = 9;</code>
+       *
+       * <pre>
+       * customization
+       * </pre>
+       */
+      public Builder setCustomMeasureTypeFactories(
+          int index, java.lang.String value) {
+        if (value == null) {
+    throw new NullPointerException();
+  }
+  ensureCustomMeasureTypeFactoriesIsMutable();
+        customMeasureTypeFactories_.set(index, value);
+        onChanged();
+        return this;
+      }
+      /**
+       * <code>repeated string customMeasureTypeFactories = 9;</code>
+       *
+       * <pre>
+       * customization
+       * </pre>
+       */
+      public Builder addCustomMeasureTypeFactories(
+          java.lang.String value) {
+        if (value == null) {
+    throw new NullPointerException();
+  }
+  ensureCustomMeasureTypeFactoriesIsMutable();
+        customMeasureTypeFactories_.add(value);
+        onChanged();
+        return this;
+      }
+      /**
+       * <code>repeated string customMeasureTypeFactories = 9;</code>
+       *
+       * <pre>
+       * customization
+       * </pre>
+       */
+      public Builder addAllCustomMeasureTypeFactories(
+          java.lang.Iterable<java.lang.String> values) {
+        ensureCustomMeasureTypeFactoriesIsMutable();
+        super.addAll(values, customMeasureTypeFactories_);
+        onChanged();
+        return this;
+      }
+      /**
+       * <code>repeated string customMeasureTypeFactories = 9;</code>
+       *
+       * <pre>
+       * customization
+       * </pre>
+       */
+      public Builder clearCustomMeasureTypeFactories() {
+        customMeasureTypeFactories_ = 
com.google.protobuf.LazyStringArrayList.EMPTY;
+        bitField0_ = (bitField0_ & ~0x00000100);
+        onChanged();
+        return this;
+      }
+      /**
+       * <code>repeated string customMeasureTypeFactories = 9;</code>
+       *
+       * <pre>
+       * customization
+       * </pre>
+       */
+      public Builder addCustomMeasureTypeFactoriesBytes(
+          com.google.protobuf.ByteString value) {
+        if (value == null) {
+    throw new NullPointerException();
+  }
+  ensureCustomMeasureTypeFactoriesIsMutable();
+        customMeasureTypeFactories_.add(value);
+        onChanged();
+        return this;
+      }
+
       // @@protoc_insertion_point(builder_scope:CubeVisitRequest)
     }
 
@@ -4422,26 +4681,27 @@ public final class CubeVisitProtos {
     java.lang.String[] descriptorData = {
       "\npstorage-hbase/src/main/java/org/apache" +
       "/kylin/storage/hbase/cube/v2/coprocessor" +
-      "/endpoint/protobuf/CubeVisit.proto\"\367\001\n\020C" +
+      "/endpoint/protobuf/CubeVisit.proto\"\233\002\n\020C" +
       "ubeVisitRequest\022\020\n\010behavior\030\001 \002(\t\022\025\n\rgtS" +
       "canRequest\030\002 \002(\014\022\024\n\014hbaseRawScan\030\003 
\002(\014\022\032" +
       "\n\022rowkeyPreambleSize\030\004 \002(\005\0223\n\020hbaseColum" +
       "nsToGT\030\005 \003(\0132\031.CubeVisitRequest.IntList\022" +
       "\021\n\tstartTime\030\006 \002(\003\022\017\n\007timeout\030\007 
\002(\003\022\026\n\016u" +
-      "seCompression\030\010 
\001(\010\032\027\n\007IntList\022\014\n\004ints\030\001" +
-      " \003(\005\"\321\002\n\021CubeVisitResponse\022\026\n\016compressed",
-      "Rows\030\001 \002(\014\022\'\n\005stats\030\002 
\002(\0132\030.CubeVisitRes" +
-      "ponse.Stats\032\372\001\n\005Stats\022\030\n\020serviceStartTim" +
-      "e\030\001 \001(\003\022\026\n\016serviceEndTime\030\002 
\001(\003\022\027\n\017scann" +
-      "edRowCount\030\003 \001(\005\022\032\n\022aggregatedRowCount\030\004" +
-      " \001(\005\022\025\n\rsystemCpuLoad\030\005 
\001(\001\022\036\n\026freePhysi" +
-      "calMemorySize\030\006 \001(\001\022\031\n\021freeSwapSpaceSize" +
-      "\030\007 \001(\001\022\020\n\010hostname\030\010 
\001(\t\022\016\n\006etcMsg\030\t \001(\t" +
-      "\022\026\n\016normalComplete\030\n \001(\0052F\n\020CubeVisitSer" +
-      "vice\0222\n\tvisitCube\022\021.CubeVisitRequest\032\022.C" +
-      "ubeVisitResponseB`\nEorg.apache.kylin.sto",
-      "rage.hbase.cube.v2.coprocessor.endpoint." +
-      "generatedB\017CubeVisitProtosH\001\210\001\001\240\001\001"
+      "seCompression\030\010 \001(\010\022\"\n\032customMeasureType" +
+      "Factories\030\t \003(\t\032\027\n\007IntList\022\014\n\004ints\030\001 
\003(\005",
+      "\"\321\002\n\021CubeVisitResponse\022\026\n\016compressedRows" +
+      "\030\001 \002(\014\022\'\n\005stats\030\002 
\002(\0132\030.CubeVisitRespons" +
+      "e.Stats\032\372\001\n\005Stats\022\030\n\020serviceStartTime\030\001 " +
+      "\001(\003\022\026\n\016serviceEndTime\030\002 
\001(\003\022\027\n\017scannedRo" +
+      "wCount\030\003 \001(\005\022\032\n\022aggregatedRowCount\030\004 
\001(\005" +
+      "\022\025\n\rsystemCpuLoad\030\005 \001(\001\022\036\n\026freePhysicalM" 
+
+      "emorySize\030\006 \001(\001\022\031\n\021freeSwapSpaceSize\030\007 
\001" +
+      "(\001\022\020\n\010hostname\030\010 \001(\t\022\016\n\006etcMsg\030\t 
\001(\t\022\026\n\016" +
+      "normalComplete\030\n \001(\0052F\n\020CubeVisitService" +
+      "\0222\n\tvisitCube\022\021.CubeVisitRequest\032\022.CubeV",
+      "isitResponseB`\nEorg.apache.kylin.storage" +
+      ".hbase.cube.v2.coprocessor.endpoint.gene" +
+      "ratedB\017CubeVisitProtosH\001\210\001\001\240\001\001"
     };
     com.google.protobuf.Descriptors.FileDescriptor.InternalDescriptorAssigner 
assigner =
       new 
com.google.protobuf.Descriptors.FileDescriptor.InternalDescriptorAssigner() {
@@ -4453,7 +4713,7 @@ public final class CubeVisitProtos {
           internal_static_CubeVisitRequest_fieldAccessorTable = new
             com.google.protobuf.GeneratedMessage.FieldAccessorTable(
               internal_static_CubeVisitRequest_descriptor,
-              new java.lang.String[] { "Behavior", "GtScanRequest", 
"HbaseRawScan", "RowkeyPreambleSize", "HbaseColumnsToGT", "StartTime", 
"Timeout", "UseCompression", });
+              new java.lang.String[] { "Behavior", "GtScanRequest", 
"HbaseRawScan", "RowkeyPreambleSize", "HbaseColumnsToGT", "StartTime", 
"Timeout", "UseCompression", "CustomMeasureTypeFactories", });
           internal_static_CubeVisitRequest_IntList_descriptor =
             
internal_static_CubeVisitRequest_descriptor.getNestedTypes().get(0);
           internal_static_CubeVisitRequest_IntList_fieldAccessorTable = new

http://git-wip-us.apache.org/repos/asf/kylin/blob/422b362e/storage-hbase/src/main/java/org/apache/kylin/storage/hbase/cube/v2/coprocessor/endpoint/protobuf/CubeVisit.proto
----------------------------------------------------------------------
diff --git 
a/storage-hbase/src/main/java/org/apache/kylin/storage/hbase/cube/v2/coprocessor/endpoint/protobuf/CubeVisit.proto
 
b/storage-hbase/src/main/java/org/apache/kylin/storage/hbase/cube/v2/coprocessor/endpoint/protobuf/CubeVisit.proto
index f16db7b..c9bc5d1 100644
--- 
a/storage-hbase/src/main/java/org/apache/kylin/storage/hbase/cube/v2/coprocessor/endpoint/protobuf/CubeVisit.proto
+++ 
b/storage-hbase/src/main/java/org/apache/kylin/storage/hbase/cube/v2/coprocessor/endpoint/protobuf/CubeVisit.proto
@@ -38,6 +38,7 @@ message CubeVisitRequest {
     required int64 startTime = 6;//when client start the request
     required int64 timeout = 7;//how long client will wait
     optional bool useCompression = 8; // compress result or not
+    repeated string customMeasureTypeFactories = 9; // customization
     message IntList {
         repeated int32 ints = 1;
     }

Reply via email to