Repository: kylin
Updated Branches:
  refs/heads/1.x-staging 97c2eac79 -> f9de5a624


KYLIN-976 Some measures only aggregates in BaseCuboid


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

Branch: refs/heads/1.x-staging
Commit: f9de5a6247666750a154039cf3f2e88514ab1ad2
Parents: 97c2eac
Author: lidongsjtu <don...@ebay.com>
Authored: Mon Dec 28 10:36:13 2015 +0800
Committer: lidongsjtu <don...@ebay.com>
Committed: Mon Dec 28 10:36:13 2015 +0800

----------------------------------------------------------------------
 .../org/apache/kylin/cube/cuboid/Cuboid.java    |   4 +
 .../kylin/job/constant/BatchConstants.java      |   1 +
 .../apache/kylin/job/hadoop/cube/CuboidJob.java |   2 +
 .../kylin/job/hadoop/cube/CuboidReducer.java    |  17 ++-
 .../kylin/job/hadoop/cube/CubeReducerTest.java  | 107 ++++++++++++--
 .../kylin/measure/MeasureAggregators.java       |  10 ++
 .../org/apache/kylin/measure/MeasureType.java   |  13 +-
 .../kylin/storage/hbase/CubeStorageEngine.java  |  11 +-
 .../storage/hbase/CubeStorageEngineTest.java    | 142 +++++++++++++++++++
 9 files changed, 287 insertions(+), 20 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/kylin/blob/f9de5a62/cube/src/main/java/org/apache/kylin/cube/cuboid/Cuboid.java
----------------------------------------------------------------------
diff --git a/cube/src/main/java/org/apache/kylin/cube/cuboid/Cuboid.java 
b/cube/src/main/java/org/apache/kylin/cube/cuboid/Cuboid.java
index 5ef0c37..7f2b7ab 100644
--- a/cube/src/main/java/org/apache/kylin/cube/cuboid/Cuboid.java
+++ b/cube/src/main/java/org/apache/kylin/cube/cuboid/Cuboid.java
@@ -88,6 +88,10 @@ public class Cuboid implements Comparable<Cuboid> {
         return cube.getRowkey().getFullMask();
     }
 
+    public static Cuboid getBaseCuboid(CubeDesc cube) {
+        return findById(cube, getBaseCuboidId(cube));
+    }
+
     private static long translateToValidCuboid(CubeDesc cubeDesc, long 
cuboidID) {
         // add mandantory
         RowKeyDesc rowkey = cubeDesc.getRowkey();

http://git-wip-us.apache.org/repos/asf/kylin/blob/f9de5a62/job/src/main/java/org/apache/kylin/job/constant/BatchConstants.java
----------------------------------------------------------------------
diff --git 
a/job/src/main/java/org/apache/kylin/job/constant/BatchConstants.java 
b/job/src/main/java/org/apache/kylin/job/constant/BatchConstants.java
index ca8b2c9..38f4a87 100644
--- a/job/src/main/java/org/apache/kylin/job/constant/BatchConstants.java
+++ b/job/src/main/java/org/apache/kylin/job/constant/BatchConstants.java
@@ -28,6 +28,7 @@ public interface BatchConstants {
 
     String CFG_CUBE_NAME = "cube.name";
     String CFG_CUBE_SEGMENT_NAME = "cube.segment.name";
+    String CFG_CUBE_CUBOID_LEVEL = "cube.cuboid.level";
 
     String CFG_II_NAME = "ii.name";
     String CFG_II_SEGMENT_NAME = "ii.segment.name";

http://git-wip-us.apache.org/repos/asf/kylin/blob/f9de5a62/job/src/main/java/org/apache/kylin/job/hadoop/cube/CuboidJob.java
----------------------------------------------------------------------
diff --git a/job/src/main/java/org/apache/kylin/job/hadoop/cube/CuboidJob.java 
b/job/src/main/java/org/apache/kylin/job/hadoop/cube/CuboidJob.java
index bff9e3a..e4875e9 100644
--- a/job/src/main/java/org/apache/kylin/job/hadoop/cube/CuboidJob.java
+++ b/job/src/main/java/org/apache/kylin/job/hadoop/cube/CuboidJob.java
@@ -115,6 +115,8 @@ public class CuboidJob extends AbstractHadoopJob {
             // set job configuration
             job.getConfiguration().set(BatchConstants.CFG_CUBE_NAME, cubeName);
             job.getConfiguration().set(BatchConstants.CFG_CUBE_SEGMENT_NAME, 
segmentName);
+            
job.getConfiguration().setInt(BatchConstants.CFG_CUBE_CUBOID_LEVEL, 
nCuboidLevel);
+
             // add metadata to distributed cache
             attachKylinPropsAndMetadata(cube, job.getConfiguration());
 

http://git-wip-us.apache.org/repos/asf/kylin/blob/f9de5a62/job/src/main/java/org/apache/kylin/job/hadoop/cube/CuboidReducer.java
----------------------------------------------------------------------
diff --git 
a/job/src/main/java/org/apache/kylin/job/hadoop/cube/CuboidReducer.java 
b/job/src/main/java/org/apache/kylin/job/hadoop/cube/CuboidReducer.java
index 4527f30..3859d0e 100644
--- a/job/src/main/java/org/apache/kylin/job/hadoop/cube/CuboidReducer.java
+++ b/job/src/main/java/org/apache/kylin/job/hadoop/cube/CuboidReducer.java
@@ -52,6 +52,8 @@ public class CuboidReducer extends KylinReducer<Text, Text, 
Text, Text> {
     private MeasureAggregators aggs;
 
     private int counter;
+    private int cuboidLevel;
+    private boolean[] needAggr;
     private Object[] input;
     private Object[] result;
 
@@ -62,6 +64,8 @@ public class CuboidReducer extends KylinReducer<Text, Text, 
Text, Text> {
     protected void setup(Context context) throws IOException {
         super.publishConfiguration(context.getConfiguration());
         cubeName = 
context.getConfiguration().get(BatchConstants.CFG_CUBE_NAME).toUpperCase();
+        // only used in Build job, not in Merge job
+        cuboidLevel = 
context.getConfiguration().getInt(BatchConstants.CFG_CUBE_CUBOID_LEVEL, 0);
 
         KylinConfig config = 
AbstractHadoopJob.loadKylinPropsAndMetadata(context.getConfiguration());
 
@@ -73,6 +77,13 @@ public class CuboidReducer extends KylinReducer<Text, Text, 
Text, Text> {
 
         input = new Object[measuresDescs.size()];
         result = new Object[measuresDescs.size()];
+        needAggr = new boolean[measuresDescs.size()];
+
+        if (cuboidLevel > 0) {
+            for (int i = 0; i < measuresDescs.size(); i++) {
+                needAggr[i] = 
!measuresDescs.get(i).getFunction().getMeasureType().onlyAggrInBaseCuboid();
+            }
+        }
     }
 
     @Override
@@ -82,7 +93,11 @@ public class CuboidReducer extends KylinReducer<Text, Text, 
Text, Text> {
 
         for (Text value : values) {
             codec.decode(ByteBuffer.wrap(value.getBytes(), 0, 
value.getLength()), input);
-            aggs.aggregate(input);
+            if (cuboidLevel > 0) {
+                aggs.aggregate(input, needAggr);
+            } else {
+                aggs.aggregate(input);
+            }
         }
         aggs.collectStates(result);
 

http://git-wip-us.apache.org/repos/asf/kylin/blob/f9de5a62/job/src/test/java/org/apache/kylin/job/hadoop/cube/CubeReducerTest.java
----------------------------------------------------------------------
diff --git 
a/job/src/test/java/org/apache/kylin/job/hadoop/cube/CubeReducerTest.java 
b/job/src/test/java/org/apache/kylin/job/hadoop/cube/CubeReducerTest.java
index 16cfa89..51f3990 100644
--- a/job/src/test/java/org/apache/kylin/job/hadoop/cube/CubeReducerTest.java
+++ b/job/src/test/java/org/apache/kylin/job/hadoop/cube/CubeReducerTest.java
@@ -22,6 +22,7 @@ import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertTrue;
 
 import java.io.File;
+import java.lang.reflect.Field;
 import java.math.BigDecimal;
 import java.nio.ByteBuffer;
 import java.util.ArrayList;
@@ -37,7 +38,12 @@ import org.apache.kylin.cube.CubeManager;
 import org.apache.kylin.cube.kv.RowConstants;
 import org.apache.kylin.cube.model.CubeDesc;
 import org.apache.kylin.job.constant.BatchConstants;
+import org.apache.kylin.measure.MeasureAggregator;
 import org.apache.kylin.measure.MeasureCodec;
+import org.apache.kylin.measure.MeasureIngester;
+import org.apache.kylin.measure.MeasureType;
+import org.apache.kylin.metadata.model.FunctionDesc;
+import org.apache.kylin.metadata.model.MeasureDesc;
 import org.junit.After;
 import org.junit.Before;
 import org.junit.Test;
@@ -76,18 +82,18 @@ public class CubeReducerTest extends 
LocalFileMetadataTestCase {
 
         Text key1 = new Text("72010ustech");
         List<Text> values1 = new ArrayList<Text>();
-        values1.add(newValueText(codec, "15.09", "15.09", "15.09", 1,22));
-        values1.add(newValueText(codec, "20.34", "20.34", "20.34", 1,23));
-        values1.add(newValueText(codec, "10", "10", "10", 1,24));
+        values1.add(newValueText(codec, "15.09", "15.09", "15.09", 1, 22));
+        values1.add(newValueText(codec, "20.34", "20.34", "20.34", 1, 23));
+        values1.add(newValueText(codec, "10", "10", "10", 1, 24));
 
         Text key2 = new Text("1tech");
         List<Text> values2 = new ArrayList<Text>();
-        values2.add(newValueText(codec, "15.09", "15.09", "15.09", 1,12));
-        values2.add(newValueText(codec, "20.34", "20.34", "20.34", 1,13));
+        values2.add(newValueText(codec, "15.09", "15.09", "15.09", 1, 12));
+        values2.add(newValueText(codec, "20.34", "20.34", "20.34", 1, 13));
 
         Text key3 = new Text("0");
         List<Text> values3 = new ArrayList<Text>();
-        values3.add(newValueText(codec, "146.52", "146.52", "146.52", 4,11));
+        values3.add(newValueText(codec, "146.52", "146.52", "146.52", 4, 11));
 
         reduceDriver.withInput(key1, values1);
         reduceDriver.withInput(key2, values2);
@@ -95,9 +101,9 @@ public class CubeReducerTest extends 
LocalFileMetadataTestCase {
 
         List<Pair<Text, Text>> result = reduceDriver.run();
 
-        Pair<Text, Text> p1 = new Pair<Text, Text>(new Text("72010ustech"), 
newValueText(codec, "45.43", "10", "20.34", 3,69));
-        Pair<Text, Text> p2 = new Pair<Text, Text>(new Text("1tech"), 
newValueText(codec, "35.43", "15.09", "20.34", 2,25));
-        Pair<Text, Text> p3 = new Pair<Text, Text>(new Text("0"), 
newValueText(codec, "146.52", "146.52", "146.52", 4,11));
+        Pair<Text, Text> p1 = new Pair<Text, Text>(new Text("72010ustech"), 
newValueText(codec, "45.43", "10", "20.34", 3, 69));
+        Pair<Text, Text> p2 = new Pair<Text, Text>(new Text("1tech"), 
newValueText(codec, "35.43", "15.09", "20.34", 2, 25));
+        Pair<Text, Text> p3 = new Pair<Text, Text>(new Text("0"), 
newValueText(codec, "146.52", "146.52", "146.52", 4, 11));
 
         assertEquals(3, result.size());
 
@@ -106,8 +112,55 @@ public class CubeReducerTest extends 
LocalFileMetadataTestCase {
         assertTrue(result.contains(p3));
     }
 
-    private Text newValueText(MeasureCodec codec, String sum, String min, 
String max, int count,int itemcount) {
-        Object[] values = new Object[] { new BigDecimal(sum), new 
BigDecimal(min), new BigDecimal(max), new LongWritable(count),new 
LongWritable(itemcount) };
+    @Test
+    public void testReducerOnlyAggrInBaseCuboid() throws Exception {
+        reduceDriver.getConfiguration().set(BatchConstants.CFG_CUBE_NAME, 
"test_kylin_cube_with_slr_ready");
+        
reduceDriver.getConfiguration().setInt(BatchConstants.CFG_CUBE_CUBOID_LEVEL, 1);
+
+        CubeDesc cubeDesc = 
CubeManager.getInstance(getTestConfig()).getCube("test_kylin_cube_with_slr_ready").getDescriptor();
+        MeasureDesc measureDesc = cubeDesc.getMeasures().get(0);
+        FunctionDesc functionDesc = measureDesc.getFunction();
+        Field field = FunctionDesc.class.getDeclaredField("measureType");
+        field.setAccessible(true);
+        MeasureType origMeasureType = functionDesc.getMeasureType();
+        field.set(functionDesc, new MockUpMeasureType(origMeasureType));
+
+        MeasureCodec codec = new MeasureCodec(cubeDesc.getMeasures());
+
+        Text key1 = new Text("72010ustech");
+        List<Text> values1 = new ArrayList<Text>();
+        values1.add(newValueText(codec, "15.09", "15.09", "15.09", 1, 100));
+        values1.add(newValueText(codec, "20.34", "20.34", "20.34", 1, 200));
+        values1.add(newValueText(codec, "10", "10", "10", 1, 300));
+
+        Text key2 = new Text("1tech");
+        List<Text> values2 = new ArrayList<Text>();
+        values2.add(newValueText(codec, "15.09", "15.09", "15.09", 1, 500));
+        values2.add(newValueText(codec, "20.34", "20.34", "20.34", 1, 1000));
+
+        Text key3 = new Text("0");
+        List<Text> values3 = new ArrayList<Text>();
+        values3.add(newValueText(codec, "146.52", "146.52", "146.52", 0, 0));
+
+        reduceDriver.withInput(key1, values1);
+        reduceDriver.withInput(key2, values2);
+        reduceDriver.withInput(key3, values3);
+
+        List<Pair<Text, Text>> result = reduceDriver.run();
+
+        Pair<Text, Text> p1 = new Pair<Text, Text>(new Text("72010ustech"), 
newValueText(codec, "0", "10", "20.34", 3, 600));
+        Pair<Text, Text> p2 = new Pair<Text, Text>(new Text("1tech"), 
newValueText(codec, "0", "15.09", "20.34", 2, 1500));
+        Pair<Text, Text> p3 = new Pair<Text, Text>(new Text("0"), 
newValueText(codec, "0", "146.52", "146.52", 0, 0));
+
+        assertEquals(3, result.size());
+
+        assertTrue(result.contains(p1));
+        assertTrue(result.contains(p2));
+        assertTrue(result.contains(p3));
+    }
+
+    private Text newValueText(MeasureCodec codec, String sum, String min, 
String max, int count, int itemcount) {
+        Object[] values = new Object[] { new BigDecimal(sum), new 
BigDecimal(min), new BigDecimal(max), new LongWritable(count), new 
LongWritable(itemcount) };
 
         buf.clear();
         codec.encode(values, buf);
@@ -117,4 +170,36 @@ public class CubeReducerTest extends 
LocalFileMetadataTestCase {
         return t;
     }
 
+    class MockUpMeasureType extends MeasureType {
+        MeasureType origMeasureType;
+
+        public MockUpMeasureType(MeasureType origMeasureType) {
+            this.origMeasureType = origMeasureType;
+        }
+
+        @Override
+        public boolean onlyAggrInBaseCuboid() {
+            return true;
+        }
+
+        @Override
+        public MeasureIngester newIngester() {
+            return origMeasureType.newIngester();
+        }
+
+        @Override
+        public MeasureAggregator newAggregator() {
+            return origMeasureType.newAggregator();
+        }
+
+        @Override
+        public boolean needRewrite() {
+            return origMeasureType.needRewrite();
+        }
+
+        @Override
+        public Class<?> getRewriteCalciteAggrFunctionClass() {
+            return origMeasureType.getRewriteCalciteAggrFunctionClass();
+        }
+    }
 }

http://git-wip-us.apache.org/repos/asf/kylin/blob/f9de5a62/metadata/src/main/java/org/apache/kylin/measure/MeasureAggregators.java
----------------------------------------------------------------------
diff --git 
a/metadata/src/main/java/org/apache/kylin/measure/MeasureAggregators.java 
b/metadata/src/main/java/org/apache/kylin/measure/MeasureAggregators.java
index 12832ff..a2cb457 100644
--- a/metadata/src/main/java/org/apache/kylin/measure/MeasureAggregators.java
+++ b/metadata/src/main/java/org/apache/kylin/measure/MeasureAggregators.java
@@ -72,6 +72,16 @@ public class MeasureAggregators implements Serializable {
         }
     }
 
+    public void aggregate(Object[] values, boolean[] aggrMask) {
+        assert values.length == descLength;
+        assert aggrMask.length == descLength;
+
+        for (int i = 0; i < descLength; i++) {
+            if (aggrMask[i])
+                aggs[i].aggregate(values[i]);
+        }
+    }
+
     public void collectStates(Object[] states) {
         for (int i = 0; i < descLength; i++) {
             states[i] = aggs[i].getState();

http://git-wip-us.apache.org/repos/asf/kylin/blob/f9de5a62/metadata/src/main/java/org/apache/kylin/measure/MeasureType.java
----------------------------------------------------------------------
diff --git a/metadata/src/main/java/org/apache/kylin/measure/MeasureType.java 
b/metadata/src/main/java/org/apache/kylin/measure/MeasureType.java
index 66ca209..661b335 100644
--- a/metadata/src/main/java/org/apache/kylin/measure/MeasureType.java
+++ b/metadata/src/main/java/org/apache/kylin/measure/MeasureType.java
@@ -39,7 +39,7 @@ import org.apache.kylin.metadata.tuple.TupleInfo;
  * @param <T> the Java type of aggregation data object, e.g. 
HyperLogLogPlusCounter
  */
 abstract public class MeasureType<T> {
-    
+
     /* 
============================================================================
      * Define
      * 
---------------------------------------------------------------------------- */
@@ -55,7 +55,12 @@ abstract public class MeasureType<T> {
     public boolean isMemoryHungry() {
         return false;
     }
-    
+
+    /** Return true if this MeasureType only aggregate values in base cuboid, 
and output initial value in child cuboid. */
+    public boolean onlyAggrInBaseCuboid() {
+        return false;
+    }
+
     /* 
============================================================================
      * Build
      * 
---------------------------------------------------------------------------- */
@@ -92,7 +97,7 @@ abstract public class MeasureType<T> {
     public CapabilityInfluence influenceCapabilityCheck(Collection<TblColRef> 
unmatchedDimensions, Collection<FunctionDesc> unmatchedAggregations, SQLDigest 
digest, MeasureDesc measureDesc) {
         return null;
     }
-    
+
     /* 
============================================================================
      * Query Rewrite
      * 
---------------------------------------------------------------------------- */
@@ -104,7 +109,7 @@ abstract public class MeasureType<T> {
 
     /** Returns a Calcite aggregation function implementation class */
     abstract public Class<?> getRewriteCalciteAggrFunctionClass();
-    
+
     /* 
============================================================================
      * Storage
      * 
---------------------------------------------------------------------------- */

http://git-wip-us.apache.org/repos/asf/kylin/blob/f9de5a62/storage/src/main/java/org/apache/kylin/storage/hbase/CubeStorageEngine.java
----------------------------------------------------------------------
diff --git 
a/storage/src/main/java/org/apache/kylin/storage/hbase/CubeStorageEngine.java 
b/storage/src/main/java/org/apache/kylin/storage/hbase/CubeStorageEngine.java
index e612eb1..626b784 100644
--- 
a/storage/src/main/java/org/apache/kylin/storage/hbase/CubeStorageEngine.java
+++ 
b/storage/src/main/java/org/apache/kylin/storage/hbase/CubeStorageEngine.java
@@ -114,7 +114,7 @@ public class CubeStorageEngine implements IStorageEngine {
         Set<TblColRef> dimensionsD = Sets.newHashSet();
         dimensionsD.addAll(groupsD);
         dimensionsD.addAll(othersD);
-        Cuboid cuboid = identifyCuboid(dimensionsD);
+        Cuboid cuboid = identifyCuboid(dimensionsD, metrics);
         context.setCuboid(cuboid);
 
         // isExactAggregation? meaning: tuples returned from storage requires 
no further aggregation in query engine
@@ -163,7 +163,12 @@ public class CubeStorageEngine implements IStorageEngine {
         }
     }
 
-    private Cuboid identifyCuboid(Set<TblColRef> dimensions) {
+    private Cuboid identifyCuboid(Set<TblColRef> dimensions, 
Collection<FunctionDesc> metrics) {
+        for (FunctionDesc metric : metrics) {
+            if (metric.getMeasureType().onlyAggrInBaseCuboid())
+                return Cuboid.getBaseCuboid(cubeDesc);
+        }
+
         long cuboidID = 0;
         for (TblColRef column : dimensions) {
             int index = cubeDesc.getRowkey().getColumnBitIndex(column);
@@ -662,7 +667,6 @@ public class CubeStorageEngine implements IStorageEngine {
         ObserverEnabler.enableCoprocessorIfBeneficial(cubeInstance, 
groupsCopD, valueDecoders, context);
     }
 
-
     private void notifyBeforeStorageQuery(SQLDigest sqlDigest) {
         for (MeasureDesc measure : cubeDesc.getMeasures()) {
             MeasureType<?> measureType = 
measure.getFunction().getMeasureType();
@@ -670,5 +674,4 @@ public class CubeStorageEngine implements IStorageEngine {
         }
     }
 
-
 }

http://git-wip-us.apache.org/repos/asf/kylin/blob/f9de5a62/storage/src/test/java/org/apache/kylin/storage/hbase/CubeStorageEngineTest.java
----------------------------------------------------------------------
diff --git 
a/storage/src/test/java/org/apache/kylin/storage/hbase/CubeStorageEngineTest.java
 
b/storage/src/test/java/org/apache/kylin/storage/hbase/CubeStorageEngineTest.java
new file mode 100644
index 0000000..d41a836
--- /dev/null
+++ 
b/storage/src/test/java/org/apache/kylin/storage/hbase/CubeStorageEngineTest.java
@@ -0,0 +1,142 @@
+/*
+ * 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.
+ */
+
+package org.apache.kylin.storage.hbase;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotEquals;
+import static org.junit.Assert.assertTrue;
+
+import java.lang.reflect.Field;
+import java.lang.reflect.Method;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.List;
+import java.util.Set;
+
+import org.apache.kylin.common.util.LocalFileMetadataTestCase;
+import org.apache.kylin.cube.CubeInstance;
+import org.apache.kylin.cube.CubeManager;
+import org.apache.kylin.cube.cuboid.Cuboid;
+import org.apache.kylin.cube.model.CubeDesc;
+import org.apache.kylin.measure.MeasureAggregator;
+import org.apache.kylin.measure.MeasureIngester;
+import org.apache.kylin.measure.MeasureType;
+import org.apache.kylin.metadata.MetadataManager;
+import org.apache.kylin.metadata.model.FunctionDesc;
+import org.apache.kylin.metadata.model.MeasureDesc;
+import org.apache.kylin.metadata.model.TblColRef;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+
+import com.google.common.collect.Lists;
+import com.google.common.collect.Sets;
+
+/**
+ * Created by dongli on 12/28/15.
+ */
+public class CubeStorageEngineTest extends LocalFileMetadataTestCase {
+
+    private CubeInstance cube;
+
+    public CubeManager getCubeManager() {
+        return CubeManager.getInstance(getTestConfig());
+    }
+
+    private CubeInstance getTestKylinCubeWithSeller() {
+        return getCubeManager().getCube("test_kylin_cube_with_slr_empty");
+    }
+
+    @Before
+    public void setUp() throws Exception {
+        this.createTestMetadata();
+        MetadataManager.clearCache();
+
+        cube = getTestKylinCubeWithSeller();
+    }
+
+    @After
+    public void after() throws Exception {
+        this.cleanupTestMetadata();
+    }
+
+    @Test
+    public void testIdentifyCuboid() {
+        CubeDesc cubeDesc = cube.getDescriptor();
+        CubeStorageEngine engine = new CubeStorageEngine(cube);
+        long baseCuboidId = cubeDesc.getRowkey().getFullMask();
+
+        try {
+            Method method = 
engine.getClass().getDeclaredMethod("identifyCuboid", Set.class, 
Collection.class);
+            method.setAccessible(true);
+
+            Set<TblColRef> dimensions = Sets.newHashSet();
+            List<FunctionDesc> metrics = Lists.newArrayList();
+
+            Object ret = method.invoke(engine, dimensions, metrics);
+
+            assertTrue(ret instanceof Cuboid);
+            assertNotEquals(baseCuboidId, ((Cuboid) ret).getId());
+
+            for (MeasureDesc measureDesc : cubeDesc.getMeasures()) {
+                Collections.addAll(metrics, measureDesc.getFunction());
+            }
+
+            FunctionDesc mockUpFuncDesc = new FunctionDesc();
+            Field field = FunctionDesc.class.getDeclaredField("measureType");
+            field.setAccessible(true);
+            field.set(mockUpFuncDesc, new MockUpMeasureType());
+            metrics.add(mockUpFuncDesc);
+
+            ret = method.invoke(engine, dimensions, metrics);
+            assertEquals(baseCuboidId, ((Cuboid) ret).getId());
+
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+    }
+
+    class MockUpMeasureType extends MeasureType<String> {
+
+        @Override
+        public MeasureIngester<String> newIngester() {
+            return null;
+        }
+
+        @Override
+        public MeasureAggregator<String> newAggregator() {
+            return null;
+        }
+
+        @Override
+        public boolean needRewrite() {
+            return false;
+        }
+
+        @Override
+        public Class<?> getRewriteCalciteAggrFunctionClass() {
+            return null;
+        }
+
+        @Override
+        public boolean onlyAggrInBaseCuboid() {
+            return true;
+        }
+    }
+}

Reply via email to