You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@kylin.apache.org by ni...@apache.org on 2019/05/27 03:34:30 UTC

[kylin] branch dynamic-measure updated (648cbbc -> 9f21f0c)

This is an automated email from the ASF dual-hosted git repository.

nic pushed a change to branch dynamic-measure
in repository https://gitbox.apache.org/repos/asf/kylin.git.


    omit 648cbbc  KYLIN-3986 Add hint about the absent measures after a successful query. Generate the GridTable according to MeasureInstance metadata
    omit 5ebcee6  KYLIN-3983 Add extra metadata for measure. Add test case and example/test_case_data for MeasureManager. Add measure metadata in sample cube
     add 20fa8b1  Add unit tests (#639)
     add 6efcd79  KYLIN-3978 InternalErrorException: null with precise count distinct
     add bb44678  #KYLIN-3977 Aviod mistaken deleting dicts by storage cleanup while building jobs are running
     add ee95242  Small performance improvements
     add e09d9d7  KYLIN-4001 Allow user-specified time format using real-time for backend
     add 876d420  KYLIN-4001 Allow user-specified time format using real-time for ui
     add 79a2fc2  Add tests for LookupExecutableUtil and JobInfoConverter (#640)
     add b48de90  Add unit tests (#645)
     add 4e7b242  minor, switch to openjdk8 for travis
     add f15b1f8  KYLIN-3958 MrHive-Dict support build by livy
     add 47431ba  KYLIN-3958 Add quote for backtick
     new 29122d9  KYLIN-3983 Add extra metadata for measure. Add test case and example/test_case_data for MeasureManager. Add measure metadata in sample cube
     new 9f21f0c  KYLIN-3986 Add hint about the absent measures after a successful query. Generate the GridTable according to MeasureInstance metadata

This update added new revisions after undoing existing revisions.
That is to say, some revisions that were in the old version of the
branch are not in the new version.  This situation occurs
when a user --force pushes a change and generates a repository
containing something like this:

 * -- * -- B -- O -- O -- O   (648cbbc)
            \
             N -- N -- N   refs/heads/dynamic-measure (9f21f0c)

You should already have received notification emails for all of the O
revisions, and so the following emails describe only the N revisions
from the common base, B.

Any revisions marked "omit" are not gone; other references still
refer to them.  Any revisions marked "discard" are gone forever.

The 2 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.


Summary of changes:
 .travis.yml                                        |   2 +-
 .../cache/cachemanager/MemcachedCacheManager.java  |   4 +-
 .../apache/kylin/common/livy/LivyRestClient.java   |   9 +-
 .../common/persistence/FileResourceStore.java      |  31 +++-
 .../common/persistence/HDFSResourceStore.java      |  31 +++-
 .../kylin/common/persistence/JDBCResourceSQL.java  |   6 +-
 .../common/persistence/JDBCResourceStore.java      |  48 +++++-
 .../common/persistence/PushdownResourceStore.java  |  15 ++
 .../kylin/common/persistence/ResourceStore.java    | 106 ++++++++++---
 .../java/org/apache/kylin/common/util/Bytes.java   |   2 +-
 .../apache/kylin/common/util/ClasspathScanner.java |   6 +-
 .../apache/kylin/common/util/HiveCmdBuilder.java   |   4 +
 .../org/apache/kylin/common/util/MailService.java  |   2 +-
 .../src/main/resources/kylin-defaults.properties   |   6 +
 .../common/persistence/ResourceStoreTest.java      | 120 +++++++++++++--
 .../java/org/apache/kylin/cube/CubeManager.java    |  52 ++++---
 .../kylin/cube/cli/DictionaryGeneratorCLI.java     |  77 +++++++++-
 .../org/apache/kylin/dict/DictionaryManager.java   | 141 ++++++++++-------
 .../apache/kylin/dict/lookup/SnapshotManager.java  |  89 +++++++----
 .../apache/kylin/dict/DictionaryManagerTest.java   |  53 +++++--
 .../kylin/dict/lookup/SnapshotManagerTest.java     | 171 +++++++++++++++++++++
 .../apache/kylin/job/engine/JobEngineConfig.java   |   2 +-
 .../storage/gtrecord/GTCubeStorageQueryBase.java   |   5 +-
 .../apache/kylin/storage/StorageContextTest.java   |  64 ++++++++
 .../kylin/storage/hybrid/HybridInstanceTest.java   |  86 +++++++++++
 .../translate}/FuzzyValueCombinationTest.java      |   6 +-
 .../kylin/engine/mr/common/AbstractHadoopJob.java  |  12 +-
 .../engine/mr/common/HadoopJobStatusChecker.java   |   2 +-
 .../kylin/engine/mr/steps/CreateDictionaryJob.java |  10 +-
 .../mr/steps/lookup/LookupExecutableUtil.java      |   4 +-
 .../mr/common/DefaultX509TrustManagerTest.java     |  36 +++--
 .../engine/mr/common/HadoopCmdOutputTest.java}     |  43 +++---
 .../engine/mr/common/JobInfoConverterTest.java     | 159 ++++++++++++++++++-
 .../mr/steps/lookup/LookupExecutableUtilTest.java  |  63 ++++++++
 .../apache/kylin/cube/ITDictionaryManagerTest.java |  13 +-
 .../apache/kylin/rest/job/MetadataCleanupJob.java  | 136 +++++++++++-----
 .../kylin/rest/job/MetadataCleanupJobTest.java     |  16 +-
 .../source/hive/CreateFlatHiveTableByLivyStep.java |  50 +-----
 .../kylin/source/hive/CreateMrHiveDictStep.java    |  17 +-
 .../apache/kylin/source/hive/MRHiveDictUtil.java   |  61 +++++++-
 .../hive/RedistributeFlatHiveTableByLivyStep.java  |  17 +-
 .../kylin/storage/hbase/HBaseResourceStore.java    |  82 ++++++++--
 .../hbase/cube/v2/CubeHBaseEndpointRPC.java        |   1 +
 .../stream/core/source/MessageParserInfo.java      |  22 +++
 .../stream}/source/kafka/AbstractTimeParser.java   |   8 +-
 .../kylin/stream}/source/kafka/DateTimeParser.java |  25 ++-
 .../kylin/stream/source/kafka/LongTimeParser.java  |  24 ++-
 .../stream/source/kafka/TimedJsonStreamParser.java |  24 ++-
 webapp/app/js/controllers/sourceMeta.js            |   8 +-
 .../partials/tables/loadStreamingTableConfig.html  |  16 +-
 webapp/app/partials/tables/table_detail.html       |   8 +
 51 files changed, 1585 insertions(+), 410 deletions(-)
 create mode 100644 core-dictionary/src/test/java/org/apache/kylin/dict/lookup/SnapshotManagerTest.java
 create mode 100644 core-storage/src/test/java/org/apache/kylin/storage/StorageContextTest.java
 create mode 100644 core-storage/src/test/java/org/apache/kylin/storage/hybrid/HybridInstanceTest.java
 rename {storage-hbase/src/test/java/org/apache/kylin/storage/hbase/common => core-storage/src/test/java/org/apache/kylin/storage/translate}/FuzzyValueCombinationTest.java (97%)
 copy core-common/src/test/java/org/apache/kylin/common/util/DateFormatTest.java => engine-mr/src/test/java/org/apache/kylin/engine/mr/common/DefaultX509TrustManagerTest.java (50%)
 copy engine-mr/src/{main/java/org/apache/kylin/engine/mr/common/SerializableConfiguration.java => test/java/org/apache/kylin/engine/mr/common/HadoopCmdOutputTest.java} (52%)
 create mode 100644 engine-mr/src/test/java/org/apache/kylin/engine/mr/steps/lookup/LookupExecutableUtilTest.java
 copy {source-kafka/src/main/java/org/apache/kylin => stream-source-kafka/src/main/java/org/apache/kylin/stream}/source/kafka/AbstractTimeParser.java (83%)
 copy {source-kafka/src/main/java/org/apache/kylin => stream-source-kafka/src/main/java/org/apache/kylin/stream}/source/kafka/DateTimeParser.java (82%)
 copy source-kafka/src/main/java/org/apache/kylin/source/kafka/DefaultTimeParser.java => stream-source-kafka/src/main/java/org/apache/kylin/stream/source/kafka/LongTimeParser.java (67%)


[kylin] 01/02: KYLIN-3983 Add extra metadata for measure. Add test case and example/test_case_data for MeasureManager. Add measure metadata in sample cube

Posted by ni...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

nic pushed a commit to branch dynamic-measure
in repository https://gitbox.apache.org/repos/asf/kylin.git

commit 29122d9128c2c8d528f4a2a93b1fe611a055d8dd
Author: yuzhang <sh...@163.com>
AuthorDate: Sun Apr 28 23:46:03 2019 +0800

    KYLIN-3983 Add extra metadata for measure. Add test case and example/test_case_data for MeasureManager. Add measure metadata in sample cube
---
 .../org/apache/kylin/common/KylinConfigBase.java   |  28 +
 .../kylin/common/persistence/ResourceStore.java    |   1 +
 .../kylin/common/persistence/ResourceTool.java     |   4 +-
 .../org/apache/kylin/cube/CubeDescManager.java     |   4 +-
 .../java/org/apache/kylin/cube/CubeManager.java    |  17 +
 .../cube/adapter/AbstractHBaseMappingAdapter.java  | 211 +++++++
 .../kylin/cube/adapter/IHBaseMappingAdapter.java   |  40 ++
 .../kylin/cube/adapter/IWiseHBaseMapper.java       |  40 ++
 .../adapter/MemoryHungryHBaseMappingAdapter.java   | 114 ++++
 .../cube/adapter/OneCFHBaseMappingAdapter.java     |  75 +++
 .../java/org/apache/kylin/measure/CubeL2Cache.java | 194 ++++++
 .../org/apache/kylin/measure/MeasureInstance.java  | 246 ++++++++
 .../org/apache/kylin/measure/MeasureManager.java   | 701 +++++++++++++++++++++
 .../org/apache/kylin/cube/CubeManagerTest.java     |  68 +-
 .../apache/kylin/measure/MeasureManagerTest.java   | 205 ++++++
 .../apache/kylin/metadata/model/DateTimeRange.java |  46 ++
 .../measure/kylin_sales_cube/BUYER_LEVEL_SUM.json  |   9 +
 .../template/measure/kylin_sales_cube/GMV_SUM.json |   9 +
 .../measure/kylin_sales_cube/SELLER_CNT_HLL.json   |   9 +
 .../measure/kylin_sales_cube/SELLER_LEVEL_SUM.json |   9 +
 .../measure/kylin_sales_cube/TOP_SELLER.json       |   9 +
 .../measure/kylin_sales_cube/TRANS_CNT.json        |   9 +
 .../measure/kylin_streaming_cube/TOTAL_AMOUNT.json |   9 +
 .../measure/kylin_streaming_cube/TOTAL_QTY.json    |   9 +
 .../measure/kylin_streaming_cube/_COUNT_.json      |   9 +
 .../measure/ci_inner_join_cube/BUYER_CONTACT.json  |   9 +
 .../measure/ci_inner_join_cube/CAL_DT_RAW.json     |   9 +
 .../measure/ci_inner_join_cube/GMV_CNT.json        |   9 +
 .../measure/ci_inner_join_cube/GMV_MAX.json        |   9 +
 .../measure/ci_inner_join_cube/GMV_MIN.json        |   9 +
 .../measure/ci_inner_join_cube/GMV_SUM.json        |   9 +
 .../measure/ci_inner_join_cube/ITEM_COUNT_SUM.json |   9 +
 .../measure/ci_inner_join_cube/PRICE_RAW.json      |   9 +
 .../measure/ci_inner_join_cube/SELLER_CONTACT.json |   9 +
 .../ci_inner_join_cube/SELLER_FORMAT_HLL.json      |   9 +
 .../measure/ci_inner_join_cube/SELLER_HLL.json     |   9 +
 .../ci_inner_join_cube/TEST_COUNT_COLUMN_CNT.json  |   9 +
 .../TEST_COUNT_DISTINCT_BITMAP.json                |   9 +
 .../ci_inner_join_cube/TEST_EXTENDED_COLUMN.json   |   9 +
 .../measure/ci_inner_join_cube/TOP_SELLER.json     |   9 +
 .../measure/ci_inner_join_cube/TRANS_CNT.json      |   9 +
 .../measure/ci_inner_join_cube/TRANS_ID_RAW.json   |   9 +
 .../measure/ci_left_join_cube/BUYER_CONTACT.json   |   9 +
 .../measure/ci_left_join_cube/CAL_DT_RAW.json      |   9 +
 .../measure/ci_left_join_cube/GMV_CNT.json         |   9 +
 .../measure/ci_left_join_cube/GMV_MAX.json         |   9 +
 .../measure/ci_left_join_cube/GMV_MIN.json         |   9 +
 .../measure/ci_left_join_cube/GMV_SUM.json         |   9 +
 .../measure/ci_left_join_cube/GVM_PERCENTILE.json  |   9 +
 .../measure/ci_left_join_cube/ITEM_COUNT_SUM.json  |   9 +
 .../measure/ci_left_join_cube/PRICE_RAW.json       |   9 +
 .../measure/ci_left_join_cube/SELLER_CONTACT.json  |   9 +
 .../ci_left_join_cube/SELLER_FORMAT_HLL.json       |   9 +
 .../measure/ci_left_join_cube/SELLER_HLL.json      |   9 +
 .../ci_left_join_cube/TEST_COUNT_COLUMN_CNT.json   |   9 +
 .../TEST_COUNT_DISTINCT_BITMAP.json                |   9 +
 .../ci_left_join_cube/TEST_EXTENDED_COLUMN.json    |   9 +
 .../measure/ci_left_join_cube/TOP_SELLER.json      |   9 +
 .../measure/ci_left_join_cube/TRANS_CNT.json       |   9 +
 .../measure/ci_left_join_cube/TRANS_ID_RAW.json    |   9 +
 .../measure/fifty_dim_full_build_cube/_COUNT_.json |   9 +
 .../localmeta/measure/ssb/TOTAL_REVENUE.json       |   9 +
 .../localmeta/measure/ssb/TOTAL_SUPPLYCOST.json    |   9 +
 .../localmeta/measure/ssb/TOTAL_V_REVENUE.json     |   9 +
 .../localmeta/measure/ssb/_COUNT_.json             |   9 +
 .../localmeta/measure/ssb_cube1/TOTAL_REVENUE.json |   9 +
 .../measure/ssb_cube1/TOTAL_SUPPLYCOST.json        |   9 +
 .../measure/ssb_cube1/TOTAL_V_REVENUE.json         |   9 +
 .../localmeta/measure/ssb_cube1/_COUNT_.json       |   9 +
 .../localmeta/measure/ssb_cube2/TOTAL_REVENUE.json |   9 +
 .../measure/ssb_cube2/TOTAL_SUPPLYCOST.json        |   9 +
 .../measure/ssb_cube2/TOTAL_V_REVENUE.json         |   9 +
 .../localmeta/measure/ssb_cube2/_COUNT_.json       |   9 +
 .../localmeta/measure/ssb_cube3/TOTAL_REVENUE.json |   9 +
 .../measure/ssb_cube3/TOTAL_SUPPLYCOST.json        |   9 +
 .../localmeta/measure/ssb_cube3/_COUNT_.json       |   9 +
 .../TOTAL_REVENUE.json                             |   9 +
 .../TOTAL_SUPPLYCOST.json                          |   9 +
 .../ssb_cube_with_dimention_range/_COUNT_.json     |   9 +
 .../GMV_MAX.json                                   |   9 +
 .../GMV_MIN.json                                   |   9 +
 .../GMV_SUM.json                                   |   9 +
 .../ITEM_COUNT_SUM.json                            |   9 +
 .../TRANS_CNT.json                                 |   9 +
 .../test_kylin_cube_with_slr_empty/GMV_MAX.json    |   9 +
 .../test_kylin_cube_with_slr_empty/GMV_MIN.json    |   9 +
 .../test_kylin_cube_with_slr_empty/GMV_SUM.json    |   9 +
 .../ITEM_COUNT_SUM.json                            |   9 +
 .../test_kylin_cube_with_slr_empty/TRANS_CNT.json  |   9 +
 .../GMV_MAX.json                                   |   9 +
 .../GMV_MIN.json                                   |   9 +
 .../GMV_SUM.json                                   |   9 +
 .../ITEM_COUNT_SUM.json                            |   9 +
 .../SELLER_CNT_HLL.json                            |   9 +
 .../TOP_SELLER.json                                |   9 +
 .../TRANS_CNT.json                                 |   9 +
 .../GMV_MAX.json                                   |   9 +
 .../GMV_MIN.json                                   |   9 +
 .../GMV_SUM.json                                   |   9 +
 .../ITEM_COUNT_SUM.json                            |   9 +
 .../SELLER_CNT_HLL.json                            |   9 +
 .../TOP_SELLER.json                                |   9 +
 .../TRANS_CNT.json                                 |   9 +
 .../test_kylin_cube_with_slr_ready/GMV_MAX.json    |   9 +
 .../test_kylin_cube_with_slr_ready/GMV_MIN.json    |   9 +
 .../test_kylin_cube_with_slr_ready/GMV_SUM.json    |   9 +
 .../ITEM_COUNT_SUM.json                            |   9 +
 .../test_kylin_cube_with_slr_ready/TRANS_CNT.json  |   9 +
 .../GMV_MAX.json                                   |   9 +
 .../GMV_MIN.json                                   |   9 +
 .../GMV_SUM.json                                   |   9 +
 .../ITEM_COUNT_SUM.json                            |   9 +
 .../TRANS_CNT.json                                 |   9 +
 .../GMV_MAX.json                                   |   9 +
 .../GMV_MIN.json                                   |   9 +
 .../GMV_SUM.json                                   |   9 +
 .../ITEM_COUNT_SUM.json                            |   9 +
 .../TRANS_CNT.json                                 |   9 +
 .../CAL_DT_RAW.json                                |   9 +
 .../test_kylin_cube_without_slr_empty/GMV_MAX.json |   9 +
 .../test_kylin_cube_without_slr_empty/GMV_MIN.json |   9 +
 .../test_kylin_cube_without_slr_empty/GMV_SUM.json |   9 +
 .../ITEM_COUNT_SUM.json                            |   9 +
 .../LEAF_CATEG_ID_RAW.json                         |   9 +
 .../LSTG_FORMAT_NAME_RAW.json                      |   9 +
 .../PRICE_RAW.json                                 |   9 +
 .../SITE_EXTENDED_1.json                           |   9 +
 .../SITE_EXTENDED_2.json                           |   9 +
 .../TRANS_CNT.json                                 |   9 +
 .../CAL_DT_RAW.json                                |   9 +
 .../GMV_MAX.json                                   |   9 +
 .../GMV_MIN.json                                   |   9 +
 .../GMV_SUM.json                                   |   9 +
 .../ITEM_COUNT_SUM.json                            |   9 +
 .../LEAF_CATEG_ID_RAW.json                         |   9 +
 .../LSTG_FORMAT_NAME_RAW.json                      |   9 +
 .../PRICE_RAW.json                                 |   9 +
 .../SELLER_CNT_BITMAP.json                         |   9 +
 .../SELLER_FORMAT_CNT.json                         |   9 +
 .../TOP_SELLER.json                                |   9 +
 .../TRANS_CNT.json                                 |   9 +
 .../USER_COUNT_BITMAP.json                         |   9 +
 .../CAL_DT_RAW.json                                |   9 +
 .../GMV_MAX.json                                   |   9 +
 .../GMV_MIN.json                                   |   9 +
 .../GMV_SUM.json                                   |   9 +
 .../ITEM_COUNT_SUM.json                            |   9 +
 .../LEAF_CATEG_ID_RAW.json                         |   9 +
 .../LSTG_FORMAT_NAME_RAW.json                      |   9 +
 .../PRICE_RAW.json                                 |   9 +
 .../SELLER_CNT_BITMAP.json                         |   9 +
 .../SELLER_FORMAT_CNT.json                         |   9 +
 .../TOP_SELLER.json                                |   9 +
 .../TRANS_CNT.json                                 |   9 +
 .../USER_COUNT_BITMAP.json                         |   9 +
 .../CAL_DT_RAW.json                                |   9 +
 .../GMV_MAX.json                                   |   9 +
 .../GMV_MIN.json                                   |   9 +
 .../GMV_SUM.json                                   |   9 +
 .../ITEM_COUNT_SUM.json                            |   9 +
 .../LEAF_CATEG_ID_RAW.json                         |   9 +
 .../LSTG_FORMAT_NAME_RAW.json                      |   9 +
 .../PRICE_RAW.json                                 |   9 +
 .../SELLER_CNT_BITMAP.json                         |   9 +
 .../SELLER_FORMAT_CNT.json                         |   9 +
 .../TOP_SELLER.json                                |   9 +
 .../TRANS_CNT.json                                 |   9 +
 .../USER_COUNT_BITMAP.json                         |   9 +
 .../CAL_DT_RAW.json                                |   9 +
 .../test_kylin_cube_without_slr_ready/GMV_MAX.json |   9 +
 .../test_kylin_cube_without_slr_ready/GMV_MIN.json |   9 +
 .../test_kylin_cube_without_slr_ready/GMV_SUM.json |   9 +
 .../ITEM_COUNT_SUM.json                            |   9 +
 .../LEAF_CATEG_ID_RAW.json                         |   9 +
 .../LSTG_FORMAT_NAME_RAW.json                      |   9 +
 .../PRICE_RAW.json                                 |   9 +
 .../SITE_EXTENDED_1.json                           |   9 +
 .../SITE_EXTENDED_2.json                           |   9 +
 .../TRANS_CNT.json                                 |   9 +
 .../test_streaming_join_table_cube/GMV_SUM.json    |   9 +
 .../ITEM_COUNT_SUM.json                            |   9 +
 .../test_streaming_join_table_cube/_COUNT_.json    |   9 +
 .../measure/test_streaming_table_cube/GMV_SUM.json |   9 +
 .../test_streaming_table_cube/ITEM_COUNT_SUM.json  |   9 +
 .../measure/test_streaming_table_cube/_COUNT_.json |   9 +
 .../test_streaming_v2_cube/GMV_PERCENTILE.json     |   9 +
 .../measure/test_streaming_v2_cube/GMV_SUM.json    |   9 +
 .../test_streaming_v2_cube/ITEM_COUNT_SUM.json     |   9 +
 .../measure/test_streaming_v2_cube/_COUNT_.json    |   9 +
 .../COUNTDISTINCT_LID.json                         |   9 +
 .../COUNTDISTINCT_UID.json                         |   9 +
 .../MAX_EXPERIENCE.json                            |   9 +
 .../MIN_EXPERIENCE.json                            |   9 +
 .../PERCENTILE_REPUTATION.json                     |   9 +
 .../SUM_COINS.json                                 |   9 +
 .../test_streaming_v2_user_info_cube/_COUNT_.json  |   9 +
 examples/test_case_data/measure/MAX_SELLER_ID.json |  11 +
 .../measure/ut_jdbc_shard/BUYER_CONTACT.json       |   9 +
 .../measure/ut_jdbc_shard/CAL_DT_RAW.json          |   9 +
 .../ut_jdbc_shard/CORR_TRANS_ID_LSTG_SITE_ID.json  |   9 +
 .../jdbc_source/measure/ut_jdbc_shard/GMV_MAX.json |   9 +
 .../jdbc_source/measure/ut_jdbc_shard/GMV_MIN.json |   9 +
 .../jdbc_source/measure/ut_jdbc_shard/GMV_SUM.json |   9 +
 .../measure/ut_jdbc_shard/GVM_PERCENTILE.json      |   9 +
 .../measure/ut_jdbc_shard/ITEM_COUNT_SUM.json      |   9 +
 .../measure/ut_jdbc_shard/PRICE_RAW.json           |   9 +
 .../measure/ut_jdbc_shard/SELLER_CONTACT.json      |   9 +
 .../measure/ut_jdbc_shard/SELLER_FORMAT_HLL.json   |   9 +
 .../measure/ut_jdbc_shard/SELLER_HLL.json          |   9 +
 .../ut_jdbc_shard/TEST_COUNT_DISTINCT_BITMAP.json  |   9 +
 .../ut_jdbc_shard/TEST_EXTENDED_COLUMN.json        |   9 +
 .../measure/ut_jdbc_shard/TOP_SELLER.json          |   9 +
 .../measure/ut_jdbc_shard/TRANS_CNT.json           |   9 +
 .../measure/ut_jdbc_shard/TRANS_ID_RAW.json        |   9 +
 214 files changed, 3773 insertions(+), 5 deletions(-)

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 93dff1b..33ced89 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
@@ -484,6 +484,30 @@ public abstract class KylinConfigBase implements Serializable {
         return getOptional("kylin.metadata.hbase-client-retries-number", "1");
     }
 
+    public int getMaxMeasureNumberInOneColumn() {
+        return Integer.parseInt(getOptional("kylin.metadata.max-measure-number-in-one-column", "10"));
+    }
+
+    public int getMaxColumnFamilyNumber() {
+        return Integer.parseInt(getOptional("kylin.metadata.max-column-family-number", "10"));
+    }
+
+    public String getAutoHBaseColumnFamilyMapper() {
+        return getOptional("kylin.metadata.auto-hbase-column-family-mapper", "org.apache.kylin.cube.adapter.MemoryHungryHBaseMappingAdapter");
+    }
+
+    public String getHBaseColumnQualifierPrefix() {
+        return getOptional("kylin.metadata.hbase-column-qualifier-prefix", "M");
+    }
+
+    public String getHBaseColumnFamilyNamePrefix() {
+        return getOptional("kylin.metadata.hbase-column-family-name-prefix", "F");
+    }
+
+    public boolean isAutoHBaseMappingEnable() {
+        return Boolean.parseBoolean(getOptional("kylin.cube.is-auto-hbase-mapping-enable", "false"));
+    }
+
     // ============================================================================
     // DICTIONARY & SNAPSHOT
     // ============================================================================
@@ -653,6 +677,10 @@ public abstract class KylinConfigBase implements Serializable {
         return Boolean.parseBoolean(getOptional("kylin.cube.is-automerge-enabled", TRUE));
     }
 
+    public boolean isEditableMetricCube() {
+        return Boolean.parseBoolean(getOptional("kylin.cube.is-editable-metric-cube", "false"));
+    }
+
     // ============================================================================
     // Cube Planner
     // ============================================================================
diff --git a/core-common/src/main/java/org/apache/kylin/common/persistence/ResourceStore.java b/core-common/src/main/java/org/apache/kylin/common/persistence/ResourceStore.java
index 7db0eed..dd65e48 100644
--- a/core-common/src/main/java/org/apache/kylin/common/persistence/ResourceStore.java
+++ b/core-common/src/main/java/org/apache/kylin/common/persistence/ResourceStore.java
@@ -80,6 +80,7 @@ abstract public class ResourceStore {
     public static final String DRAFT_RESOURCE_ROOT = "/draft";
     public static final String USER_ROOT = "/user";
     public static final String EXT_SNAPSHOT_RESOURCE_ROOT = "/ext_table_snapshot";
+    public static final String MEASURE_RESOURCE_ROOT = "/measure";
 
     public static final String METASTORE_UUID_TAG = "/UUID";
 
diff --git a/core-common/src/main/java/org/apache/kylin/common/persistence/ResourceTool.java b/core-common/src/main/java/org/apache/kylin/common/persistence/ResourceTool.java
index 3ff0694..dad643c 100644
--- a/core-common/src/main/java/org/apache/kylin/common/persistence/ResourceTool.java
+++ b/core-common/src/main/java/org/apache/kylin/common/persistence/ResourceTool.java
@@ -28,6 +28,7 @@ import java.util.Locale;
 import java.util.NavigableSet;
 import java.util.Set;
 import java.util.TreeSet;
+import java.util.stream.Collectors;
 
 import org.apache.kylin.common.KylinConfig;
 import org.apache.kylin.common.persistence.ResourceParallelCopier.Stats;
@@ -192,7 +193,8 @@ public class ResourceTool {
     public NavigableSet<String> list(KylinConfig config, String path) throws IOException {
         ResourceStore store = ResourceStore.getStore(config);
         NavigableSet<String> result = store.listResources(path);
-        System.out.println("" + result);
+        System.out.println("" + result.stream().collect(Collectors.joining(System.lineSeparator())));
+        System.out.println();
         return result;
     }
 
diff --git a/core-cube/src/main/java/org/apache/kylin/cube/CubeDescManager.java b/core-cube/src/main/java/org/apache/kylin/cube/CubeDescManager.java
index a7459c0..ac1df3f 100644
--- a/core-cube/src/main/java/org/apache/kylin/cube/CubeDescManager.java
+++ b/core-cube/src/main/java/org/apache/kylin/cube/CubeDescManager.java
@@ -38,6 +38,7 @@ import org.apache.kylin.cube.model.validation.ValidateContext;
 import org.apache.kylin.dimension.DictionaryDimEnc;
 import org.apache.kylin.dimension.DimensionEncoding;
 import org.apache.kylin.dimension.DimensionEncodingFactory;
+import org.apache.kylin.measure.MeasureManager;
 import org.apache.kylin.measure.topn.TopNMeasureType;
 import org.apache.kylin.metadata.cachesync.Broadcaster;
 import org.apache.kylin.metadata.cachesync.Broadcaster.Event;
@@ -248,10 +249,9 @@ public class CubeDescManager {
             }
 
             desc.setSignature(desc.calculateSignature());
-
             // save resource
             crud.save(desc);
-
+            MeasureManager.getInstance(config).updateMeasuresOnCube(desc);
             return desc;
         }
     }
diff --git a/core-cube/src/main/java/org/apache/kylin/cube/CubeManager.java b/core-cube/src/main/java/org/apache/kylin/cube/CubeManager.java
index bd9832f..6a6f2b4 100755
--- a/core-cube/src/main/java/org/apache/kylin/cube/CubeManager.java
+++ b/core-cube/src/main/java/org/apache/kylin/cube/CubeManager.java
@@ -44,6 +44,7 @@ import org.apache.kylin.common.util.Dictionary;
 import org.apache.kylin.common.util.Pair;
 import org.apache.kylin.common.util.RandomUtil;
 import org.apache.kylin.cube.cuboid.Cuboid;
+import org.apache.kylin.measure.MeasureManager;
 import org.apache.kylin.cube.model.CubeDesc;
 import org.apache.kylin.cube.model.SnapshotTableDesc;
 import org.apache.kylin.dict.DictionaryInfo;
@@ -347,6 +348,10 @@ public class CubeManager implements IRealizationProvider {
         if (update == null || update.getCubeInstance() == null)
             throw new IllegalStateException();
 
+        boolean isNewCube = getCube(update.getCubeInstance().getName()) == null;
+        // init the MeasureInstance Cache first
+        getMeasureManager();
+
         CubeInstance cube = update.getCubeInstance();
         logger.info("Updating cube instance '{}'", cube.getName());
 
@@ -395,6 +400,11 @@ public class CubeManager implements IRealizationProvider {
         //this is a duplicate call to take care of scenarios where REST cache service unavailable
         ProjectManager.getInstance(cube.getConfig()).clearL2Cache(cube.getProject());
 
+        logger.info("Update MeasureInstance of cube instance: " + cube.getName());
+        if (isNewCube) {
+            getMeasureManager().createMeasuresOnCube(cube);
+        }
+        getMeasureManager().updateSegmentsOnCube(cube, update);
         return cube;
     }
 
@@ -498,6 +508,9 @@ public class CubeManager implements IRealizationProvider {
             // delete cube instance and cube desc
             CubeInstance cube = getCube(cubeName);
 
+            logger.info("Drop measure on cube first");
+            getMeasureManager().deleteByCube(cube.getProject(), cube.getName());
+
             // remove cube and update cache
             crud.delete(cube);
             Cuboid.clearCache(cube);
@@ -1231,4 +1244,8 @@ public class CubeManager implements IRealizationProvider {
         }
         return cube;
     }
+
+    public MeasureManager getMeasureManager() {
+        return MeasureManager.getInstance(this.config);
+    }
 }
diff --git a/core-cube/src/main/java/org/apache/kylin/cube/adapter/AbstractHBaseMappingAdapter.java b/core-cube/src/main/java/org/apache/kylin/cube/adapter/AbstractHBaseMappingAdapter.java
new file mode 100644
index 0000000..2b468ef
--- /dev/null
+++ b/core-cube/src/main/java/org/apache/kylin/cube/adapter/AbstractHBaseMappingAdapter.java
@@ -0,0 +1,211 @@
+/*
+ * 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.cube.adapter;
+
+import com.google.common.collect.Lists;
+import org.apache.commons.lang3.math.NumberUtils;
+import org.apache.kylin.common.KylinConfig;
+import org.apache.kylin.common.util.ClassUtil;
+import org.apache.kylin.common.util.Pair;
+import org.apache.kylin.cube.CubeDescManager;
+import org.apache.kylin.cube.model.CubeDesc;
+import org.apache.kylin.cube.model.HBaseColumnDesc;
+import org.apache.kylin.cube.model.HBaseColumnFamilyDesc;
+import org.apache.kylin.cube.model.HBaseMappingDesc;
+import org.apache.kylin.measure.MeasureType;
+import org.apache.kylin.metadata.model.FunctionDesc;
+import org.apache.kylin.metadata.model.MeasureDesc;
+
+import java.lang.reflect.Constructor;
+import java.lang.reflect.InvocationTargetException;
+import java.util.Comparator;
+import java.util.List;
+import java.util.Locale;
+import java.util.stream.Collectors;
+
+public abstract class AbstractHBaseMappingAdapter implements IHBaseMappingAdapter, IWiseHBaseMapper {
+
+
+    public static final AbstractHBaseMappingAdapter getHBaseAdapter(KylinConfig config) {
+        try {
+            Class<? extends AbstractHBaseMappingAdapter> adapterClass =
+                    ClassUtil.forName(config.getAutoHBaseColumnFamilyMapper(), AbstractHBaseMappingAdapter.class);
+            Constructor<? extends AbstractHBaseMappingAdapter> constructor = adapterClass.getConstructor(KylinConfig.class);
+            return constructor.newInstance(config);
+        } catch (ClassNotFoundException
+                | NoSuchMethodException
+                | IllegalAccessException
+                |InstantiationException
+                | InvocationTargetException e) {
+            throw new IllegalArgumentException("Can't reflect HbaseMapper: " + config.getAutoHBaseColumnFamilyMapper());
+        }
+    }
+
+    protected KylinConfig config;
+    final protected String hBaseColumnFamilyNamePrefix;
+    final protected String hBaseColumnQualifierPrefix;
+
+    protected AbstractHBaseMappingAdapter(KylinConfig config) {
+        this.config = config;
+        hBaseColumnFamilyNamePrefix = this.config.getHBaseColumnFamilyNamePrefix();
+        hBaseColumnQualifierPrefix = this.config.getHBaseColumnQualifierPrefix();
+    }
+
+    protected AbstractHBaseMappingAdapter() {
+        this(KylinConfig.getInstanceFromEnv());
+    }
+
+    @Override
+    public void initHBaseMapping(CubeDesc cubeDesc) {
+        List<MeasureDesc> measures = cubeDesc.getMeasures();
+        if (null == measures) {
+            throw new IllegalArgumentException("cubeDesc.getMeasures got null.");
+        }
+        boolean needResetHBaseMapping = config.isAutoHBaseMappingEnable() && null == cubeDesc.getHbaseMapping();
+        if (needResetHBaseMapping) {
+            HBaseMappingDesc hbaseMapping = getHBaseMappingOnlyOnce(cubeDesc);
+            cubeDesc.setHbaseMapping(hbaseMapping);
+        }
+        cubeDesc.getHbaseMapping().init(cubeDesc);
+    }
+
+    @Override
+    public void initMeasureReferenceToColumnFamilyWithChecking(CubeDesc cubeDesc) {
+        cubeDesc.initMeasureReferenceToColumnFamily();
+    }
+
+    protected HBaseColumnFamilyDesc getSingleColumnCFContain(MeasureDesc measure, String cfName) {
+        HBaseColumnFamilyDesc ret = new HBaseColumnFamilyDesc();
+        HBaseColumnDesc[] hbaseColumnDescs = {getColumnContainSingleMeasure(measure, hBaseColumnQualifierPrefix)};
+        ret.setColumns(hbaseColumnDescs);
+        ret.setName(cfName);
+        return ret;
+    }
+
+    protected HBaseColumnDesc getHBaseColumnDescWithName(String qualifier) {
+        HBaseColumnDesc normColumn = new HBaseColumnDesc();
+        normColumn.setQualifier(qualifier);
+        return normColumn;
+    }
+
+    protected  MeasureDesc getMeasureByName(CubeDesc desc, String measureName) {
+        for (MeasureDesc m : desc.getMeasures()) {
+            if (m.getName().equals(measureName)) {
+                return m;
+            }
+        }
+        throw new IllegalStateException(String.format(Locale.ROOT, "Can't find measure %s in cube %s", measureName, desc.getName()));
+    }
+
+
+    protected MeasureType<?> getMeasureType(MeasureDesc measure) {
+        FunctionDesc func = measure.getFunction();
+        func.setReturnType(func.getReturnType());
+        MeasureType<?> measureType = func.getMeasureType();
+        if (null == measureType) {
+            throw new IllegalArgumentException(String.format(Locale.ROOT, "measure type of %s can't be null!", measure.getName()));
+        }
+        return measureType;
+    }
+
+    // only copy reference
+    protected HBaseMappingDesc copy(HBaseMappingDesc needCopy) {
+        List<HBaseColumnFamilyDesc> copyCFs = Lists.newArrayListWithCapacity(needCopy.getColumnFamily().length);
+        for (HBaseColumnFamilyDesc cf : needCopy.getColumnFamily()) {
+            List<HBaseColumnDesc> copyColumns = Lists.newArrayListWithCapacity(cf.getColumns().length);
+            for (HBaseColumnDesc c : cf.getColumns()) {
+                List<String> copyMeasureRefs = Lists.newArrayListWithCapacity(c.getMeasureRefs().length);
+                for (String mf : c.getMeasureRefs()) {
+                    copyMeasureRefs.add(mf);
+                }
+                HBaseColumnDesc copyC = getHBaseColumnDescWithName(c.getQualifier());
+                copyC.setMeasureRefs(copyMeasureRefs.toArray(new String[0]));
+                copyColumns.add(copyC);
+            }
+            HBaseColumnFamilyDesc copyCF = new HBaseColumnFamilyDesc();
+            copyCF.setName(cf.getName());
+            copyCF.setColumns(copyColumns.toArray(new HBaseColumnDesc[0]));
+            copyCFs.add(copyCF);
+        }
+        HBaseMappingDesc copyMapping = new HBaseMappingDesc();
+        copyMapping.setColumnFamily(copyCFs.toArray(new HBaseColumnFamilyDesc[0]));
+        return copyMapping;
+    }
+
+    /**
+     *
+     * @param cubeName
+     * @return  [index, measure cnt], sorted by measure cnt asc
+     */
+    protected List<Pair<Integer, Integer>> getNormCFIndexInOldMapping(String cubeName){
+        List<Pair<Integer, Integer>> normCFIndexes = Lists.newArrayListWithExpectedSize(5);
+        HBaseColumnFamilyDesc[] cfs = getCubeDescManager().getCubeDesc(cubeName).getHbaseMapping().getColumnFamily();
+        for (int i = 0; i < cfs.length; i++) {
+            if (!cfs[i].isMemoryHungry()) {
+                normCFIndexes.add(new Pair<>(i, getMeasureNumberInCF(cfs[i])));
+            }
+        }
+        normCFIndexes.sort(Comparator.comparingInt(Pair::getSecond));
+        return normCFIndexes;
+    }
+
+    protected int getMeasureNumberInCF(HBaseColumnFamilyDesc cf) {
+        int ret = 0;
+        for (HBaseColumnDesc c : cf.getColumns()) {
+            ret += c.getMeasureRefs().length;
+        }
+        return ret;
+    }
+
+    protected HBaseColumnDesc getColumnContainSingleMeasure(MeasureDesc measure, String qualifier) {
+        return getColumnContainSingleMeasure(measure.getName(), qualifier);
+    }
+
+    protected HBaseColumnDesc getColumnContainSingleMeasure(String measureName, String qualifier) {
+        HBaseColumnDesc hbaseColumn = getHBaseColumnDescWithName(qualifier);
+        hbaseColumn.setMeasureRefs(new String[]{measureName});
+        return hbaseColumn;
+    }
+
+    protected CubeDescManager getCubeDescManager() {
+        return CubeDescManager.getInstance(config);
+    }
+
+    protected int findMaxSuffixOfCF(List<HBaseColumnFamilyDesc> cfs) {
+        if (cfs == null || cfs.size() == 0) {
+            return 0;
+        }
+        List<Integer> cfSuffixes = cfs.stream()
+                .map(cf -> NumberUtils.toInt(cf.getName().replace(hBaseColumnFamilyNamePrefix, "")))
+                .sorted()
+                .collect(Collectors.toList());
+        return cfSuffixes.get(cfSuffixes.size() - 1);
+    }
+
+    protected int findMaxSuffixOfColumn(List<HBaseColumnDesc> cs) {
+        if (cs == null || cs.size() == 0) {
+            return 0;
+        }
+        List<Integer> cSuffixes = cs.stream()
+                .map(cf -> NumberUtils.toInt(cf.getQualifier().replace(hBaseColumnQualifierPrefix, "")))
+                .sorted()
+                .collect(Collectors.toList());
+        return cSuffixes.get(cSuffixes.size() - 1);
+    }
+}
diff --git a/core-cube/src/main/java/org/apache/kylin/cube/adapter/IHBaseMappingAdapter.java b/core-cube/src/main/java/org/apache/kylin/cube/adapter/IHBaseMappingAdapter.java
new file mode 100644
index 0000000..024be21
--- /dev/null
+++ b/core-cube/src/main/java/org/apache/kylin/cube/adapter/IHBaseMappingAdapter.java
@@ -0,0 +1,40 @@
+/*
+ * 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.cube.adapter;
+
+import org.apache.kylin.cube.model.CubeDesc;
+
+/**
+ * Initialize hbaseMappingDesc in CubeDesc to adapt hbase storage
+ * @author simple
+ */
+public interface IHBaseMappingAdapter {
+
+    /**
+     * Normalize the column family, column and used measure
+     * @param cubeDesc
+     */
+    public void initHBaseMapping(CubeDesc cubeDesc);
+
+    /**
+     * Build measure reference in HBaseColumnDesc and make sure that every measure has been assigned
+     * @param cubeDesc
+     */
+    public void initMeasureReferenceToColumnFamilyWithChecking(CubeDesc cubeDesc);
+}
diff --git a/core-cube/src/main/java/org/apache/kylin/cube/adapter/IWiseHBaseMapper.java b/core-cube/src/main/java/org/apache/kylin/cube/adapter/IWiseHBaseMapper.java
new file mode 100644
index 0000000..e71d0c0
--- /dev/null
+++ b/core-cube/src/main/java/org/apache/kylin/cube/adapter/IWiseHBaseMapper.java
@@ -0,0 +1,40 @@
+/*
+ * 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.cube.adapter;
+
+import org.apache.kylin.cube.model.CubeDesc;
+import org.apache.kylin.cube.model.HBaseMappingDesc;
+
+import java.util.List;
+
+public interface IWiseHBaseMapper {
+    /**
+     * Only called at the first time meet the cube, which must doesn't have hbase mapping;
+     * @param cubeDesc the first meet cube
+     */
+    HBaseMappingDesc getHBaseMappingOnlyOnce(CubeDesc cubeDesc);
+
+    /**
+     * add new measure to old hbase mapping
+     * @param newDesc
+     * @param needAddMeasure
+     * @return
+     */
+    HBaseMappingDesc addMeasure(CubeDesc newDesc, List<String> needAddMeasure);
+}
diff --git a/core-cube/src/main/java/org/apache/kylin/cube/adapter/MemoryHungryHBaseMappingAdapter.java b/core-cube/src/main/java/org/apache/kylin/cube/adapter/MemoryHungryHBaseMappingAdapter.java
new file mode 100644
index 0000000..93b7f96
--- /dev/null
+++ b/core-cube/src/main/java/org/apache/kylin/cube/adapter/MemoryHungryHBaseMappingAdapter.java
@@ -0,0 +1,114 @@
+/*
+ * 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.cube.adapter;
+
+import com.google.common.collect.Lists;
+import org.apache.kylin.common.KylinConfig;
+import org.apache.kylin.common.util.Pair;
+import org.apache.kylin.cube.model.CubeDesc;
+import org.apache.kylin.cube.model.HBaseColumnDesc;
+import org.apache.kylin.cube.model.HBaseColumnFamilyDesc;
+import org.apache.kylin.cube.model.HBaseMappingDesc;
+import org.apache.kylin.measure.MeasureType;
+import org.apache.kylin.metadata.model.MeasureDesc;
+
+import java.util.Comparator;
+import java.util.List;
+
+public class MemoryHungryHBaseMappingAdapter extends AbstractHBaseMappingAdapter {
+
+    public MemoryHungryHBaseMappingAdapter(KylinConfig config) {
+        super(config);
+    }
+
+    @Override
+    public HBaseMappingDesc getHBaseMappingOnlyOnce(CubeDesc cubeDesc) {
+        List<HBaseColumnFamilyDesc> hbaseCFDescs = Lists.newArrayListWithCapacity(4);
+
+        List<String> normMeasures = Lists.newArrayListWithCapacity(cubeDesc.getMeasures().size());
+        for (MeasureDesc measure : cubeDesc.getMeasures()) {
+            MeasureType<?> measureType = getMeasureType(measure);
+            if (measureType.isMemoryHungry()) {
+                HBaseColumnFamilyDesc memoryHungryCF = getSingleColumnCFContain(measure,
+                        hBaseColumnFamilyNamePrefix + (hbaseCFDescs.size() + 1));
+                hbaseCFDescs.add(memoryHungryCF);
+            } else {
+                normMeasures.add(measure.getName());
+            }
+        }
+
+        if (normMeasures.size() > 0) {
+            // use to mapping no memory hungry measures
+            HBaseColumnFamilyDesc normalCF = new HBaseColumnFamilyDesc();
+            normalCF.setName(hBaseColumnFamilyNamePrefix + (hbaseCFDescs.size() + 1));
+            HBaseColumnDesc normColumn = getHBaseColumnDescWithName(hBaseColumnQualifierPrefix);
+            normColumn.setMeasureRefs(normMeasures.toArray(new String[normMeasures.size()]));
+            normalCF.setColumns(new HBaseColumnDesc[]{normColumn});
+            hbaseCFDescs.add(normalCF);
+        }
+
+        HBaseMappingDesc hbaseMapping = new HBaseMappingDesc();
+        hbaseMapping.setColumnFamily(hbaseCFDescs.toArray(new HBaseColumnFamilyDesc[hbaseCFDescs.size()]));
+        return hbaseMapping;
+
+    }
+
+    @Override
+    public HBaseMappingDesc addMeasure(CubeDesc newDesc, List<String> needAddMeasure) {
+        if (needAddMeasure == null) {
+            return getHBaseMappingOnlyOnce(newDesc);
+        }
+        HBaseMappingDesc oldMappingCopy = copy(getCubeDescManager().getCubeDesc(newDesc.getName()).getHbaseMapping());
+        if (needAddMeasure.size() == 0) {
+            return oldMappingCopy;
+        }
+        List<HBaseColumnFamilyDesc> cfs = Lists.newArrayList(oldMappingCopy.getColumnFamily());
+        // first element always contain the min number of norm measure
+        List<Pair<Integer, Integer>> normCFIndex = getNormCFIndexInOldMapping(newDesc.getName());
+        for (String measureName : needAddMeasure) {
+            MeasureDesc measureDesc = getMeasureByName(newDesc, measureName);
+            if (getMeasureType(measureDesc).isMemoryHungry()) {
+                // add new CF
+                HBaseColumnFamilyDesc memoryCF = getSingleColumnCFContain(measureDesc, hBaseColumnFamilyNamePrefix + (findMaxSuffixOfCF(cfs) + 1));
+                cfs.add(memoryCF);
+            } else {
+                // find norm CF then add new column to contain this measure,
+                // if don't have an norm CF or achieve max measure count, create one
+                boolean needAddCF = normCFIndex.size() == 0
+                        || (normCFIndex.get(0).getSecond() >= config.getMaxMeasureNumberInOneColumn() && cfs.size() <= config.getMaxColumnFamilyNumber());
+                if (needAddCF) {
+                    HBaseColumnFamilyDesc normCF = getSingleColumnCFContain(measureDesc, hBaseColumnFamilyNamePrefix + (findMaxSuffixOfCF(cfs) + 1));
+                    cfs.add(normCF);
+                    normCFIndex.add(new Pair<>(cfs.size() - 1, 1));
+                } else {
+                    Pair<Integer, Integer> idxCntPair = normCFIndex.get(0);
+                    Integer idx = idxCntPair.getFirst();
+                    List<HBaseColumnDesc> normColumn = Lists.newArrayList(cfs.get(idx).getColumns());
+                    HBaseColumnDesc newColumn = getColumnContainSingleMeasure(measureDesc, hBaseColumnQualifierPrefix + (findMaxSuffixOfColumn(normColumn) + 1));
+                    normColumn.add(newColumn);
+                    cfs.get(idx).setColumns(normColumn.toArray(new HBaseColumnDesc[0]));
+                    idxCntPair.setSecond(idxCntPair.getSecond() + 1);
+                }
+                normCFIndex.sort(Comparator.comparingInt(Pair::getSecond));
+            }
+        }
+        oldMappingCopy.setColumnFamily(cfs.toArray(new HBaseColumnFamilyDesc[0]));
+        return oldMappingCopy;
+    }
+}
diff --git a/core-cube/src/main/java/org/apache/kylin/cube/adapter/OneCFHBaseMappingAdapter.java b/core-cube/src/main/java/org/apache/kylin/cube/adapter/OneCFHBaseMappingAdapter.java
new file mode 100644
index 0000000..0260736
--- /dev/null
+++ b/core-cube/src/main/java/org/apache/kylin/cube/adapter/OneCFHBaseMappingAdapter.java
@@ -0,0 +1,75 @@
+/*
+ * 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.cube.adapter;
+
+import com.google.common.collect.Lists;
+import org.apache.kylin.common.KylinConfig;
+import org.apache.kylin.cube.model.CubeDesc;
+import org.apache.kylin.cube.model.HBaseColumnDesc;
+import org.apache.kylin.cube.model.HBaseColumnFamilyDesc;
+import org.apache.kylin.cube.model.HBaseMappingDesc;
+import org.apache.kylin.metadata.model.MeasureDesc;
+
+import java.util.List;
+
+/**
+ * All metrics are assigned in one column family. Each metric is assigned into one qualifier
+ */
+public class OneCFHBaseMappingAdapter extends AbstractHBaseMappingAdapter {
+
+    public OneCFHBaseMappingAdapter(KylinConfig config) {
+        super(config);
+    }
+
+    @Override
+    public HBaseMappingDesc getHBaseMappingOnlyOnce(CubeDesc cubeDesc) {
+        // use to mapping no memory hungry measures
+        HBaseColumnFamilyDesc finalColumnFamily = new HBaseColumnFamilyDesc();
+        finalColumnFamily.setName(hBaseColumnFamilyNamePrefix + 1);
+
+        List<HBaseColumnDesc> columnList = Lists.newArrayListWithExpectedSize(cubeDesc.getMeasures().size());
+        List<MeasureDesc> measureDescs = Lists.newArrayList(cubeDesc.getMeasures());
+//        measureDescs.sort(Comparator.comparingLong(MeasureDesc::getCreatedTime));
+        for (MeasureDesc measure : measureDescs) {
+            HBaseColumnDesc column = getHBaseColumnDescWithName(hBaseColumnQualifierPrefix + (columnList.size() + 1));
+            column.setMeasureRefs(new String[]{measure.getName()});
+            columnList.add(column);
+        }
+
+        finalColumnFamily.setColumns(columnList.toArray(new HBaseColumnDesc[columnList.size()]));
+
+        HBaseMappingDesc hbaseMapping = new HBaseMappingDesc();
+        hbaseMapping.setColumnFamily(new HBaseColumnFamilyDesc[]{finalColumnFamily});
+        return hbaseMapping;
+    }
+
+    @Override
+    public HBaseMappingDesc addMeasure(CubeDesc newDesc, List<String> needAddMeasure) {
+        // just add column on by one
+        HBaseMappingDesc oldMappingCopy = copy(getCubeDescManager().getCubeDesc(newDesc.getName()).getHbaseMapping());
+        HBaseColumnFamilyDesc columnFamilyDesc = oldMappingCopy.getColumnFamily()[0];
+        List<HBaseColumnDesc> hBaseColumnDescs = Lists.newArrayList(columnFamilyDesc.getColumns());
+        for (String measureName : needAddMeasure) {
+            hBaseColumnDescs.add(getColumnContainSingleMeasure(measureName, hBaseColumnQualifierPrefix + (findMaxSuffixOfColumn(hBaseColumnDescs) + 1)));
+        }
+        columnFamilyDesc.setColumns(hBaseColumnDescs.toArray(new HBaseColumnDesc[0]));
+
+        return oldMappingCopy;
+    }
+}
diff --git a/core-cube/src/main/java/org/apache/kylin/measure/CubeL2Cache.java b/core-cube/src/main/java/org/apache/kylin/measure/CubeL2Cache.java
new file mode 100644
index 0000000..dd5a8b3
--- /dev/null
+++ b/core-cube/src/main/java/org/apache/kylin/measure/CubeL2Cache.java
@@ -0,0 +1,194 @@
+/*
+ * 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.measure;
+
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.Lists;
+import com.google.common.collect.Maps;
+import org.apache.kylin.cube.CubeInstance;
+import org.apache.kylin.cube.CubeManager;
+import org.apache.kylin.metadata.model.ISegment;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.Collections;
+import java.util.List;
+import java.util.Locale;
+import java.util.Map;
+import java.util.Set;
+import java.util.concurrent.ConcurrentSkipListMap;
+import java.util.stream.Collectors;
+
+public class CubeL2Cache {
+
+    private static final Logger LOG = LoggerFactory.getLogger(CubeL2Cache.class);
+
+    private CubeManager cubeMgr;
+    private Map<String, CubeCache> cubeCaches = new ConcurrentSkipListMap<>(String.CASE_INSENSITIVE_ORDER);
+
+
+    public CubeL2Cache(CubeManager cubeMgr) {
+        this.cubeMgr = cubeMgr;
+    }
+
+    // cat
+    public List<MeasureInstance> getMeasuresOnCubeAllowMiss(String cubeName) {
+        return getMeasuresOnCube(cubeName, true);
+    }
+
+    public List<MeasureInstance> getMeasuresOnCube(String cubeName) {
+        return getMeasuresOnCube(cubeName, false);
+    }
+
+    private List<MeasureInstance> getMeasuresOnCube(String cubeName, boolean allowMiss) {
+        CubeCache cache = getCubeCache(cubeName, allowMiss);
+        if (cache == null) {
+            return Collections.EMPTY_LIST;
+        }
+        return ImmutableList.copyOf(cache.measures);
+    }
+
+    public List<MeasureInstance> getMeasuresOf(String cubeName, String segmentName) {
+        CubeCache cache = getCubeCache(cubeName);
+        if (cache == null) {
+            return Collections.EMPTY_LIST;
+        }
+        List<MeasureInstance> ret = cache.segmentMeasureMap.get(segmentName);
+        if (null == ret) {
+            return Collections.EMPTY_LIST;
+        }
+        return ImmutableList.copyOf(ret);
+    }
+
+    private CubeCache getCubeCache(String cubeName) {
+        return getCubeCache(cubeName, false);
+    }
+
+    private CubeCache getCubeCache(String cubeName, boolean allowMiss) {
+        CubeCache cache = cubeCaches.get(cubeName);
+        if (null == cache) {
+            cache =  allowMiss ? reloadCacheAllowMiss(cubeName) : reloadCache(cubeName);
+        }
+        return cache;
+    }
+
+    // delete
+    public CubeCache remove(String cubeName) {
+        return cubeCaches.remove(cubeName);
+    }
+
+    // add
+    public CubeCache reloadCache(String cube) {
+        LOG.debug("Reloading L2 cube cache for " + cube);
+        CubeCache cubeCache = new CubeCache(cube);
+
+        CubeInstance cubeInstance = cubeMgr.getCube(cube);
+        if (cubeInstance == null) {
+            return null;
+        }
+        loadMeasureOnCube(cubeCache, cubeInstance);
+        cubeCaches.put(cube, cubeCache);
+        return cubeCache;
+    }
+
+    public CubeCache reloadCacheAllowMiss(String cube) {
+        LOG.debug("Reloading L2 cube cache(allow miss) for " + cube);
+        CubeCache cubeCache = new CubeCache(cube);
+
+        CubeInstance cubeInstance = cubeMgr.getCube(cube);
+        loadMeasureOnCube(cubeCache, cubeInstance, true);
+        cubeCaches.put(cube, cubeCache);
+        return cubeCache;
+    }
+
+    private void loadMeasureOnCube(CubeCache cubeCache, CubeInstance cubeInstance) {
+        loadMeasureOnCube(cubeCache, cubeInstance, false);
+    }
+
+    private void loadMeasureOnCube(CubeCache cubeCache, CubeInstance cubeInstance, boolean allowMiss) {
+
+        List<String> measureNameFromCube = cubeInstance.getMeasures().stream().map(m -> m.getName()).collect(Collectors.toList());
+        List<String> measureKeyFromL1Cache = getMeasureKeyFromCache(cubeInstance.getName());
+        for (String mk : measureKeyFromL1Cache) {
+            MeasureInstance measure = cubeMgr.getMeasureManager().getMeasureByKey(mk);
+            if (null != measure) {
+                cubeCache.measures.add(measure);
+                // update segment map
+                for (ISegment seg : measure.getSegments()) {
+                    if (cubeCache.segmentMeasureMap.get(seg.getName()) == null) {
+                        List<MeasureInstance> measuresOverSeg = Lists.newArrayList();
+                        measuresOverSeg.add(measure);
+                        cubeCache.segmentMeasureMap.put(seg.getName(), measuresOverSeg);
+                    } else {
+                        cubeCache.segmentMeasureMap.get(seg.getName()).add(measure);
+                    }
+                }
+            } else {
+                String msg = String.format(Locale.ROOT, "Measure %s is not found in L1 cache now.", mk);
+                LOG.warn(msg);
+            }
+        }
+        if (cubeCache.measures.size() != measureNameFromCube.size()) {
+            List<String> measureNameFromL2Cache = cubeCache.measures.stream().map(m -> m.getName()).collect(Collectors.toList());
+            String msg = String.format(Locale.ROOT, "measures in cube %s are different with measures in L2 cahe %s", measureNameFromCube, measureNameFromL2Cache);
+            if (allowMiss) {
+                LOG.warn(msg);
+            } else {
+                throw new MissMeasureCacheException(msg);
+            }
+        }
+    }
+
+    private List<String> getMeasureKeyFromCache(String name) {
+        Set<String> cacheKey = cubeMgr.getMeasureManager().getCache().keySet();
+        String pre = name + "/";
+        return cacheKey.stream().filter(s -> s.startsWith(pre)).collect(Collectors.toList());
+    }
+
+    private List<String> getMeasureKeyFromCubeCache(CubeInstance cubeInstance) {
+        return cubeInstance.getMeasures().stream()
+                .map(m -> MeasureInstance.getResourceName(cubeInstance.getName(), m.getName()))
+                .collect(Collectors.toList());
+    }
+
+
+    public static class MissMeasureCacheException extends RuntimeException {
+        public MissMeasureCacheException(Exception e) {
+            super(e);
+        }
+
+        public MissMeasureCacheException(String msg) {
+            super(msg);
+        }
+    }
+
+    private static class CubeCache {
+        private String cubeName;
+        private List<MeasureInstance> measures;
+        // segment name => MeasureInstance s
+        private Map<String, List<MeasureInstance>> segmentMeasureMap;
+
+        CubeCache(String cubeName) {
+            this.cubeName = cubeName;
+            this.measures = Lists.newArrayList();
+            this.segmentMeasureMap = Maps.newHashMap();
+        }
+    }
+
+}
diff --git a/core-cube/src/main/java/org/apache/kylin/measure/MeasureInstance.java b/core-cube/src/main/java/org/apache/kylin/measure/MeasureInstance.java
new file mode 100644
index 0000000..90a5ec0
--- /dev/null
+++ b/core-cube/src/main/java/org/apache/kylin/measure/MeasureInstance.java
@@ -0,0 +1,246 @@
+/*
+ * 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.measure;
+
+import com.fasterxml.jackson.annotation.JsonAutoDetect;
+import com.fasterxml.jackson.annotation.JsonIgnore;
+import com.fasterxml.jackson.annotation.JsonProperty;
+import com.google.common.collect.Lists;
+import org.apache.kylin.common.persistence.RootPersistentEntity;
+import org.apache.kylin.common.util.RandomUtil;
+import org.apache.kylin.cube.CubeInstance;
+import org.apache.kylin.metadata.model.DateTimeRange;
+import org.apache.kylin.metadata.model.ISegment;
+import org.apache.kylin.metadata.model.MeasureDesc;
+import org.apache.kylin.metadata.model.SegmentStatusEnum;
+import org.apache.kylin.metadata.model.Segments;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.Iterator;
+import java.util.List;
+import java.util.Locale;
+import java.util.stream.Collectors;
+
+import static org.apache.kylin.metadata.model.SegmentRange.TSRange;
+
+@JsonAutoDetect(fieldVisibility = JsonAutoDetect.Visibility.NONE, getterVisibility = JsonAutoDetect.Visibility.NONE, isGetterVisibility = JsonAutoDetect.Visibility.NONE, setterVisibility = JsonAutoDetect.Visibility.NONE)
+public class MeasureInstance extends RootPersistentEntity {
+    private static final Logger LOG = LoggerFactory.getLogger(MeasureInstance.class);
+
+    public static MeasureInstance createMeasureInstance(MeasureDesc measureDesc, CubeInstance cube) {
+        MeasureInstance measureInstance = new MeasureInstance();
+        measureInstance.setName(measureDesc.getName());
+        measureInstance.setMeasureDesc(measureDesc);
+        measureInstance.setCubeName(cube.getName());
+        measureInstance.setSegments(new Segments<>());
+        measureInstance.setSegmentsName(Lists.newArrayList());
+        measureInstance.setOnline(true);
+        return measureInstance;
+    }
+
+    public static MeasureInstance copy(MeasureInstance needCopy) {
+        MeasureInstance copy = new MeasureInstance();
+        copy.setName(needCopy.getName());
+        copy.setCubeName(needCopy.getCubeName());
+        copy.setSegmentsName(Lists.newArrayList(needCopy.getSegmentsName()));
+        Segments<ISegment> copySegs = new Segments<>();
+        // just copy reference of segments, you can't modify any element in segments here.
+        needCopy.getSegments().forEach(s -> copySegs.add(s));
+        copy.setSegments(copySegs);
+        copy.setOnline(copy.isOnline());
+        copy.setLastModified(needCopy.getLastModified());
+        copy.setUuid(needCopy.getUuid());
+        copy.setDateTimeRanges(needCopy.getDateTimeRanges());
+        return copy;
+    }
+
+    public static String getResourceName(String cubeName, String measureName) {
+        return cubeName + "/" + measureName;
+    }
+
+    @JsonProperty("name")
+    private String name;
+    @JsonProperty("cube_name")
+    private String cubeName;
+    @JsonProperty("segments_name")
+    private List<String> segmentsName;
+    @JsonProperty("segments")
+    @JsonIgnore
+    private Segments<ISegment> segments;
+    @JsonProperty("online")
+    private boolean online = true;
+
+    private MeasureDesc measureDesc;
+
+    private List<DateTimeRange> dateTimeRanges;
+
+    public String getName() {
+        return name;
+    }
+
+    public void setName(String name) {
+        this.name = name;
+    }
+
+    public String getCubeName() {
+        return cubeName;
+    }
+
+    public void setCubeName(String cubeName) {
+        this.cubeName = cubeName;
+    }
+
+    public Segments<ISegment> getSegments() {
+        return segments;
+    }
+
+    public void setSegments(Segments<ISegment> segments) {
+        this.segments = segments;
+    }
+
+    public List<String> getSegmentsName() {
+        return segmentsName;
+    }
+
+    public void setSegmentsName(List<String> segmentsName) {
+        this.segmentsName = segmentsName;
+    }
+
+    public void setOnline(boolean online) {
+        this.online = online;
+    }
+
+    public boolean isOnline() {
+        return online;
+    }
+
+    public List<DateTimeRange> getDateTimeRanges() {
+        return dateTimeRanges;
+    }
+
+    public MeasureDesc getMeasureDesc() {
+        return measureDesc;
+    }
+
+    public void setMeasureDesc(MeasureDesc measureDesc) {
+        this.measureDesc = measureDesc;
+    }
+
+    public void setDateTimeRanges(List<DateTimeRange> dateTimeRanges) {
+        this.dateTimeRanges = dateTimeRanges;
+    }
+
+    public void init(CubeInstance cube) {
+        refreshSegments(cube);
+        this.measureDesc = findMeasureByName(this.name, cube);
+    }
+
+    private MeasureDesc findMeasureByName(String measureName, CubeInstance cube) {
+        for (MeasureDesc m : cube.getMeasures()) {
+            if (m.getName().equals(measureName)) {
+                return m;
+            }
+        }
+        LOG.warn("Can't find measure by name: {}, maybe it has been deleted in CubeDesc: {} ", measureName, cube.getDescriptor().getName());
+        return null;
+    }
+
+    public void refreshSegments(CubeInstance cube) {
+        // refresh segments
+        if (null == this.segments) {
+            this.segments = new Segments<>();
+        }
+        this.segments.clear();
+        Iterator<? extends ISegment> cubeSegIter = cube.getSegments(SegmentStatusEnum.READY).iterator();
+        while (cubeSegIter.hasNext()) {
+            ISegment seg = cubeSegIter.next();
+            if (this.getSegmentsName().contains(seg.getName())) {
+                this.segments.add(seg);
+            }
+        }
+        if (this.segments.size() != this.segmentsName.size()) {
+            throw new IllegalStateException(String.format(Locale.ROOT, "Segment names size doesn't equal segments size. Segment names: %s, name in segments: %s, Cube: %s",
+                    this.segmentsName,
+                    this.segments.stream().map(ISegment::getName).collect(Collectors.toList()),
+                    cubeName));
+        }
+
+        // resort segment name
+        for (int i = 0; i < this.segments.size(); i++) {
+            this.segmentsName.set(i, segments.get(i).getName());
+        }
+
+        // refresh date time ranges
+        if (this.dateTimeRanges == null) {
+            dateTimeRanges = Lists.newArrayListWithCapacity(4);
+        }
+        dateTimeRanges.clear();
+        if (segments.size() == 0) {
+            return;
+        }
+
+
+        long startTime = segments.getTSStart();
+
+        for (int i = 1; i < segments.size(); i++) {
+            TSRange lastTsRange = segments.get(i - 1).getTSRange();
+            TSRange tsRange = segments.get(i).getTSRange();
+            if (tsRange.start.v < lastTsRange.end.v) {
+                throw new IllegalStateException(String.format(Locale.ROOT, "Overlap time range, [%s, %s]  [%s, %s]",
+                        lastTsRange.start.v, lastTsRange.end.v, tsRange.start.v, tsRange.end.v));
+            } else if (tsRange.start.v > lastTsRange.end.v) {
+                // there have a hole
+                dateTimeRanges.add(DateTimeRange.create(startTime, lastTsRange.end.v));
+                // change cursor
+                startTime = tsRange.start.v;
+            } else {
+                continue;
+            }
+        }
+        long endTime = segments.getTSEnd();
+        dateTimeRanges.add(DateTimeRange.create(startTime, endTime));
+    }
+
+    public String getKey(){
+        return getResourceName(cubeName, name);
+    }
+
+    @Override
+    public String resourceName() {
+        return getKey();
+    }
+
+    public boolean isOnSegment(ISegment s) {
+        return isOnSegment(s.getName());
+    }
+
+    public boolean isOnSegment(String segName) {
+        return segmentsName.contains(segName);
+    }
+
+    public void updateRandomUuid() {
+        setUuid(RandomUtil.randomUUID().toString());
+    }
+
+    @Override
+    public String toString() {
+        return getKey();
+    }
+}
diff --git a/core-cube/src/main/java/org/apache/kylin/measure/MeasureManager.java b/core-cube/src/main/java/org/apache/kylin/measure/MeasureManager.java
new file mode 100644
index 0000000..5a0fed1
--- /dev/null
+++ b/core-cube/src/main/java/org/apache/kylin/measure/MeasureManager.java
@@ -0,0 +1,701 @@
+/*
+ * 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.measure;
+
+import com.google.common.base.Preconditions;
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.Lists;
+import com.google.common.collect.Sets;
+import org.apache.kylin.common.KylinConfig;
+import org.apache.kylin.common.persistence.JsonSerializer;
+import org.apache.kylin.common.persistence.ResourceStore;
+import org.apache.kylin.common.persistence.Serializer;
+import org.apache.kylin.common.util.AutoReadWriteLock;
+import org.apache.kylin.cube.CubeInstance;
+import org.apache.kylin.cube.CubeManager;
+import org.apache.kylin.cube.CubeUpdate;
+import org.apache.kylin.cube.model.CubeDesc;
+import org.apache.kylin.metadata.MetadataConstants;
+import org.apache.kylin.metadata.cachesync.Broadcaster;
+import org.apache.kylin.metadata.cachesync.CachedCrudAssist;
+import org.apache.kylin.metadata.cachesync.CaseInsensitiveStringCache;
+import org.apache.kylin.metadata.model.ISegment;
+import org.apache.kylin.metadata.model.MeasureDesc;
+import org.apache.kylin.metadata.model.SegmentStatusEnum;
+import org.apache.kylin.metadata.project.ProjectInstance;
+import org.apache.kylin.metadata.project.ProjectManager;
+import org.apache.kylin.metadata.project.RealizationEntry;
+import org.apache.kylin.metadata.realization.RealizationType;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.io.IOException;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Locale;
+import java.util.Set;
+import java.util.stream.Collectors;
+
+import static org.apache.kylin.common.util.AutoReadWriteLock.AutoLock;
+import static org.apache.kylin.metadata.cachesync.Broadcaster.Event.CREATE;
+import static org.apache.kylin.metadata.cachesync.Broadcaster.Event.DROP;
+import static org.apache.kylin.metadata.cachesync.Broadcaster.Event.UPDATE;
+
+public class MeasureManager {
+
+    public static final Serializer<MeasureInstance> MEASURE_SERIALIZER = new JsonSerializer<>(MeasureInstance.class);
+
+    private static final Logger LOG = LoggerFactory.getLogger(MeasureManager.class);
+    public static final String CUBE_MEASURE = "cube_measure";
+
+    public static MeasureManager getInstance(KylinConfig config) {
+        return config.getManager(MeasureManager.class);
+    }
+
+    // called by reflection
+    static MeasureManager newInstance(KylinConfig config) throws IOException {
+        return new MeasureManager(config);
+    }
+
+    // ===============================================
+
+    private KylinConfig config;
+
+    // measure instance store path ==> MeasureInstance
+    private CaseInsensitiveStringCache<MeasureInstance> measureMap;
+    private CubeL2Cache cubeL2Cache;
+
+    private CachedCrudAssist<MeasureInstance> crud;
+
+    private AutoReadWriteLock measureMapLock = new AutoReadWriteLock();
+
+    private MeasureManager(KylinConfig config) throws IOException {
+        LOG.info("Initializing MeasureManager with config " + config);
+        this.config = config;
+        this.measureMap = new CaseInsensitiveStringCache<>(config, "measure");
+        this.cubeL2Cache = new CubeL2Cache(getCubeManager());
+
+        this.crud = new CachedCrudAssist<MeasureInstance>(getStore(), ResourceStore.MEASURE_RESOURCE_ROOT, MeasureInstance.class, measureMap) {
+            @Override
+            protected MeasureInstance initEntityAfterReload(MeasureInstance entity, String resourceName) {
+                CubeInstance cube = getCubeManager().getCube(entity.getCubeName());
+                entity.init(cube);
+
+                return entity;
+            }
+        };
+
+        // touch lower level metadata before registering my listener
+        crud.reloadAll();
+        Broadcaster.getInstance(config).registerListener(new MeasureSyncListener(), CUBE_MEASURE);
+    }
+
+    private class MeasureSyncListener extends Broadcaster.Listener {
+
+        @Override
+        public void onEntityChange(Broadcaster broadcaster, String entity, Broadcaster.Event event, String cacheKey) throws IOException {
+
+            switch (entity) {
+//                case MEASURE:
+//                    triggerByMeasure(broadcaster, entity, event, cacheKey);
+//                    break;
+//                case CUBE:
+//                case CUBE_DESC:
+                case CUBE_MEASURE:
+                    triggerByCube(broadcaster, entity, event, cacheKey);
+                    break;
+                default :
+                    break;
+            }
+        }
+
+        private void triggerByCube(Broadcaster broadcaster, String cube, Broadcaster.Event event, String cubeName) throws IOException {
+            if (event == DROP) {
+                removeLocalByCube(cubeName);
+            } else {
+                reloadByCubeQuietly(cubeName);
+            }
+        }
+
+        private void triggerByMeasure(Broadcaster broadcaster, String measure, Broadcaster.Event event, String measureKey) {
+            if (event == DROP) {
+                removeLocal(measureKey);
+            } else {
+                reloadQuietly(measureKey);
+            }
+        }
+
+    }
+
+    private MeasureInstance reloadQuietly(String cacheKey) {
+        try (AutoLock lock = measureMapLock.lockForWrite()) {
+            MeasureInstance ret = crud.reloadQuietly(cacheKey);
+            cubeL2Cache.reloadCache(ret.getCubeName());
+            return ret;
+        }
+    }
+
+    private List<MeasureInstance> reloadByCubeQuietly(String cubeName) throws IOException {
+        try (AutoLock lock = measureMapLock.lockForWrite()) {
+            CubeInstance cube = getCubeManager().getCube(cubeName);
+            if (cube == null) {
+                LOG.warn("Can't find cube {} in cache, it's missing or unload yet, so kylin can't reload cache of measures on cube. you can trigger this reload process again by update this cube!");
+                return Collections.EMPTY_LIST;
+            }
+            // remove L1 cache
+            getMeasuresInCubeAllowMiss(cube.getProject(), cube.getName()).stream()
+                    .forEach(m -> measureMap.removeLocal(m.getKey()));
+
+            List<String> paths = getStore().collectResourceRecursively(ResourceStore.MEASURE_RESOURCE_ROOT + "/" + cube.getName(), MetadataConstants.FILE_SURFIX);
+
+            List<MeasureInstance> ret = Lists.newArrayListWithCapacity(paths.size());
+            paths.forEach(p -> ret.add(crud.reloadAt(p)));
+            cubeL2Cache.reloadCache(cubeName);
+            return ImmutableList.copyOf(ret);
+        }
+    }
+
+    public ResourceStore getStore() {
+        return ResourceStore.getStore(this.config);
+    }
+
+    public MeasureInstance getMeasure(String cubeName, String measureName) {
+        try (AutoLock lock = measureMapLock.lockForRead()) {
+            return getMeasureByKey(MeasureInstance.getResourceName(cubeName, measureName));
+        }
+    }
+
+    public MeasureInstance getMeasureByKey(String key) {
+        try (AutoLock lock = measureMapLock.lockForRead()) {
+            return measureMap.get(key);
+        }
+    }
+
+    public List<MeasureInstance> getMeasuresOnSegment(String projectName, String cubeName, String segmentName) {
+        try (AutoLock lock = measureMapLock.lockForRead()) {
+            return cubeL2Cache.getMeasuresOf(cubeName, segmentName);
+        }
+    }
+
+    public List<MeasureInstance> getMeasuresInCube(String projectName, String cubeName) {
+        try (AutoLock lock = measureMapLock.lockForRead()) {
+            return cubeL2Cache.getMeasuresOnCube(cubeName);
+        }
+    }
+
+    /**
+     * Sometimes, CubeDesc in cache contain more measures than in Measures in cache, or vice versa.
+     * this call return cache may miss those measures. Those measure will be restored after CubeDesc update
+     * @param projectName
+     * @param cubeName
+     * @return
+     */
+    public List<MeasureInstance> getMeasuresInCubeAllowMiss(String projectName, String cubeName) {
+        try (AutoLock lock = measureMapLock.lockForRead()) {
+            // try get don't allow miss
+            return cubeL2Cache.getMeasuresOnCube(cubeName);
+        } catch (CubeL2Cache.MissMeasureCacheException e) {
+            LOG.info("There have some missing measures. cause by: " + e.getLocalizedMessage());
+            return cubeL2Cache.getMeasuresOnCubeAllowMiss(cubeName);
+        }
+    }
+
+    /**
+     * create and announce
+     * @param cube
+     * @return
+     * @throws IOException
+     */
+    public List<MeasureInstance> createMeasuresOnCube(CubeInstance cube) throws IOException {
+        try (AutoLock lock = measureMapLock.lockForWrite()) {
+            boolean existed = cubeL2Cache.getMeasuresOnCubeAllowMiss(cube.getName()).size() != 0;
+            List<MeasureDesc> measures = cube.getMeasures();
+            List<MeasureInstance> needSaveMeasures = measures.stream()
+                    .map(m -> MeasureInstance.createMeasureInstance(m, cube))
+                    .collect(Collectors.toList());
+
+            return batchSaveCubeMeasure(needSaveMeasures, cube.getName(), existed);
+        }
+    }
+
+    // don't announce
+    private MeasureInstance createMeasureAlone(MeasureInstance measureInstance) throws IOException {
+        try (AutoLock lock = measureMapLock.lockForWrite()) {
+            createInStore(measureInstance);
+            // save in cache
+            return createCache(measureInstance);
+        }
+    }
+
+    private void createInStore(MeasureInstance measureInstance) throws IOException {
+        try (AutoLock lock = measureMapLock.lockForWrite()) {
+            // save meta data
+            getStore().checkAndPutResource(getResourcePath(measureInstance), measureInstance, MEASURE_SERIALIZER);
+        }
+    }
+
+    private MeasureInstance createCache(MeasureInstance measureInstance) {
+        try (AutoLock lock = measureMapLock.lockForWrite()) {
+            // save in cache
+            measureMap.putLocal(measureInstance.getKey(), measureInstance);
+            cubeL2Cache.reloadCache(measureInstance.getCubeName());
+            return measureInstance;
+        }
+    }
+
+    public List<MeasureInstance> batchSaveCubeMeasure(List<MeasureInstance> measures, String cubeName, boolean existed) throws IOException {
+        try (AutoLock lock = measureMapLock.lockForWrite()) {
+            // save in store
+            batchSaveCubeMeasureInStore(measures);
+
+            // announce
+            announceCubeMeasureEvent(existed ? UPDATE : CREATE, cubeName);
+
+            // save in cache
+            return batchSaveCubeMeasureInCache(measures, cubeName);
+        }
+    }
+
+    private List<MeasureInstance> batchSaveCubeMeasureInStore(List<MeasureInstance> measures) throws IOException {
+        try (AutoLock lock = measureMapLock.lockForWrite()) {
+            // save in store
+            for (MeasureInstance m : measures) {
+                if (null == m.getUuid()) {
+                    m.updateRandomUuid();
+                }
+                createInStore(m);
+            }
+            return measures;
+        }
+    }
+
+    private List<MeasureInstance> batchSaveCubeMeasureInCache(List<MeasureInstance> measures, String cubeName) throws IOException {
+        try (AutoLock lock = measureMapLock.lockForWrite()) {
+            // save in cache
+            for (MeasureInstance m : measures) {
+                measureMap.putLocal(m.getKey(), m);
+            }
+            cubeL2Cache.reloadCache(cubeName);
+
+            return measures;
+        }
+    }
+
+    // ================delete====================
+
+    private MeasureInstance deleteInStore(MeasureInstance m) throws IOException {
+        try (AutoLock lock = measureMapLock.lockForWrite()) {
+            if (m.getSegmentsName().size() > 0) {
+                throw new IllegalStateException(String.format(Locale.ROOT, "Can't delete measure %s, please delete the contained segments first. %s", m.getName(), m.getSegmentsName()));
+            }
+            getStore().deleteResource(getResourcePath(m));
+            return m;
+        }
+    }
+
+    private MeasureInstance deleteCache(MeasureInstance m) {
+        try (AutoLock lock = measureMapLock.lockForWrite()) {
+            measureMap.remove(m.getKey());
+            cubeL2Cache.reloadCache(m.getCubeName());
+            return m;
+        }
+    }
+
+    public List<MeasureInstance> deleteByCube(String projectName, String cubeName) throws IOException {
+        try (AutoLock lock = measureMapLock.lockForWrite()) {
+            // delete meta data
+            List<MeasureInstance> needDrop = deleteInStoreByCube(projectName, cubeName);
+            if (null != needDrop && needDrop.size() > 0) {
+                // announce delete cube measure
+                announceCubeMeasureEvent(DROP, cubeName);
+                // delete in cache
+                removeLocalByCube(cubeName);
+            }
+            return needDrop;
+        }
+    }
+
+    private List<MeasureInstance> removeLocalByCube(String cubeName) {
+        try (AutoLock lock = measureMapLock.lockForWrite()) {
+            List<MeasureInstance> needRemove = cubeL2Cache.getMeasuresOnCube(cubeName);
+            if (needRemove.size() == 0) {
+                // get from L1 cache
+                needRemove = getMeasuresInCubeFromL1Cache(cubeName);
+            }
+            // remove CubeL2Cache
+            cubeL2Cache.remove(cubeName);
+            // remove measureMap
+            needRemove.forEach(m -> removeL1Cache(m.getKey()));
+            return needRemove;
+        }
+    }
+
+    private List<MeasureInstance> getMeasuresInCubeFromL1Cache(String cubeName) {
+        String prefix = cubeName + "/";
+        return measureMap.keySet()
+                .stream()
+                .filter(k -> k.startsWith(prefix))
+                .map(k -> measureMap.get(k))
+                .collect(Collectors.toList());
+    }
+
+    private MeasureInstance removeL1Cache(String key) {
+        try (AutoLock lock = measureMapLock.lockForWrite()) {
+            MeasureInstance ret = measureMap.get(key);
+            if (null != ret) {
+                measureMap.removeLocal(key);
+            }
+            return ret;
+        }
+    }
+
+    /**
+     * remove L1 cache and reload L2 cache by measure key
+     * @param key
+     * @return
+     */
+    private MeasureInstance removeLocal(String key) {
+        try (AutoLock lock = measureMapLock.lockForWrite()) {
+            MeasureInstance ret = removeL1Cache(key);
+            if (null != ret) {
+                cubeL2Cache.reloadCache(ret.getCubeName());
+//                cubeL2Cache.reloadCacheAllowMiss(ret.getCubeName());
+            }
+            return ret;
+        }
+    }
+
+    /**
+     * just delete meta data in store, don't broadcast
+     * @param projectName
+     * @param cubeName
+     * @return
+     */
+    private List<MeasureInstance> deleteInStoreByCube(String projectName, String cubeName) throws IOException {
+        try (AutoLock lock = measureMapLock.lockForWrite()) {
+            List<MeasureInstance> needDrop = getMeasuresInCube(projectName, cubeName);
+            ResourceStore store = getStore();
+            for (MeasureInstance m : needDrop) {
+                store.deleteResource(getResourcePath(m));
+            }
+            return needDrop;
+        }
+    }
+
+    public void deleteSegmentByName(CubeInstance cube, String segmentName) throws IOException {
+        try (AutoLock lock = measureMapLock.lockForWrite()) {
+            List<MeasureInstance> updated = deleteSegInMeasure(cube, segmentName);
+            batchSaveCubeMeasure(updated, cube.getName(), true);
+        }
+    }
+
+    private List<MeasureInstance> deleteSegInMeasure(CubeInstance cube, String segmentName) {
+        List<MeasureInstance> measuresOnSegment = getMeasuresOnSegment(cube.getProject(), cube.getName(), segmentName);
+        if (measuresOnSegment.size() <= 0) {
+            return measuresOnSegment;
+        }
+        List<MeasureInstance> updated = measuresOnSegment.stream()
+                .map(m -> MeasureInstance.copy(m))
+                .collect(Collectors.toList());
+        for (MeasureInstance m : updated) {
+            if (!m.getSegmentsName().remove(segmentName)) {
+                LOG.warn("Can't find segment by name {} in measure {}.", segmentName, m.getKey());
+                continue;
+            }
+            m.refreshSegments(cube);
+        }
+        return updated;
+    }
+
+    private List<MeasureInstance> batchDeleteSegInMeasure(CubeInstance cube, List<String> segmentsName) {
+        List<MeasureInstance> measuresOnCube = getMeasuresInCube(cube.getProject(), cube.getName());
+        if (measuresOnCube.size() <= 0) {
+            return measuresOnCube;
+        }
+        List<MeasureInstance> updated = measuresOnCube.stream()
+                .map(m -> MeasureInstance.copy(m))
+                .collect(Collectors.toList());
+        for (MeasureInstance m : updated) {
+            if (m.getSegmentsName().removeIf(s -> segmentsName.contains(s))) {
+                m.refreshSegments(cube);
+            }
+        }
+        return updated;
+    }
+
+    /**
+     *
+     * if segsToDrop is null it's mean delete all;
+     */
+    public void deleteSegments(CubeInstance cube, ISegment... segsToDrop) throws IOException {
+        try (AutoLock lock = measureMapLock.lockForWrite()) {
+            List<String> needDrop = Lists.newArrayList(segsToDrop).stream().map(ISegment::getName).collect(Collectors.toList());
+            deleteSegmentsByName(cube, needDrop);
+        }
+    }
+
+    private void deleteSegmentsByName(CubeInstance cube, List<String> needDrop) throws IOException {
+        // save in store
+        List<MeasureInstance> updated = batchDeleteSegInMeasure(cube, needDrop);
+        List<MeasureInstance> storedMeasures = batchSaveCubeMeasureInStore(updated);
+        // announce
+        announceUpdateCubeMeasure(cube.getName());
+        // save in cache
+        batchSaveCubeMeasureInCache(storedMeasures, cube.getName());
+    }
+
+    public void deleteAllSegments(CubeInstance cube) throws IOException {
+        try (AutoLock lock = measureMapLock.lockForWrite()) {
+            List<String> needDrop;
+            LOG.info("Delete all segments in cube.", cube.getName());
+            needDrop = cube.getSegments().stream().map(ISegment::getName).collect(Collectors.toList());
+
+            // save in store
+            deleteSegmentsByName(cube, needDrop);
+        }
+    }
+
+    // ================update=====================
+    /**
+     * if some measures on cube have been modified. add or delete measure
+     * @param cubeDesc
+     * @return updated measures in cube
+     */
+    public List<MeasureInstance> updateMeasuresOnCube(CubeDesc cubeDesc) throws IOException {
+        try (AutoLock lock = measureMapLock.lockForWrite()) {
+            List<CubeInstance> cubesByDesc = getCubeManager().getCubesByDesc(cubeDesc.getName());
+            List<MeasureInstance> ret = Lists.newArrayList();
+            for (CubeInstance cube : cubesByDesc) {
+                ret.addAll(updateMeasuresOnCube(cube));
+            }
+
+            return ret;
+        }
+    }
+
+    public List<MeasureInstance> updateSegmentsOnCube(CubeInstance updatedCube, CubeUpdate update) throws IOException {
+        ISegment[] toAddSegs = getReadySegments(update.getToAddSegs());
+        ISegment[] toUpdateSegs = getReadySegments(update.getToUpdateSegs());
+        ISegment[] toRemoveSegs = getReadySegments(update.getToRemoveSegs());
+
+        boolean needToUpdateSegs = toAddSegs.length > 0 || toUpdateSegs.length > 0 || toRemoveSegs.length > 0;
+
+        if (!needToUpdateSegs) {
+            return Collections.emptyList();
+        }
+        /* there may have overlap between toRemoveSegs and toUpdateSegs,
+         * because they are collected by their uuid.
+         * So we remove toRemoveSegs firstly, then add toUpdateSegs.
+         */
+        List<MeasureInstance> newMeasures = batchDeleteSegInMeasure(updatedCube,
+                Arrays.stream(toRemoveSegs).map(m -> m.getName()).collect(Collectors.toList()));
+
+        Set<String> toAddSegNames = Arrays.stream(toAddSegs).map(ISegment::getName).collect(Collectors.toSet());
+        Set<String> toUpdateSegNames = Arrays.stream(toUpdateSegs).map(ISegment::getName).collect(Collectors.toSet());
+
+        for (int i = 0;
+             (toAddSegNames.size() > 0 || toUpdateSegNames.size() > 0)
+                     && i < newMeasures.size(); i++) {
+            MeasureInstance measure = newMeasures.get(i);
+            Set<String> newSegsName = Sets.newHashSet(measure.getSegmentsName());
+            newSegsName.addAll(toAddSegNames);
+            newSegsName.addAll(toUpdateSegNames);
+            List<String> newSegsNameList = Lists.newArrayList(newSegsName);
+            Collections.sort(newSegsNameList);
+            measure.setSegmentsName(newSegsNameList);
+            measure.refreshSegments(updatedCube);
+        }
+        batchSaveCubeMeasure(newMeasures, updatedCube.getName(), true);
+        return newMeasures;
+    }
+
+    private ISegment[] getReadySegments(ISegment[] segs) {
+        if (null == segs) {
+            return new ISegment[]{};
+        }
+        return Arrays.stream(segs)
+                .filter(s -> s.getStatus().equals(SegmentStatusEnum.READY))
+                .toArray(ISegment[]::new);
+    }
+
+    private List<MeasureInstance> updateMeasuresOnCube(CubeInstance cube) throws IOException {
+        try (AutoLock lock = measureMapLock.lockForWrite()) {
+            List<MeasureInstance> cachedMeasureOnCube = getMeasuresInCubeAllowMiss(cube.getProject(), cube.getName());
+            List<MeasureInstance> needDrop = Lists.newArrayListWithCapacity(5);
+            List<MeasureInstance> needAdd = Lists.newArrayListWithCapacity(6);
+
+            // find need drop
+            Set<String> latestMeasures = cube.getMeasures().stream().map(MeasureDesc::getName).collect(Collectors.toSet());
+            cachedMeasureOnCube.stream()
+                    .filter(cm -> !latestMeasures.contains(cm.getName()))
+                    .forEach(cm -> needDrop.add(cm));
+            // find need add
+            Set<String> curMeasureNames = cachedMeasureOnCube.stream().map(MeasureInstance::getName).collect(Collectors.toSet());
+            cube.getMeasures().stream()
+                    .filter(m -> !curMeasureNames.contains(m.getName()))
+                    .forEach(m -> needAdd.add(MeasureInstance.createMeasureInstance(m, cube)));
+
+            for (MeasureInstance m : needAdd) {
+                createInStore(m);
+            }
+
+            for (MeasureInstance m : needDrop) {
+                deleteInStore(m);
+                removeLocal(m.getKey());
+            }
+
+            announceUpdateCubeMeasure(cube.getName());
+
+            reloadByCubeQuietly(cube.getName());
+
+            return getMeasuresInCube(cube.getProject(), cube.getName());
+        }
+    }
+
+    /**
+     *
+     * @param project
+     * @param cubeName
+     * @param updatedMeasures
+     * @return
+     * @throws IOException
+     */
+    public List<MeasureInstance> updateMeasures(String project, String cubeName, List<MeasureInstance> updatedMeasures) throws IOException {
+        try (AutoLock lock = measureMapLock.lockForWrite()) {
+            return batchSaveCubeMeasure(updatedMeasures, cubeName, true);
+        }
+    }
+
+    private String getResourcePath(MeasureInstance m) {
+        return ResourceStore.MEASURE_RESOURCE_ROOT + "/" + m.resourceName() + MetadataConstants.FILE_SURFIX;
+    }
+
+    public AutoReadWriteLock getMeasureMapLock() {
+        return measureMapLock;
+    }
+
+    private CubeManager getCubeManager(){
+        return CubeManager.getInstance(config);
+    }
+
+    private void announceUpdateCubeMeasure(String cubeName) {
+        announceCubeMeasureEvent(UPDATE, cubeName);
+    }
+
+    private void announceCubeMeasureEvent(Broadcaster.Event e, String cubeName) {
+        measureMap.getBroadcaster().announce(CUBE_MEASURE, e.getType(), cubeName);
+    }
+
+    public CaseInsensitiveStringCache<MeasureInstance> getCache() {
+        return measureMap;
+    }
+
+    public static void main(String[] args) throws IOException {
+        String errInputMsg =
+                "Error argument. Usage: init cube cubeName \n" +
+                "                            project projectName \n" +
+                "                            all";
+        if (args.length < 1 || !args[0].equals("init")) {
+            LOG.error(errInputMsg);
+            return;
+        }
+        switch (args[1]) {
+            case "all":
+                // init all cube
+                initAllCube();
+                break;
+            case "project":
+                // init by project
+                String projectName = args[2];
+                initByProject(projectName);
+                break;
+            case "cube":
+                // init by project
+                String cubeName = args[2];
+                initialCubeMeasure(cubeName);
+                break;
+            default:
+                LOG.error(errInputMsg);
+                break;
+        }
+
+        return;
+    }
+
+    private static void initAllCube() throws IOException {
+        KylinConfig config = KylinConfig.getInstanceFromEnv();
+        CubeManager cubeMgr = CubeManager.getInstance(config);
+        List<CubeInstance> allCubInstance = cubeMgr.listAllCubes();
+        for (CubeInstance cube : allCubInstance) {
+            initialCubeMeasure(cube.getName());
+        }
+    }
+
+    private static void initByProject(String projectName) throws IOException {
+        KylinConfig config = KylinConfig.getInstanceFromEnv();
+        LOG.info("Initialize all cube measure under project " + projectName);
+        ProjectInstance project = ProjectManager.getInstance(config).getProject(projectName);
+        Preconditions.checkNotNull(project, "Can't find project " + projectName);
+        List<RealizationEntry> realizationEntries = project.getRealizationEntries(RealizationType.CUBE);
+        for (RealizationEntry r : realizationEntries) {
+            String cubeName = r.getRealization();
+            initialCubeMeasure(cubeName);
+        }
+    }
+
+    private static void initialCubeMeasure(String cubeName) throws IOException {
+        KylinConfig config = KylinConfig.getInstanceFromEnv();
+        CubeInstance cube = CubeManager.getInstance(config).getCube(cubeName);
+        if (null == cube) {
+            LOG.error(String.format(Locale.ROOT, "Can't find cube by project: %s, cube: %s.", cubeName));
+            return;
+        }
+
+        List<MeasureInstance> measures = cube.getMeasures().stream()
+                .map(m -> MeasureInstance.createMeasureInstance(m, cube))
+                .collect(Collectors.toList());
+        List<String> segsName = cube.getSegments(SegmentStatusEnum.READY).stream()
+                .map(ISegment::getName)
+                .collect(Collectors.toList());
+        MeasureManager measureManager = MeasureManager.getInstance(config);
+        Iterator<MeasureInstance> iter = measures.iterator();
+
+        while (iter.hasNext()) {
+            MeasureInstance m = iter.next();
+            MeasureInstance measureInStore = measureManager.getMeasure(m.getCubeName(), m.getName());
+            if (null != measureInStore) {
+                LOG.info(m.getKey() + " already exist, won't initialize it. you can delete it first.");
+                m.setUuid(measureInStore.getUuid());
+                m.setLastModified(measureInStore.getLastModified());
+                iter.remove();
+            }
+            m.setSegmentsName(segsName);
+            try {
+                m.refreshSegments(cube);
+            } catch (IllegalStateException e){
+                LOG.error("Error: ", e);
+                continue;
+            }
+        }
+
+        measureManager.batchSaveCubeMeasureInStore(measures);
+    }
+}
diff --git a/core-cube/src/test/java/org/apache/kylin/cube/CubeManagerTest.java b/core-cube/src/test/java/org/apache/kylin/cube/CubeManagerTest.java
index 7a102bb..907e6b5 100644
--- a/core-cube/src/test/java/org/apache/kylin/cube/CubeManagerTest.java
+++ b/core-cube/src/test/java/org/apache/kylin/cube/CubeManagerTest.java
@@ -31,6 +31,8 @@ import org.apache.kylin.common.KylinConfig;
 import org.apache.kylin.common.persistence.ResourceStore;
 import org.apache.kylin.common.util.LocalFileMetadataTestCase;
 import org.apache.kylin.cube.model.CubeDesc;
+import org.apache.kylin.measure.MeasureInstance;
+import org.apache.kylin.measure.MeasureManager;
 import org.apache.kylin.metadata.model.SegmentRange;
 import org.apache.kylin.metadata.model.SegmentRange.TSRange;
 import org.apache.kylin.metadata.model.SegmentStatusEnum;
@@ -38,6 +40,7 @@ import org.apache.kylin.metadata.project.ProjectInstance;
 import org.apache.kylin.metadata.project.ProjectManager;
 import org.apache.kylin.metadata.realization.RealizationStatusEnum;
 import org.junit.After;
+import org.junit.Assert;
 import org.junit.Before;
 import org.junit.Test;
 
@@ -79,13 +82,24 @@ public class CubeManagerTest extends LocalFileMetadataTestCase {
 
         // clean legacy in case last run failed
         store.deleteResource("/cube/a_whole_new_cube.json");
-
+        for (String measureRes : store.collectResourceRecursively("/measure/a_whole_new_cube", ".json")) {
+            store.deleteResource(measureRes);
+        }
         CubeDescManager cubeDescMgr = getCubeDescManager();
         CubeDesc desc = cubeDescMgr.getCubeDesc("test_kylin_cube_with_slr_desc");
         CubeInstance createdCube = cubeMgr.createCube("a_whole_new_cube", ProjectInstance.DEFAULT_PROJECT_NAME, desc,
                 null);
         assertTrue(createdCube.equals(cubeMgr.getCube("a_whole_new_cube")));
 
+        // test MeasureManager
+        assertTrue(getStore().collectResourceRecursively("/measure/a_whole_new_cube", ".json").size() == createdCube.getMeasures().size());
+        List<MeasureInstance> measuresInCreatedCube = getMeasureManager().getMeasuresInCube(createdCube.getProject(), createdCube.getName());
+        assertTrue(createdCube.getMeasures().size() == measuresInCreatedCube.size());
+        for (MeasureInstance m : measuresInCreatedCube) {
+            assertTrue(createdCube.getMeasures().contains(m.getMeasureDesc()));
+            assertTrue(m.getSegments().size() == 0);
+        }
+
         assertTrue(prjMgr.listAllRealizations(ProjectInstance.DEFAULT_PROJECT_NAME).contains(createdCube));
 
         CubeInstance droppedCube = CubeManager.getInstance(getTestConfig()).dropCube("a_whole_new_cube", false);
@@ -94,6 +108,10 @@ public class CubeManagerTest extends LocalFileMetadataTestCase {
         assertTrue(!prjMgr.listAllRealizations(ProjectInstance.DEFAULT_PROJECT_NAME).contains(droppedCube));
 
         assertNull(CubeManager.getInstance(getTestConfig()).getCube("a_whole_new_cube"));
+
+        List<MeasureInstance> measuresInDroppedCube = getMeasureManager().getMeasuresInCube(droppedCube.getProject(), droppedCube.getName());
+        assertTrue(measuresInDroppedCube.size() == 0);
+        assertTrue(getStore().collectResourceRecursively("/measure/a_whole_new_cube", ".json").size() == 0);
     }
 
     @Test
@@ -109,7 +127,9 @@ public class CubeManagerTest extends LocalFileMetadataTestCase {
 
             // no segment at first
             assertEquals(0, cube.getSegments().size());
-
+            for (MeasureInstance m : getMeasureManager().getMeasuresInCube(cube.getProject(), cube.getName())) {
+                assertTrue(m.getSegmentsName().size() == 0);
+            }
             // append first
             CubeSegment seg1 = mgr.appendSegment(cube, new TSRange(0L, 1000L), null, null, null);
             mgr.updateCubeSegStatus(seg1, SegmentStatusEnum.READY);
@@ -119,10 +139,20 @@ public class CubeManagerTest extends LocalFileMetadataTestCase {
 
             cube = mgr.getCube(cube.getName());
             assertEquals(2, cube.getSegments().size());
+            for (MeasureInstance m : getMeasureManager().getMeasuresInCube(cube.getProject(), cube.getName())) {
+                assertEquals(2, m.getSegmentsName().size());
+            }
 
             SegmentRange mergedSeg = cube.autoMergeCubeSegments();
 
             assertTrue(mergedSeg != null);
+
+            for (MeasureInstance m : getMeasureManager().getMeasuresInCube(cube.getProject(), cube.getName())) {
+                assertEquals(1, m.getSegmentsName().size());
+                assertEquals(1, m.getDateTimeRanges().size());
+                assertTrue(0L == m.getSegments().get(0).getTSRange().start.v);
+                assertTrue(2000L == m.getSegments().get(0).getTSRange().end.v);
+            }
         }
     }
 
@@ -181,6 +211,13 @@ public class CubeManagerTest extends LocalFileMetadataTestCase {
         assertTrue(cube.getSegmentById(seg5.getUuid()) != null
                 && cube.getSegmentById(seg5.getUuid()).getStatus() == SegmentStatusEnum.READY);
 
+        for (MeasureInstance m : getMeasureManager().getMeasuresInCube(cube.getProject(), cube.getName())) {
+            assertTrue(m.getSegmentsName().size() == 4);
+            assertEquals(seg1.getName(), m.getSegments().get(0).getName());
+            assertEquals(seg2.getName(), m.getSegments().get(1).getName());
+            assertEquals(seg4.getName(), m.getSegments().get(2).getName());
+            assertEquals(seg5.getName(), m.getSegments().get(3).getName());
+        }
     }
 
     @Test
@@ -246,6 +283,12 @@ public class CubeManagerTest extends LocalFileMetadataTestCase {
         assertTrue(cube.getSegmentById(merge2.getUuid()) != null
                 && cube.getSegmentById(merge2.getUuid()).getStatus() == SegmentStatusEnum.NEW);
 
+        for (MeasureInstance m : getMeasureManager().getMeasuresInCube(cube.getProject(), cube.getName())) {
+            assertTrue(m.getSegmentsName().size() == 3);
+            assertEquals(merge1.getName(), m.getSegments().get(0).getName());
+            assertEquals(seg3.getName(), m.getSegments().get(1).getName());
+            assertEquals(seg4.getName(), m.getSegments().get(2).getName());
+        }
     }
 
     @Test
@@ -436,8 +479,29 @@ public class CubeManagerTest extends LocalFileMetadataTestCase {
         assertEquals(segment._getDateRangeEnd(), SECOND_BUILD_DATE_END.longValue());
     }
 
+    @Test
+    public void testDeleteSegment() throws IOException {
+        KylinConfig config = getTestConfig();
+        CubeManager cubeMgr = CubeManager.getInstance(config);
+
+        String cubeName = "test_kylin_cube_with_slr_ready_3_segments";
+
+        CubeInstance cube = cubeMgr.getCube(cubeName);
+        int segNumber = cube.getSegments().size();
+
+        CubeSegment toRemoveSeg = cube.getSegment("19691231160000_20131112000000", null);
+        cubeMgr.updateCubeDropSegments(cube, toRemoveSeg);
+
+        int newSegNumber = cubeMgr.getCube(cubeName).getSegments().size();
+
+        Assert.assertTrue(segNumber == newSegNumber + 1);
+    }
 
     public CubeDescManager getCubeDescManager() {
         return CubeDescManager.getInstance(getTestConfig());
     }
+
+    private MeasureManager getMeasureManager() {
+        return MeasureManager.getInstance(getTestConfig());
+    }
 }
diff --git a/core-cube/src/test/java/org/apache/kylin/measure/MeasureManagerTest.java b/core-cube/src/test/java/org/apache/kylin/measure/MeasureManagerTest.java
new file mode 100644
index 0000000..22a10f8
--- /dev/null
+++ b/core-cube/src/test/java/org/apache/kylin/measure/MeasureManagerTest.java
@@ -0,0 +1,205 @@
+/*
+ * 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.measure;
+
+import com.google.common.collect.Lists;
+import com.google.common.collect.Sets;
+import org.apache.kylin.common.persistence.ResourceTool;
+import org.apache.kylin.common.util.JsonUtil;
+import org.apache.kylin.common.util.LocalFileMetadataTestCase;
+import org.apache.kylin.cube.CubeDescManager;
+import org.apache.kylin.cube.CubeInstance;
+import org.apache.kylin.cube.CubeManager;
+import org.apache.kylin.cube.CubeSegment;
+import org.apache.kylin.cube.adapter.AbstractHBaseMappingAdapter;
+import org.apache.kylin.cube.model.CubeDesc;
+import org.apache.kylin.cube.model.HBaseMappingDesc;
+import org.apache.kylin.metadata.model.MeasureDesc;
+import org.apache.kylin.metadata.model.SegmentStatusEnum;
+import org.apache.log4j.BasicConfigurator;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.Arrays;
+import java.util.List;
+import java.util.Set;
+import java.util.stream.Collectors;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
+public class MeasureManagerTest extends LocalFileMetadataTestCase {
+    private static final String MEASURE_DATA_DIR = "../examples/test_case_data/measure/";
+    private static final String MEASURE_DATA_SUFFIX = ".json";
+
+    @Before
+    public void setUp() throws Exception {
+        BasicConfigurator.configure();
+        this.createTestMetadata();
+    }
+
+    @After
+    public void after() throws Exception {
+        this.cleanupTestMetadata();
+    }
+
+    @Test
+    public void testInitAllCube() throws IOException {
+        ResourceTool.main(new String[]{"remove", "/measure"});
+        MeasureManager.main(new String[]{"init", "all"});
+        // clear manager for reload
+        getTestConfig().clearManagers();
+
+        List<CubeInstance> allCubes = getCubeManager().listAllCubes();
+
+        for (CubeInstance cube : allCubes) {
+            Set<MeasureDesc> measureFromCubeDesc = Sets.newHashSet(cube.getMeasures());
+            Set<MeasureDesc> measureFromCache = getMeasureManager()
+                    .getMeasuresInCube(cube.getProject(), cube.getName())
+                    .stream()
+                    .map(m -> m.getMeasureDesc())
+                    .collect(Collectors.toSet());
+            assertEquals(measureFromCubeDesc, measureFromCache);
+        }
+    }
+
+    @Test
+    public void testAddMeasureOnNewCube() throws IOException {
+        String newCubeName = "ci_inner_join_cube";
+        CubeInstance cubeInstance = getCubeManager().getCube(newCubeName);
+        CubeDesc cubeDesc = cubeInstance.getDescriptor();
+        MeasureDesc newMeasure = getMAX_SELLER_ID();
+        CubeDesc updatedCubeDesc = addMeasure(cubeDesc, newMeasure);
+        getCubeDescManager().updateCubeDesc(updatedCubeDesc);
+        List<MeasureInstance> measuresInsInCube = getMeasureManager().getMeasuresInCube(cubeInstance.getProject(), cubeInstance.getName());
+        List<MeasureDesc> measuresInCube = measuresInsInCube
+                .stream()
+                .map(m -> m.getMeasureDesc())
+                .collect(Collectors.toList());
+        assertTrue(measuresInCube.contains(newMeasure));
+
+        measuresInsInCube.forEach(m -> assertTrue(m.getKey() + " has some segments: " + m.getSegmentsName(), m.getSegments().size() == 0));
+    }
+
+    @Test
+    public void testDeleteMeasureOnNewCube() throws IOException {
+        String newCubeName = "ci_inner_join_cube";
+        CubeInstance cubeInstance = getCubeManager().getCube(newCubeName);
+        CubeDesc cubeDesc = cubeInstance.getDescriptor();
+        MeasureDesc needDeleteMeasure = cubeDesc.getMeasures().get(cubeDesc.getMeasures().size() >> 1);
+        CubeDesc updatedCubeDesc = deleteMeasure(cubeDesc, needDeleteMeasure);
+        getCubeDescManager().updateCubeDesc(updatedCubeDesc);
+        List<MeasureInstance> measuresInsInCube = getMeasureManager().getMeasuresInCube(cubeInstance.getProject(), cubeInstance.getName());
+        List<MeasureDesc> measuresInCube = measuresInsInCube
+                .stream()
+                .map(m -> m.getMeasureDesc())
+                .collect(Collectors.toList());
+        assertTrue(!measuresInCube.contains(needDeleteMeasure));
+    }
+
+
+
+    @Test
+    public void testAddMeasureOnBuiltCube() throws IOException {
+        CubeInstance cubeInstance = getCubeManager().getCube("test_kylin_cube_with_slr_ready_2_segments");
+
+        List<MeasureInstance> measuresInsInCubeBeforeAdd = getMeasureManager().getMeasuresInCube(cubeInstance.getProject(), cubeInstance.getName());
+
+        measuresInsInCubeBeforeAdd.forEach(m -> assertTrue(m.getSegments().size() == cubeInstance.getSegments(SegmentStatusEnum.READY).size()));
+
+        CubeDesc cubeDesc = cubeInstance.getDescriptor();
+        MeasureDesc newMeasure = getMAX_SELLER_ID();
+        CubeDesc updatedCubeDesc = addMeasure(cubeDesc, newMeasure);
+        getCubeDescManager().updateCubeDesc(updatedCubeDesc);
+
+        List<MeasureInstance> measuresInsInCubeAfterAdd = getMeasureManager().getMeasuresInCube(cubeInstance.getProject(), cubeInstance.getName());
+        List<MeasureDesc> measuresInCube = measuresInsInCubeAfterAdd
+                .stream()
+                .map(m -> m.getMeasureDesc())
+                .collect(Collectors.toList());
+        assertTrue(measuresInCube.contains(newMeasure));
+
+        for (MeasureInstance m : measuresInsInCubeAfterAdd) {
+            if (m.getName().equals(newMeasure.getName())) {
+
+                assertTrue(m.getSegments().size() == 0);
+            } else {
+                assertTrue(m.getSegments().size() == cubeInstance.getSegments(SegmentStatusEnum.READY).size());
+            }
+        }
+    }
+
+    @Test
+    public void testGetMeasureAfterDropSegment() throws IOException {
+        getMeasureManager();
+        CubeInstance cubeInstance = getCubeManager().getCube("test_kylin_cube_with_slr_ready_3_segments");
+        CubeSegment firstSegment = cubeInstance.getFirstSegment();
+        CubeInstance cubeAfterDelete = getCubeManager().updateCubeDropSegments(cubeInstance, firstSegment);
+
+        List<MeasureInstance> measuresInCube = getMeasureManager().getMeasuresInCube(cubeInstance.getProject(), cubeInstance.getName());
+        for (MeasureInstance m : measuresInCube) {
+            assertTrue(m.getSegments().size() == cubeAfterDelete.getSegments(SegmentStatusEnum.READY).size());
+            assertTrue(!m.getSegments().contains(firstSegment));
+        }
+    }
+
+    private CubeDescManager getCubeDescManager() {
+        return CubeDescManager.getInstance(getTestConfig());
+    }
+
+    private CubeManager getCubeManager() {
+        return CubeManager.getInstance(getTestConfig());
+    }
+
+    public MeasureDesc getMAX_SELLER_ID() {
+        return parseMeasureData("MAX_SELLER_ID");
+    }
+
+    private MeasureDesc parseMeasureData(String path) {
+        File file = new File(MEASURE_DATA_DIR + path + MEASURE_DATA_SUFFIX);
+        try {
+            return JsonUtil.readValue(file, MeasureDesc.class);
+        } catch (IOException e) {
+            throw new IllegalArgumentException(e);
+        }
+    }
+
+    private CubeDesc addMeasure(CubeDesc cubeDesc, MeasureDesc needAdd) {
+        List<MeasureDesc> measures = Lists.newArrayList(cubeDesc.getMeasures());
+        measures.add(needAdd);
+        cubeDesc.setMeasures(measures);
+        HBaseMappingDesc hBaseMappingDesc = AbstractHBaseMappingAdapter.getHBaseAdapter(getTestConfig()).addMeasure(cubeDesc, Arrays.asList(needAdd.getName()));
+        cubeDesc.setHbaseMapping(hBaseMappingDesc);
+        return cubeDesc;
+    }
+    private CubeDesc deleteMeasure(CubeDesc cubeDesc, MeasureDesc needDeleteMeasure) {
+        List<MeasureDesc> newMeasures = Lists.newArrayList(cubeDesc.getMeasures());
+        newMeasures.remove(needDeleteMeasure);
+        cubeDesc.setMeasures(newMeasures);
+        HBaseMappingDesc hBaseMappingDesc = AbstractHBaseMappingAdapter.getHBaseAdapter(getTestConfig()).getHBaseMappingOnlyOnce(cubeDesc);
+        cubeDesc.setHbaseMapping(hBaseMappingDesc);
+        return cubeDesc;
+    }
+    private MeasureManager getMeasureManager() {
+        return MeasureManager.getInstance(getTestConfig());
+    }
+}
diff --git a/core-metadata/src/main/java/org/apache/kylin/metadata/model/DateTimeRange.java b/core-metadata/src/main/java/org/apache/kylin/metadata/model/DateTimeRange.java
new file mode 100644
index 0000000..ac80454
--- /dev/null
+++ b/core-metadata/src/main/java/org/apache/kylin/metadata/model/DateTimeRange.java
@@ -0,0 +1,46 @@
+/*
+ * 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.metadata.model;
+
+import java.time.Instant;
+import java.time.LocalDateTime;
+import java.time.ZoneId;
+
+public class DateTimeRange extends SegmentRange<LocalDateTime> {
+
+    public static DateTimeRange create(long s, long e) {
+        return new DateTimeRange(getDateTimeOfTimestamp(s), getDateTimeOfTimestamp(e));
+    }
+
+    public DateTimeRange(LocalDateTime start, LocalDateTime end) {
+        super(start, end);
+    }
+
+    @Override
+    public String toString() {
+        return "[" + this.start.v.toString() + ", " + this.end.v.toString() + ")";
+    }
+
+
+    public static LocalDateTime getDateTimeOfTimestamp(long timestamp) {
+        Instant instant = Instant.ofEpochMilli(timestamp);
+        ZoneId zone = ZoneId.of("GMT");
+        return LocalDateTime.ofInstant(instant, zone);
+    }
+}
diff --git a/examples/sample_cube/template/measure/kylin_sales_cube/BUYER_LEVEL_SUM.json b/examples/sample_cube/template/measure/kylin_sales_cube/BUYER_LEVEL_SUM.json
new file mode 100644
index 0000000..c04c7d9
--- /dev/null
+++ b/examples/sample_cube/template/measure/kylin_sales_cube/BUYER_LEVEL_SUM.json
@@ -0,0 +1,9 @@
+{
+  "uuid" : "4f099a83-1e14-702a-3756-cbab09740bd6",
+  "last_modified" : 1557191165660,
+  "version" : "2.6.0.20500",
+  "name" : "BUYER_LEVEL_SUM",
+  "cube_name" : "kylin_sales_cube",
+  "segments_name" : [ ],
+  "online" : true
+}
\ No newline at end of file
diff --git a/examples/sample_cube/template/measure/kylin_sales_cube/GMV_SUM.json b/examples/sample_cube/template/measure/kylin_sales_cube/GMV_SUM.json
new file mode 100644
index 0000000..7ba763f
--- /dev/null
+++ b/examples/sample_cube/template/measure/kylin_sales_cube/GMV_SUM.json
@@ -0,0 +1,9 @@
+{
+  "uuid" : "16490392-e3c9-5ea6-cddd-057e4ab15f9d",
+  "last_modified" : 1557191165614,
+  "version" : "2.6.0.20500",
+  "name" : "GMV_SUM",
+  "cube_name" : "kylin_sales_cube",
+  "segments_name" : [ ],
+  "online" : true
+}
\ No newline at end of file
diff --git a/examples/sample_cube/template/measure/kylin_sales_cube/SELLER_CNT_HLL.json b/examples/sample_cube/template/measure/kylin_sales_cube/SELLER_CNT_HLL.json
new file mode 100644
index 0000000..f74d9be
--- /dev/null
+++ b/examples/sample_cube/template/measure/kylin_sales_cube/SELLER_CNT_HLL.json
@@ -0,0 +1,9 @@
+{
+  "uuid" : "801ef9c6-4638-bde7-0859-804e1438611c",
+  "last_modified" : 1557191165670,
+  "version" : "2.6.0.20500",
+  "name" : "SELLER_CNT_HLL",
+  "cube_name" : "kylin_sales_cube",
+  "segments_name" : [ ],
+  "online" : true
+}
\ No newline at end of file
diff --git a/examples/sample_cube/template/measure/kylin_sales_cube/SELLER_LEVEL_SUM.json b/examples/sample_cube/template/measure/kylin_sales_cube/SELLER_LEVEL_SUM.json
new file mode 100644
index 0000000..7bb12ac
--- /dev/null
+++ b/examples/sample_cube/template/measure/kylin_sales_cube/SELLER_LEVEL_SUM.json
@@ -0,0 +1,9 @@
+{
+  "uuid" : "bbd71a34-ccdd-1cc8-4d0e-770830a48e6d",
+  "last_modified" : 1557191165663,
+  "version" : "2.6.0.20500",
+  "name" : "SELLER_LEVEL_SUM",
+  "cube_name" : "kylin_sales_cube",
+  "segments_name" : [ ],
+  "online" : true
+}
\ No newline at end of file
diff --git a/examples/sample_cube/template/measure/kylin_sales_cube/TOP_SELLER.json b/examples/sample_cube/template/measure/kylin_sales_cube/TOP_SELLER.json
new file mode 100644
index 0000000..03507b5
--- /dev/null
+++ b/examples/sample_cube/template/measure/kylin_sales_cube/TOP_SELLER.json
@@ -0,0 +1,9 @@
+{
+  "uuid" : "14204832-c61f-aa22-43c7-5212b90dbd06",
+  "last_modified" : 1557191165673,
+  "version" : "2.6.0.20500",
+  "name" : "TOP_SELLER",
+  "cube_name" : "kylin_sales_cube",
+  "segments_name" : [ ],
+  "online" : true
+}
\ No newline at end of file
diff --git a/examples/sample_cube/template/measure/kylin_sales_cube/TRANS_CNT.json b/examples/sample_cube/template/measure/kylin_sales_cube/TRANS_CNT.json
new file mode 100644
index 0000000..9af7ba0
--- /dev/null
+++ b/examples/sample_cube/template/measure/kylin_sales_cube/TRANS_CNT.json
@@ -0,0 +1,9 @@
+{
+  "uuid" : "5c2759c1-128c-7c27-c36b-4826a459ab04",
+  "last_modified" : 1557191165667,
+  "version" : "2.6.0.20500",
+  "name" : "TRANS_CNT",
+  "cube_name" : "kylin_sales_cube",
+  "segments_name" : [ ],
+  "online" : true
+}
\ No newline at end of file
diff --git a/examples/sample_cube/template/measure/kylin_streaming_cube/TOTAL_AMOUNT.json b/examples/sample_cube/template/measure/kylin_streaming_cube/TOTAL_AMOUNT.json
new file mode 100644
index 0000000..ba8a751
--- /dev/null
+++ b/examples/sample_cube/template/measure/kylin_streaming_cube/TOTAL_AMOUNT.json
@@ -0,0 +1,9 @@
+{
+  "uuid" : "c804c0e9-d1c5-c677-e324-bc4d1fbba074",
+  "last_modified" : 1557191165679,
+  "version" : "2.6.0.20500",
+  "name" : "TOTAL_AMOUNT",
+  "cube_name" : "kylin_streaming_cube",
+  "segments_name" : [ ],
+  "online" : true
+}
\ No newline at end of file
diff --git a/examples/sample_cube/template/measure/kylin_streaming_cube/TOTAL_QTY.json b/examples/sample_cube/template/measure/kylin_streaming_cube/TOTAL_QTY.json
new file mode 100644
index 0000000..f93ff8e
--- /dev/null
+++ b/examples/sample_cube/template/measure/kylin_streaming_cube/TOTAL_QTY.json
@@ -0,0 +1,9 @@
+{
+  "uuid" : "849e959f-437b-c717-b159-d5df97ecb354",
+  "last_modified" : 1557191165682,
+  "version" : "2.6.0.20500",
+  "name" : "TOTAL_QTY",
+  "cube_name" : "kylin_streaming_cube",
+  "segments_name" : [ ],
+  "online" : true
+}
\ No newline at end of file
diff --git a/examples/sample_cube/template/measure/kylin_streaming_cube/_COUNT_.json b/examples/sample_cube/template/measure/kylin_streaming_cube/_COUNT_.json
new file mode 100644
index 0000000..20b5b13
--- /dev/null
+++ b/examples/sample_cube/template/measure/kylin_streaming_cube/_COUNT_.json
@@ -0,0 +1,9 @@
+{
+  "uuid" : "d1538137-528f-c7e7-5038-fca89dd0f268",
+  "last_modified" : 1557191165676,
+  "version" : "2.6.0.20500",
+  "name" : "_COUNT_",
+  "cube_name" : "kylin_streaming_cube",
+  "segments_name" : [ ],
+  "online" : true
+}
\ No newline at end of file
diff --git a/examples/test_case_data/localmeta/measure/ci_inner_join_cube/BUYER_CONTACT.json b/examples/test_case_data/localmeta/measure/ci_inner_join_cube/BUYER_CONTACT.json
new file mode 100644
index 0000000..9fee10d
--- /dev/null
+++ b/examples/test_case_data/localmeta/measure/ci_inner_join_cube/BUYER_CONTACT.json
@@ -0,0 +1,9 @@
+{
+  "uuid" : "21ed4daf-6bd6-f49c-4e14-a0e92849128e",
+  "last_modified" : 1556584529151,
+  "version" : "2.6.0.20500",
+  "name" : "BUYER_CONTACT",
+  "cube_name" : "ci_inner_join_cube",
+  "segments_name" : [ ],
+  "online" : true
+}
\ No newline at end of file
diff --git a/examples/test_case_data/localmeta/measure/ci_inner_join_cube/CAL_DT_RAW.json b/examples/test_case_data/localmeta/measure/ci_inner_join_cube/CAL_DT_RAW.json
new file mode 100644
index 0000000..5eb1fdd
--- /dev/null
+++ b/examples/test_case_data/localmeta/measure/ci_inner_join_cube/CAL_DT_RAW.json
@@ -0,0 +1,9 @@
+{
+  "uuid" : "de1be29e-58d1-f840-3aff-f75496c74e86",
+  "last_modified" : 1556584529163,
+  "version" : "2.6.0.20500",
+  "name" : "CAL_DT_RAW",
+  "cube_name" : "ci_inner_join_cube",
+  "segments_name" : [ ],
+  "online" : true
+}
\ No newline at end of file
diff --git a/examples/test_case_data/localmeta/measure/ci_inner_join_cube/GMV_CNT.json b/examples/test_case_data/localmeta/measure/ci_inner_join_cube/GMV_CNT.json
new file mode 100644
index 0000000..16d883a
--- /dev/null
+++ b/examples/test_case_data/localmeta/measure/ci_inner_join_cube/GMV_CNT.json
@@ -0,0 +1,9 @@
+{
+  "uuid" : "68425d58-a998-ae29-e9be-e477b02d6304",
+  "last_modified" : 1556584529127,
+  "version" : "2.6.0.20500",
+  "name" : "GMV_CNT",
+  "cube_name" : "ci_inner_join_cube",
+  "segments_name" : [ ],
+  "online" : true
+}
\ No newline at end of file
diff --git a/examples/test_case_data/localmeta/measure/ci_inner_join_cube/GMV_MAX.json b/examples/test_case_data/localmeta/measure/ci_inner_join_cube/GMV_MAX.json
new file mode 100644
index 0000000..4bb5333
--- /dev/null
+++ b/examples/test_case_data/localmeta/measure/ci_inner_join_cube/GMV_MAX.json
@@ -0,0 +1,9 @@
+{
+  "uuid" : "04deb300-6356-aaf4-f9e4-6d9a44837a54",
+  "last_modified" : 1556584529134,
+  "version" : "2.6.0.20500",
+  "name" : "GMV_MAX",
+  "cube_name" : "ci_inner_join_cube",
+  "segments_name" : [ ],
+  "online" : true
+}
\ No newline at end of file
diff --git a/examples/test_case_data/localmeta/measure/ci_inner_join_cube/GMV_MIN.json b/examples/test_case_data/localmeta/measure/ci_inner_join_cube/GMV_MIN.json
new file mode 100644
index 0000000..7eafc62
--- /dev/null
+++ b/examples/test_case_data/localmeta/measure/ci_inner_join_cube/GMV_MIN.json
@@ -0,0 +1,9 @@
+{
+  "uuid" : "c61ea582-0a33-77b8-35e0-cdefdec3b628",
+  "last_modified" : 1556584529130,
+  "version" : "2.6.0.20500",
+  "name" : "GMV_MIN",
+  "cube_name" : "ci_inner_join_cube",
+  "segments_name" : [ ],
+  "online" : true
+}
\ No newline at end of file
diff --git a/examples/test_case_data/localmeta/measure/ci_inner_join_cube/GMV_SUM.json b/examples/test_case_data/localmeta/measure/ci_inner_join_cube/GMV_SUM.json
new file mode 100644
index 0000000..babf89f
--- /dev/null
+++ b/examples/test_case_data/localmeta/measure/ci_inner_join_cube/GMV_SUM.json
@@ -0,0 +1,9 @@
+{
+  "uuid" : "9975eb29-5e44-2f63-295e-915ab8f6c959",
+  "last_modified" : 1556584529124,
+  "version" : "2.6.0.20500",
+  "name" : "GMV_SUM",
+  "cube_name" : "ci_inner_join_cube",
+  "segments_name" : [ ],
+  "online" : true
+}
\ No newline at end of file
diff --git a/examples/test_case_data/localmeta/measure/ci_inner_join_cube/ITEM_COUNT_SUM.json b/examples/test_case_data/localmeta/measure/ci_inner_join_cube/ITEM_COUNT_SUM.json
new file mode 100644
index 0000000..7a80c80
--- /dev/null
+++ b/examples/test_case_data/localmeta/measure/ci_inner_join_cube/ITEM_COUNT_SUM.json
@@ -0,0 +1,9 @@
+{
+  "uuid" : "91f1823c-2811-03a5-2538-632c2f0fd359",
+  "last_modified" : 1556584529121,
+  "version" : "2.6.0.20500",
+  "name" : "ITEM_COUNT_SUM",
+  "cube_name" : "ci_inner_join_cube",
+  "segments_name" : [ ],
+  "online" : true
+}
\ No newline at end of file
diff --git a/examples/test_case_data/localmeta/measure/ci_inner_join_cube/PRICE_RAW.json b/examples/test_case_data/localmeta/measure/ci_inner_join_cube/PRICE_RAW.json
new file mode 100644
index 0000000..da83461
--- /dev/null
+++ b/examples/test_case_data/localmeta/measure/ci_inner_join_cube/PRICE_RAW.json
@@ -0,0 +1,9 @@
+{
+  "uuid" : "85ec8895-5116-d0aa-aadb-d4134cb864ef",
+  "last_modified" : 1556584529160,
+  "version" : "2.6.0.20500",
+  "name" : "PRICE_RAW",
+  "cube_name" : "ci_inner_join_cube",
+  "segments_name" : [ ],
+  "online" : true
+}
\ No newline at end of file
diff --git a/examples/test_case_data/localmeta/measure/ci_inner_join_cube/SELLER_CONTACT.json b/examples/test_case_data/localmeta/measure/ci_inner_join_cube/SELLER_CONTACT.json
new file mode 100644
index 0000000..9972df0
--- /dev/null
+++ b/examples/test_case_data/localmeta/measure/ci_inner_join_cube/SELLER_CONTACT.json
@@ -0,0 +1,9 @@
+{
+  "uuid" : "728fac74-796a-617b-3e02-7225d26ee260",
+  "last_modified" : 1556584529154,
+  "version" : "2.6.0.20500",
+  "name" : "SELLER_CONTACT",
+  "cube_name" : "ci_inner_join_cube",
+  "segments_name" : [ ],
+  "online" : true
+}
\ No newline at end of file
diff --git a/examples/test_case_data/localmeta/measure/ci_inner_join_cube/SELLER_FORMAT_HLL.json b/examples/test_case_data/localmeta/measure/ci_inner_join_cube/SELLER_FORMAT_HLL.json
new file mode 100644
index 0000000..cb72ad7
--- /dev/null
+++ b/examples/test_case_data/localmeta/measure/ci_inner_join_cube/SELLER_FORMAT_HLL.json
@@ -0,0 +1,9 @@
+{
+  "uuid" : "26142ef0-72b2-7566-9704-67dd05c33e78",
+  "last_modified" : 1556584529140,
+  "version" : "2.6.0.20500",
+  "name" : "SELLER_FORMAT_HLL",
+  "cube_name" : "ci_inner_join_cube",
+  "segments_name" : [ ],
+  "online" : true
+}
\ No newline at end of file
diff --git a/examples/test_case_data/localmeta/measure/ci_inner_join_cube/SELLER_HLL.json b/examples/test_case_data/localmeta/measure/ci_inner_join_cube/SELLER_HLL.json
new file mode 100644
index 0000000..e75b5a2
--- /dev/null
+++ b/examples/test_case_data/localmeta/measure/ci_inner_join_cube/SELLER_HLL.json
@@ -0,0 +1,9 @@
+{
+  "uuid" : "68829a34-9a79-9c3a-5bcc-6c87a4b6f987",
+  "last_modified" : 1556584529137,
+  "version" : "2.6.0.20500",
+  "name" : "SELLER_HLL",
+  "cube_name" : "ci_inner_join_cube",
+  "segments_name" : [ ],
+  "online" : true
+}
\ No newline at end of file
diff --git a/examples/test_case_data/localmeta/measure/ci_inner_join_cube/TEST_COUNT_COLUMN_CNT.json b/examples/test_case_data/localmeta/measure/ci_inner_join_cube/TEST_COUNT_COLUMN_CNT.json
new file mode 100644
index 0000000..b5384aa
--- /dev/null
+++ b/examples/test_case_data/localmeta/measure/ci_inner_join_cube/TEST_COUNT_COLUMN_CNT.json
@@ -0,0 +1,9 @@
+{
+  "uuid" : "5ba87fd0-0584-e754-c1c6-63ef37e45b5a",
+  "last_modified" : 1556584529166,
+  "version" : "2.6.0.20500",
+  "name" : "TEST_COUNT_COLUMN_CNT",
+  "cube_name" : "ci_inner_join_cube",
+  "segments_name" : [ ],
+  "online" : true
+}
\ No newline at end of file
diff --git a/examples/test_case_data/localmeta/measure/ci_inner_join_cube/TEST_COUNT_DISTINCT_BITMAP.json b/examples/test_case_data/localmeta/measure/ci_inner_join_cube/TEST_COUNT_DISTINCT_BITMAP.json
new file mode 100644
index 0000000..d08bd06
--- /dev/null
+++ b/examples/test_case_data/localmeta/measure/ci_inner_join_cube/TEST_COUNT_DISTINCT_BITMAP.json
@@ -0,0 +1,9 @@
+{
+  "uuid" : "05133092-a741-6727-d39a-8e516b1d18a2",
+  "last_modified" : 1556584529145,
+  "version" : "2.6.0.20500",
+  "name" : "TEST_COUNT_DISTINCT_BITMAP",
+  "cube_name" : "ci_inner_join_cube",
+  "segments_name" : [ ],
+  "online" : true
+}
\ No newline at end of file
diff --git a/examples/test_case_data/localmeta/measure/ci_inner_join_cube/TEST_EXTENDED_COLUMN.json b/examples/test_case_data/localmeta/measure/ci_inner_join_cube/TEST_EXTENDED_COLUMN.json
new file mode 100644
index 0000000..dede53d
--- /dev/null
+++ b/examples/test_case_data/localmeta/measure/ci_inner_join_cube/TEST_EXTENDED_COLUMN.json
@@ -0,0 +1,9 @@
+{
+  "uuid" : "4728882d-5def-9245-7906-a3f32c67f1a0",
+  "last_modified" : 1556584529149,
+  "version" : "2.6.0.20500",
+  "name" : "TEST_EXTENDED_COLUMN",
+  "cube_name" : "ci_inner_join_cube",
+  "segments_name" : [ ],
+  "online" : true
+}
\ No newline at end of file
diff --git a/examples/test_case_data/localmeta/measure/ci_inner_join_cube/TOP_SELLER.json b/examples/test_case_data/localmeta/measure/ci_inner_join_cube/TOP_SELLER.json
new file mode 100644
index 0000000..da65103
--- /dev/null
+++ b/examples/test_case_data/localmeta/measure/ci_inner_join_cube/TOP_SELLER.json
@@ -0,0 +1,9 @@
+{
+  "uuid" : "859659a1-706a-006a-e5e3-b4807341a883",
+  "last_modified" : 1556584529142,
+  "version" : "2.6.0.20500",
+  "name" : "TOP_SELLER",
+  "cube_name" : "ci_inner_join_cube",
+  "segments_name" : [ ],
+  "online" : true
+}
\ No newline at end of file
diff --git a/examples/test_case_data/localmeta/measure/ci_inner_join_cube/TRANS_CNT.json b/examples/test_case_data/localmeta/measure/ci_inner_join_cube/TRANS_CNT.json
new file mode 100644
index 0000000..27c28d5
--- /dev/null
+++ b/examples/test_case_data/localmeta/measure/ci_inner_join_cube/TRANS_CNT.json
@@ -0,0 +1,9 @@
+{
+  "uuid" : "fc662172-4939-f075-c712-04b8ddebe366",
+  "last_modified" : 1556584529083,
+  "version" : "2.6.0.20500",
+  "name" : "TRANS_CNT",
+  "cube_name" : "ci_inner_join_cube",
+  "segments_name" : [ ],
+  "online" : true
+}
\ No newline at end of file
diff --git a/examples/test_case_data/localmeta/measure/ci_inner_join_cube/TRANS_ID_RAW.json b/examples/test_case_data/localmeta/measure/ci_inner_join_cube/TRANS_ID_RAW.json
new file mode 100644
index 0000000..bd841ba
--- /dev/null
+++ b/examples/test_case_data/localmeta/measure/ci_inner_join_cube/TRANS_ID_RAW.json
@@ -0,0 +1,9 @@
+{
+  "uuid" : "3bf11317-348b-59ab-61bb-ba887a841ee8",
+  "last_modified" : 1556584529157,
+  "version" : "2.6.0.20500",
+  "name" : "TRANS_ID_RAW",
+  "cube_name" : "ci_inner_join_cube",
+  "segments_name" : [ ],
+  "online" : true
+}
\ No newline at end of file
diff --git a/examples/test_case_data/localmeta/measure/ci_left_join_cube/BUYER_CONTACT.json b/examples/test_case_data/localmeta/measure/ci_left_join_cube/BUYER_CONTACT.json
new file mode 100644
index 0000000..370e2ab
--- /dev/null
+++ b/examples/test_case_data/localmeta/measure/ci_left_join_cube/BUYER_CONTACT.json
@@ -0,0 +1,9 @@
+{
+  "uuid" : "92da77d8-ff90-c328-7617-6d812391b3ec",
+  "last_modified" : 1556584529202,
+  "version" : "2.6.0.20500",
+  "name" : "BUYER_CONTACT",
+  "cube_name" : "ci_left_join_cube",
+  "segments_name" : [ ],
+  "online" : true
+}
\ No newline at end of file
diff --git a/examples/test_case_data/localmeta/measure/ci_left_join_cube/CAL_DT_RAW.json b/examples/test_case_data/localmeta/measure/ci_left_join_cube/CAL_DT_RAW.json
new file mode 100644
index 0000000..5e14386
--- /dev/null
+++ b/examples/test_case_data/localmeta/measure/ci_left_join_cube/CAL_DT_RAW.json
@@ -0,0 +1,9 @@
+{
+  "uuid" : "b810c89f-a494-74f0-fdb6-fb3c7bae9d88",
+  "last_modified" : 1556584529213,
+  "version" : "2.6.0.20500",
+  "name" : "CAL_DT_RAW",
+  "cube_name" : "ci_left_join_cube",
+  "segments_name" : [ ],
+  "online" : true
+}
\ No newline at end of file
diff --git a/examples/test_case_data/localmeta/measure/ci_left_join_cube/GMV_CNT.json b/examples/test_case_data/localmeta/measure/ci_left_join_cube/GMV_CNT.json
new file mode 100644
index 0000000..0235f18
--- /dev/null
+++ b/examples/test_case_data/localmeta/measure/ci_left_join_cube/GMV_CNT.json
@@ -0,0 +1,9 @@
+{
+  "uuid" : "238e8d62-fed2-0f28-b059-d7ae49e29f29",
+  "last_modified" : 1556584529178,
+  "version" : "2.6.0.20500",
+  "name" : "GMV_CNT",
+  "cube_name" : "ci_left_join_cube",
+  "segments_name" : [ ],
+  "online" : true
+}
\ No newline at end of file
diff --git a/examples/test_case_data/localmeta/measure/ci_left_join_cube/GMV_MAX.json b/examples/test_case_data/localmeta/measure/ci_left_join_cube/GMV_MAX.json
new file mode 100644
index 0000000..06ee157
--- /dev/null
+++ b/examples/test_case_data/localmeta/measure/ci_left_join_cube/GMV_MAX.json
@@ -0,0 +1,9 @@
+{
+  "uuid" : "6d4981d1-78d1-ed88-4bee-984cc6194b6c",
+  "last_modified" : 1556584529184,
+  "version" : "2.6.0.20500",
+  "name" : "GMV_MAX",
+  "cube_name" : "ci_left_join_cube",
+  "segments_name" : [ ],
+  "online" : true
+}
\ No newline at end of file
diff --git a/examples/test_case_data/localmeta/measure/ci_left_join_cube/GMV_MIN.json b/examples/test_case_data/localmeta/measure/ci_left_join_cube/GMV_MIN.json
new file mode 100644
index 0000000..416657a
--- /dev/null
+++ b/examples/test_case_data/localmeta/measure/ci_left_join_cube/GMV_MIN.json
@@ -0,0 +1,9 @@
+{
+  "uuid" : "f6fc1c8b-cbb5-2b30-39c8-e3a504ef5dfc",
+  "last_modified" : 1556584529181,
+  "version" : "2.6.0.20500",
+  "name" : "GMV_MIN",
+  "cube_name" : "ci_left_join_cube",
+  "segments_name" : [ ],
+  "online" : true
+}
\ No newline at end of file
diff --git a/examples/test_case_data/localmeta/measure/ci_left_join_cube/GMV_SUM.json b/examples/test_case_data/localmeta/measure/ci_left_join_cube/GMV_SUM.json
new file mode 100644
index 0000000..328cfa2
--- /dev/null
+++ b/examples/test_case_data/localmeta/measure/ci_left_join_cube/GMV_SUM.json
@@ -0,0 +1,9 @@
+{
+  "uuid" : "94f5e426-9f6c-0fd4-fc63-cb0bc560c1e8",
+  "last_modified" : 1556584529175,
+  "version" : "2.6.0.20500",
+  "name" : "GMV_SUM",
+  "cube_name" : "ci_left_join_cube",
+  "segments_name" : [ ],
+  "online" : true
+}
\ No newline at end of file
diff --git a/examples/test_case_data/localmeta/measure/ci_left_join_cube/GVM_PERCENTILE.json b/examples/test_case_data/localmeta/measure/ci_left_join_cube/GVM_PERCENTILE.json
new file mode 100644
index 0000000..d3dddc2
--- /dev/null
+++ b/examples/test_case_data/localmeta/measure/ci_left_join_cube/GVM_PERCENTILE.json
@@ -0,0 +1,9 @@
+{
+  "uuid" : "f3206098-1a23-bb7a-e129-e4c7074a9900",
+  "last_modified" : 1556584529216,
+  "version" : "2.6.0.20500",
+  "name" : "GVM_PERCENTILE",
+  "cube_name" : "ci_left_join_cube",
+  "segments_name" : [ ],
+  "online" : true
+}
\ No newline at end of file
diff --git a/examples/test_case_data/localmeta/measure/ci_left_join_cube/ITEM_COUNT_SUM.json b/examples/test_case_data/localmeta/measure/ci_left_join_cube/ITEM_COUNT_SUM.json
new file mode 100644
index 0000000..6947271
--- /dev/null
+++ b/examples/test_case_data/localmeta/measure/ci_left_join_cube/ITEM_COUNT_SUM.json
@@ -0,0 +1,9 @@
+{
+  "uuid" : "0957c61f-e1e8-bbc0-dadc-8b9f191bb140",
+  "last_modified" : 1556584529172,
+  "version" : "2.6.0.20500",
+  "name" : "ITEM_COUNT_SUM",
+  "cube_name" : "ci_left_join_cube",
+  "segments_name" : [ ],
+  "online" : true
+}
\ No newline at end of file
diff --git a/examples/test_case_data/localmeta/measure/ci_left_join_cube/PRICE_RAW.json b/examples/test_case_data/localmeta/measure/ci_left_join_cube/PRICE_RAW.json
new file mode 100644
index 0000000..7c78b8f
--- /dev/null
+++ b/examples/test_case_data/localmeta/measure/ci_left_join_cube/PRICE_RAW.json
@@ -0,0 +1,9 @@
+{
+  "uuid" : "d300ebdb-c9da-b0a5-d900-cca205cfd134",
+  "last_modified" : 1556584529210,
+  "version" : "2.6.0.20500",
+  "name" : "PRICE_RAW",
+  "cube_name" : "ci_left_join_cube",
+  "segments_name" : [ ],
+  "online" : true
+}
\ No newline at end of file
diff --git a/examples/test_case_data/localmeta/measure/ci_left_join_cube/SELLER_CONTACT.json b/examples/test_case_data/localmeta/measure/ci_left_join_cube/SELLER_CONTACT.json
new file mode 100644
index 0000000..d6e60ed
--- /dev/null
+++ b/examples/test_case_data/localmeta/measure/ci_left_join_cube/SELLER_CONTACT.json
@@ -0,0 +1,9 @@
+{
+  "uuid" : "1c8e1ebd-855b-8d5e-1b60-6da269e11605",
+  "last_modified" : 1556584529204,
+  "version" : "2.6.0.20500",
+  "name" : "SELLER_CONTACT",
+  "cube_name" : "ci_left_join_cube",
+  "segments_name" : [ ],
+  "online" : true
+}
\ No newline at end of file
diff --git a/examples/test_case_data/localmeta/measure/ci_left_join_cube/SELLER_FORMAT_HLL.json b/examples/test_case_data/localmeta/measure/ci_left_join_cube/SELLER_FORMAT_HLL.json
new file mode 100644
index 0000000..c4c99f8
--- /dev/null
+++ b/examples/test_case_data/localmeta/measure/ci_left_join_cube/SELLER_FORMAT_HLL.json
@@ -0,0 +1,9 @@
+{
+  "uuid" : "de21a5a6-5029-4fbb-81e5-cb77a9452806",
+  "last_modified" : 1556584529190,
+  "version" : "2.6.0.20500",
+  "name" : "SELLER_FORMAT_HLL",
+  "cube_name" : "ci_left_join_cube",
+  "segments_name" : [ ],
+  "online" : true
+}
\ No newline at end of file
diff --git a/examples/test_case_data/localmeta/measure/ci_left_join_cube/SELLER_HLL.json b/examples/test_case_data/localmeta/measure/ci_left_join_cube/SELLER_HLL.json
new file mode 100644
index 0000000..1108370
--- /dev/null
+++ b/examples/test_case_data/localmeta/measure/ci_left_join_cube/SELLER_HLL.json
@@ -0,0 +1,9 @@
+{
+  "uuid" : "1a1ecc38-451b-464f-b54b-5d989b4d469d",
+  "last_modified" : 1556584529187,
+  "version" : "2.6.0.20500",
+  "name" : "SELLER_HLL",
+  "cube_name" : "ci_left_join_cube",
+  "segments_name" : [ ],
+  "online" : true
+}
\ No newline at end of file
diff --git a/examples/test_case_data/localmeta/measure/ci_left_join_cube/TEST_COUNT_COLUMN_CNT.json b/examples/test_case_data/localmeta/measure/ci_left_join_cube/TEST_COUNT_COLUMN_CNT.json
new file mode 100644
index 0000000..6b46bf9
--- /dev/null
+++ b/examples/test_case_data/localmeta/measure/ci_left_join_cube/TEST_COUNT_COLUMN_CNT.json
@@ -0,0 +1,9 @@
+{
+  "uuid" : "4942846c-38e3-d5fe-90a7-95e9234f3d83",
+  "last_modified" : 1556584529219,
+  "version" : "2.6.0.20500",
+  "name" : "TEST_COUNT_COLUMN_CNT",
+  "cube_name" : "ci_left_join_cube",
+  "segments_name" : [ ],
+  "online" : true
+}
\ No newline at end of file
diff --git a/examples/test_case_data/localmeta/measure/ci_left_join_cube/TEST_COUNT_DISTINCT_BITMAP.json b/examples/test_case_data/localmeta/measure/ci_left_join_cube/TEST_COUNT_DISTINCT_BITMAP.json
new file mode 100644
index 0000000..b6b4bd3
--- /dev/null
+++ b/examples/test_case_data/localmeta/measure/ci_left_join_cube/TEST_COUNT_DISTINCT_BITMAP.json
@@ -0,0 +1,9 @@
+{
+  "uuid" : "bfdaf4cb-8e4d-662f-c44e-d1be13156b6a",
+  "last_modified" : 1556584529196,
+  "version" : "2.6.0.20500",
+  "name" : "TEST_COUNT_DISTINCT_BITMAP",
+  "cube_name" : "ci_left_join_cube",
+  "segments_name" : [ ],
+  "online" : true
+}
\ No newline at end of file
diff --git a/examples/test_case_data/localmeta/measure/ci_left_join_cube/TEST_EXTENDED_COLUMN.json b/examples/test_case_data/localmeta/measure/ci_left_join_cube/TEST_EXTENDED_COLUMN.json
new file mode 100644
index 0000000..5888a75
--- /dev/null
+++ b/examples/test_case_data/localmeta/measure/ci_left_join_cube/TEST_EXTENDED_COLUMN.json
@@ -0,0 +1,9 @@
+{
+  "uuid" : "9cd64950-ffb2-e8bd-e464-6a024eda2901",
+  "last_modified" : 1556584529199,
+  "version" : "2.6.0.20500",
+  "name" : "TEST_EXTENDED_COLUMN",
+  "cube_name" : "ci_left_join_cube",
+  "segments_name" : [ ],
+  "online" : true
+}
\ No newline at end of file
diff --git a/examples/test_case_data/localmeta/measure/ci_left_join_cube/TOP_SELLER.json b/examples/test_case_data/localmeta/measure/ci_left_join_cube/TOP_SELLER.json
new file mode 100644
index 0000000..7c269de
--- /dev/null
+++ b/examples/test_case_data/localmeta/measure/ci_left_join_cube/TOP_SELLER.json
@@ -0,0 +1,9 @@
+{
+  "uuid" : "2b7fc8f4-e1c1-32c4-7872-160fd1ec6ecf",
+  "last_modified" : 1556584529193,
+  "version" : "2.6.0.20500",
+  "name" : "TOP_SELLER",
+  "cube_name" : "ci_left_join_cube",
+  "segments_name" : [ ],
+  "online" : true
+}
\ No newline at end of file
diff --git a/examples/test_case_data/localmeta/measure/ci_left_join_cube/TRANS_CNT.json b/examples/test_case_data/localmeta/measure/ci_left_join_cube/TRANS_CNT.json
new file mode 100644
index 0000000..347d1a6
--- /dev/null
+++ b/examples/test_case_data/localmeta/measure/ci_left_join_cube/TRANS_CNT.json
@@ -0,0 +1,9 @@
+{
+  "uuid" : "3c4c8c88-6bea-e439-41f4-b7a77927da4d",
+  "last_modified" : 1556584529169,
+  "version" : "2.6.0.20500",
+  "name" : "TRANS_CNT",
+  "cube_name" : "ci_left_join_cube",
+  "segments_name" : [ ],
+  "online" : true
+}
\ No newline at end of file
diff --git a/examples/test_case_data/localmeta/measure/ci_left_join_cube/TRANS_ID_RAW.json b/examples/test_case_data/localmeta/measure/ci_left_join_cube/TRANS_ID_RAW.json
new file mode 100644
index 0000000..ae92725
--- /dev/null
+++ b/examples/test_case_data/localmeta/measure/ci_left_join_cube/TRANS_ID_RAW.json
@@ -0,0 +1,9 @@
+{
+  "uuid" : "9c18b16f-22ce-6eab-24aa-d211e94c4aea",
+  "last_modified" : 1556584529207,
+  "version" : "2.6.0.20500",
+  "name" : "TRANS_ID_RAW",
+  "cube_name" : "ci_left_join_cube",
+  "segments_name" : [ ],
+  "online" : true
+}
\ No newline at end of file
diff --git a/examples/test_case_data/localmeta/measure/fifty_dim_full_build_cube/_COUNT_.json b/examples/test_case_data/localmeta/measure/fifty_dim_full_build_cube/_COUNT_.json
new file mode 100644
index 0000000..2f2bc67
--- /dev/null
+++ b/examples/test_case_data/localmeta/measure/fifty_dim_full_build_cube/_COUNT_.json
@@ -0,0 +1,9 @@
+{
+  "uuid" : "25baa916-2287-0d36-4938-0d75094ebbda",
+  "last_modified" : 1556584529222,
+  "version" : "2.6.0.20500",
+  "name" : "_COUNT_",
+  "cube_name" : "fifty_dim_full_build_cube",
+  "segments_name" : [ ],
+  "online" : true
+}
\ No newline at end of file
diff --git a/examples/test_case_data/localmeta/measure/ssb/TOTAL_REVENUE.json b/examples/test_case_data/localmeta/measure/ssb/TOTAL_REVENUE.json
new file mode 100644
index 0000000..ef68e51
--- /dev/null
+++ b/examples/test_case_data/localmeta/measure/ssb/TOTAL_REVENUE.json
@@ -0,0 +1,9 @@
+{
+  "uuid" : "f925a53e-da71-a9ae-3866-1fc296462e47",
+  "last_modified" : 1556584529229,
+  "version" : "2.6.0.20500",
+  "name" : "TOTAL_REVENUE",
+  "cube_name" : "ssb",
+  "segments_name" : [ ],
+  "online" : true
+}
\ No newline at end of file
diff --git a/examples/test_case_data/localmeta/measure/ssb/TOTAL_SUPPLYCOST.json b/examples/test_case_data/localmeta/measure/ssb/TOTAL_SUPPLYCOST.json
new file mode 100644
index 0000000..e4ac5fa
--- /dev/null
+++ b/examples/test_case_data/localmeta/measure/ssb/TOTAL_SUPPLYCOST.json
@@ -0,0 +1,9 @@
+{
+  "uuid" : "57d3ee89-c95c-f846-1c88-8a3a876cfea7",
+  "last_modified" : 1556584529232,
+  "version" : "2.6.0.20500",
+  "name" : "TOTAL_SUPPLYCOST",
+  "cube_name" : "ssb",
+  "segments_name" : [ ],
+  "online" : true
+}
\ No newline at end of file
diff --git a/examples/test_case_data/localmeta/measure/ssb/TOTAL_V_REVENUE.json b/examples/test_case_data/localmeta/measure/ssb/TOTAL_V_REVENUE.json
new file mode 100644
index 0000000..73c7413
--- /dev/null
+++ b/examples/test_case_data/localmeta/measure/ssb/TOTAL_V_REVENUE.json
@@ -0,0 +1,9 @@
+{
+  "uuid" : "abf3238c-1184-24b5-6525-732c9174786f",
+  "last_modified" : 1556584529234,
+  "version" : "2.6.0.20500",
+  "name" : "TOTAL_V_REVENUE",
+  "cube_name" : "ssb",
+  "segments_name" : [ ],
+  "online" : true
+}
\ No newline at end of file
diff --git a/examples/test_case_data/localmeta/measure/ssb/_COUNT_.json b/examples/test_case_data/localmeta/measure/ssb/_COUNT_.json
new file mode 100644
index 0000000..2164636
--- /dev/null
+++ b/examples/test_case_data/localmeta/measure/ssb/_COUNT_.json
@@ -0,0 +1,9 @@
+{
+  "uuid" : "b0831650-9e56-95f7-1b9a-105ea4260038",
+  "last_modified" : 1556584529225,
+  "version" : "2.6.0.20500",
+  "name" : "_COUNT_",
+  "cube_name" : "ssb",
+  "segments_name" : [ ],
+  "online" : true
+}
\ No newline at end of file
diff --git a/examples/test_case_data/localmeta/measure/ssb_cube1/TOTAL_REVENUE.json b/examples/test_case_data/localmeta/measure/ssb_cube1/TOTAL_REVENUE.json
new file mode 100644
index 0000000..26c4f60
--- /dev/null
+++ b/examples/test_case_data/localmeta/measure/ssb_cube1/TOTAL_REVENUE.json
@@ -0,0 +1,9 @@
+{
+  "uuid" : "ca1622f8-046b-b1c1-d8e1-08206d25c7bc",
+  "last_modified" : 1556584529241,
+  "version" : "2.6.0.20500",
+  "name" : "TOTAL_REVENUE",
+  "cube_name" : "ssb_cube1",
+  "segments_name" : [ ],
+  "online" : true
+}
\ No newline at end of file
diff --git a/examples/test_case_data/localmeta/measure/ssb_cube1/TOTAL_SUPPLYCOST.json b/examples/test_case_data/localmeta/measure/ssb_cube1/TOTAL_SUPPLYCOST.json
new file mode 100644
index 0000000..b92b250
--- /dev/null
+++ b/examples/test_case_data/localmeta/measure/ssb_cube1/TOTAL_SUPPLYCOST.json
@@ -0,0 +1,9 @@
+{
+  "uuid" : "43999d14-59d2-4288-d7cf-b78eb59b9544",
+  "last_modified" : 1556584529244,
+  "version" : "2.6.0.20500",
+  "name" : "TOTAL_SUPPLYCOST",
+  "cube_name" : "ssb_cube1",
+  "segments_name" : [ ],
+  "online" : true
+}
\ No newline at end of file
diff --git a/examples/test_case_data/localmeta/measure/ssb_cube1/TOTAL_V_REVENUE.json b/examples/test_case_data/localmeta/measure/ssb_cube1/TOTAL_V_REVENUE.json
new file mode 100644
index 0000000..b30b57a
--- /dev/null
+++ b/examples/test_case_data/localmeta/measure/ssb_cube1/TOTAL_V_REVENUE.json
@@ -0,0 +1,9 @@
+{
+  "uuid" : "ac78157d-bd86-2476-42d2-712d2ac4acd0",
+  "last_modified" : 1556584529247,
+  "version" : "2.6.0.20500",
+  "name" : "TOTAL_V_REVENUE",
+  "cube_name" : "ssb_cube1",
+  "segments_name" : [ ],
+  "online" : true
+}
\ No newline at end of file
diff --git a/examples/test_case_data/localmeta/measure/ssb_cube1/_COUNT_.json b/examples/test_case_data/localmeta/measure/ssb_cube1/_COUNT_.json
new file mode 100644
index 0000000..154a8e3
--- /dev/null
+++ b/examples/test_case_data/localmeta/measure/ssb_cube1/_COUNT_.json
@@ -0,0 +1,9 @@
+{
+  "uuid" : "182cdf1d-a95b-9945-1ee2-becdf8352a86",
+  "last_modified" : 1556584529237,
+  "version" : "2.6.0.20500",
+  "name" : "_COUNT_",
+  "cube_name" : "ssb_cube1",
+  "segments_name" : [ ],
+  "online" : true
+}
\ No newline at end of file
diff --git a/examples/test_case_data/localmeta/measure/ssb_cube2/TOTAL_REVENUE.json b/examples/test_case_data/localmeta/measure/ssb_cube2/TOTAL_REVENUE.json
new file mode 100644
index 0000000..3383433
--- /dev/null
+++ b/examples/test_case_data/localmeta/measure/ssb_cube2/TOTAL_REVENUE.json
@@ -0,0 +1,9 @@
+{
+  "uuid" : "63b33a86-8b02-dc3c-5a93-d91442d1e400",
+  "last_modified" : 1556584529253,
+  "version" : "2.6.0.20500",
+  "name" : "TOTAL_REVENUE",
+  "cube_name" : "ssb_cube2",
+  "segments_name" : [ ],
+  "online" : true
+}
\ No newline at end of file
diff --git a/examples/test_case_data/localmeta/measure/ssb_cube2/TOTAL_SUPPLYCOST.json b/examples/test_case_data/localmeta/measure/ssb_cube2/TOTAL_SUPPLYCOST.json
new file mode 100644
index 0000000..ac1b771
--- /dev/null
+++ b/examples/test_case_data/localmeta/measure/ssb_cube2/TOTAL_SUPPLYCOST.json
@@ -0,0 +1,9 @@
+{
+  "uuid" : "e2e3f914-3970-b5d0-3503-44b4f4942e9f",
+  "last_modified" : 1556584529256,
+  "version" : "2.6.0.20500",
+  "name" : "TOTAL_SUPPLYCOST",
+  "cube_name" : "ssb_cube2",
+  "segments_name" : [ ],
+  "online" : true
+}
\ No newline at end of file
diff --git a/examples/test_case_data/localmeta/measure/ssb_cube2/TOTAL_V_REVENUE.json b/examples/test_case_data/localmeta/measure/ssb_cube2/TOTAL_V_REVENUE.json
new file mode 100644
index 0000000..dd563e9
--- /dev/null
+++ b/examples/test_case_data/localmeta/measure/ssb_cube2/TOTAL_V_REVENUE.json
@@ -0,0 +1,9 @@
+{
+  "uuid" : "0e82b772-a18e-f4b0-2360-97830dff74ba",
+  "last_modified" : 1556584529259,
+  "version" : "2.6.0.20500",
+  "name" : "TOTAL_V_REVENUE",
+  "cube_name" : "ssb_cube2",
+  "segments_name" : [ ],
+  "online" : true
+}
\ No newline at end of file
diff --git a/examples/test_case_data/localmeta/measure/ssb_cube2/_COUNT_.json b/examples/test_case_data/localmeta/measure/ssb_cube2/_COUNT_.json
new file mode 100644
index 0000000..c7e689b
--- /dev/null
+++ b/examples/test_case_data/localmeta/measure/ssb_cube2/_COUNT_.json
@@ -0,0 +1,9 @@
+{
+  "uuid" : "89e50c9d-d6a0-f45a-8161-e097a7865c02",
+  "last_modified" : 1556584529250,
+  "version" : "2.6.0.20500",
+  "name" : "_COUNT_",
+  "cube_name" : "ssb_cube2",
+  "segments_name" : [ ],
+  "online" : true
+}
\ No newline at end of file
diff --git a/examples/test_case_data/localmeta/measure/ssb_cube3/TOTAL_REVENUE.json b/examples/test_case_data/localmeta/measure/ssb_cube3/TOTAL_REVENUE.json
new file mode 100644
index 0000000..0d2d992
--- /dev/null
+++ b/examples/test_case_data/localmeta/measure/ssb_cube3/TOTAL_REVENUE.json
@@ -0,0 +1,9 @@
+{
+  "uuid" : "a1d86904-9382-c16b-7b23-d11d339012cd",
+  "last_modified" : 1556584529265,
+  "version" : "2.6.0.20500",
+  "name" : "TOTAL_REVENUE",
+  "cube_name" : "ssb_cube3",
+  "segments_name" : [ ],
+  "online" : true
+}
\ No newline at end of file
diff --git a/examples/test_case_data/localmeta/measure/ssb_cube3/TOTAL_SUPPLYCOST.json b/examples/test_case_data/localmeta/measure/ssb_cube3/TOTAL_SUPPLYCOST.json
new file mode 100644
index 0000000..df2415c
--- /dev/null
+++ b/examples/test_case_data/localmeta/measure/ssb_cube3/TOTAL_SUPPLYCOST.json
@@ -0,0 +1,9 @@
+{
+  "uuid" : "d1198145-36b1-b18d-08d9-eebeaf0dac13",
+  "last_modified" : 1556584529268,
+  "version" : "2.6.0.20500",
+  "name" : "TOTAL_SUPPLYCOST",
+  "cube_name" : "ssb_cube3",
+  "segments_name" : [ ],
+  "online" : true
+}
\ No newline at end of file
diff --git a/examples/test_case_data/localmeta/measure/ssb_cube3/_COUNT_.json b/examples/test_case_data/localmeta/measure/ssb_cube3/_COUNT_.json
new file mode 100644
index 0000000..eeca378
--- /dev/null
+++ b/examples/test_case_data/localmeta/measure/ssb_cube3/_COUNT_.json
@@ -0,0 +1,9 @@
+{
+  "uuid" : "fd30eda2-8207-1fe0-81b3-98c223e89449",
+  "last_modified" : 1556584529262,
+  "version" : "2.6.0.20500",
+  "name" : "_COUNT_",
+  "cube_name" : "ssb_cube3",
+  "segments_name" : [ ],
+  "online" : true
+}
\ No newline at end of file
diff --git a/examples/test_case_data/localmeta/measure/ssb_cube_with_dimention_range/TOTAL_REVENUE.json b/examples/test_case_data/localmeta/measure/ssb_cube_with_dimention_range/TOTAL_REVENUE.json
new file mode 100644
index 0000000..d73492c
--- /dev/null
+++ b/examples/test_case_data/localmeta/measure/ssb_cube_with_dimention_range/TOTAL_REVENUE.json
@@ -0,0 +1,9 @@
+{
+  "uuid" : "558ecc93-e1e3-4f67-ae2c-39e5deffeed0",
+  "last_modified" : 1556584529290,
+  "version" : "2.6.0.20500",
+  "name" : "TOTAL_REVENUE",
+  "cube_name" : "ssb_cube_with_dimention_range",
+  "segments_name" : [ "19920523163722_20180523173026" ],
+  "online" : true
+}
\ No newline at end of file
diff --git a/examples/test_case_data/localmeta/measure/ssb_cube_with_dimention_range/TOTAL_SUPPLYCOST.json b/examples/test_case_data/localmeta/measure/ssb_cube_with_dimention_range/TOTAL_SUPPLYCOST.json
new file mode 100644
index 0000000..c2ec700
--- /dev/null
+++ b/examples/test_case_data/localmeta/measure/ssb_cube_with_dimention_range/TOTAL_SUPPLYCOST.json
@@ -0,0 +1,9 @@
+{
+  "uuid" : "7acbd8b0-0b73-5ad1-ad43-50b401f2d65e",
+  "last_modified" : 1556584529293,
+  "version" : "2.6.0.20500",
+  "name" : "TOTAL_SUPPLYCOST",
+  "cube_name" : "ssb_cube_with_dimention_range",
+  "segments_name" : [ "19920523163722_20180523173026" ],
+  "online" : true
+}
\ No newline at end of file
diff --git a/examples/test_case_data/localmeta/measure/ssb_cube_with_dimention_range/_COUNT_.json b/examples/test_case_data/localmeta/measure/ssb_cube_with_dimention_range/_COUNT_.json
new file mode 100644
index 0000000..b6643bc
--- /dev/null
+++ b/examples/test_case_data/localmeta/measure/ssb_cube_with_dimention_range/_COUNT_.json
@@ -0,0 +1,9 @@
+{
+  "uuid" : "4d2e4f04-fb94-e06f-2f9a-2cd47fb0bee2",
+  "last_modified" : 1556584529286,
+  "version" : "2.6.0.20500",
+  "name" : "_COUNT_",
+  "cube_name" : "ssb_cube_with_dimention_range",
+  "segments_name" : [ "19920523163722_20180523173026" ],
+  "online" : true
+}
\ No newline at end of file
diff --git a/examples/test_case_data/localmeta/measure/test_kylin_cube_with_slr_1_new_segment/GMV_MAX.json b/examples/test_case_data/localmeta/measure/test_kylin_cube_with_slr_1_new_segment/GMV_MAX.json
new file mode 100644
index 0000000..6d41954
--- /dev/null
+++ b/examples/test_case_data/localmeta/measure/test_kylin_cube_with_slr_1_new_segment/GMV_MAX.json
@@ -0,0 +1,9 @@
+{
+  "uuid" : "27217dee-62b2-18d3-fd08-3ab21014ebe9",
+  "last_modified" : 1556584529302,
+  "version" : "2.6.0.20500",
+  "name" : "GMV_MAX",
+  "cube_name" : "test_kylin_cube_with_slr_1_new_segment",
+  "segments_name" : [ ],
+  "online" : true
+}
\ No newline at end of file
diff --git a/examples/test_case_data/localmeta/measure/test_kylin_cube_with_slr_1_new_segment/GMV_MIN.json b/examples/test_case_data/localmeta/measure/test_kylin_cube_with_slr_1_new_segment/GMV_MIN.json
new file mode 100644
index 0000000..cd1d066
--- /dev/null
+++ b/examples/test_case_data/localmeta/measure/test_kylin_cube_with_slr_1_new_segment/GMV_MIN.json
@@ -0,0 +1,9 @@
+{
+  "uuid" : "b25cd796-67e7-29b2-d99e-4429b5ce5881",
+  "last_modified" : 1556584529299,
+  "version" : "2.6.0.20500",
+  "name" : "GMV_MIN",
+  "cube_name" : "test_kylin_cube_with_slr_1_new_segment",
+  "segments_name" : [ ],
+  "online" : true
+}
\ No newline at end of file
diff --git a/examples/test_case_data/localmeta/measure/test_kylin_cube_with_slr_1_new_segment/GMV_SUM.json b/examples/test_case_data/localmeta/measure/test_kylin_cube_with_slr_1_new_segment/GMV_SUM.json
new file mode 100644
index 0000000..a390281
--- /dev/null
+++ b/examples/test_case_data/localmeta/measure/test_kylin_cube_with_slr_1_new_segment/GMV_SUM.json
@@ -0,0 +1,9 @@
+{
+  "uuid" : "b7d6eadb-1ac5-58f1-d754-1f6499c8376e",
+  "last_modified" : 1556584529296,
+  "version" : "2.6.0.20500",
+  "name" : "GMV_SUM",
+  "cube_name" : "test_kylin_cube_with_slr_1_new_segment",
+  "segments_name" : [ ],
+  "online" : true
+}
\ No newline at end of file
diff --git a/examples/test_case_data/localmeta/measure/test_kylin_cube_with_slr_1_new_segment/ITEM_COUNT_SUM.json b/examples/test_case_data/localmeta/measure/test_kylin_cube_with_slr_1_new_segment/ITEM_COUNT_SUM.json
new file mode 100644
index 0000000..ed50245
--- /dev/null
+++ b/examples/test_case_data/localmeta/measure/test_kylin_cube_with_slr_1_new_segment/ITEM_COUNT_SUM.json
@@ -0,0 +1,9 @@
+{
+  "uuid" : "0a7a1c58-8261-bec2-d036-723cb98f1731",
+  "last_modified" : 1556584529308,
+  "version" : "2.6.0.20500",
+  "name" : "ITEM_COUNT_SUM",
+  "cube_name" : "test_kylin_cube_with_slr_1_new_segment",
+  "segments_name" : [ ],
+  "online" : true
+}
\ No newline at end of file
diff --git a/examples/test_case_data/localmeta/measure/test_kylin_cube_with_slr_1_new_segment/TRANS_CNT.json b/examples/test_case_data/localmeta/measure/test_kylin_cube_with_slr_1_new_segment/TRANS_CNT.json
new file mode 100644
index 0000000..e8d650d
--- /dev/null
+++ b/examples/test_case_data/localmeta/measure/test_kylin_cube_with_slr_1_new_segment/TRANS_CNT.json
@@ -0,0 +1,9 @@
+{
+  "uuid" : "2c535460-388d-2bb4-66dd-35c0aff101d5",
+  "last_modified" : 1556584529305,
+  "version" : "2.6.0.20500",
+  "name" : "TRANS_CNT",
+  "cube_name" : "test_kylin_cube_with_slr_1_new_segment",
+  "segments_name" : [ ],
+  "online" : true
+}
\ No newline at end of file
diff --git a/examples/test_case_data/localmeta/measure/test_kylin_cube_with_slr_empty/GMV_MAX.json b/examples/test_case_data/localmeta/measure/test_kylin_cube_with_slr_empty/GMV_MAX.json
new file mode 100644
index 0000000..c7e5b89
--- /dev/null
+++ b/examples/test_case_data/localmeta/measure/test_kylin_cube_with_slr_empty/GMV_MAX.json
@@ -0,0 +1,9 @@
+{
+  "uuid" : "2f5386dd-59ef-213d-6118-2cfb49e9567c",
+  "last_modified" : 1556584529317,
+  "version" : "2.6.0.20500",
+  "name" : "GMV_MAX",
+  "cube_name" : "test_kylin_cube_with_slr_empty",
+  "segments_name" : [ ],
+  "online" : true
+}
\ No newline at end of file
diff --git a/examples/test_case_data/localmeta/measure/test_kylin_cube_with_slr_empty/GMV_MIN.json b/examples/test_case_data/localmeta/measure/test_kylin_cube_with_slr_empty/GMV_MIN.json
new file mode 100644
index 0000000..523a557
--- /dev/null
+++ b/examples/test_case_data/localmeta/measure/test_kylin_cube_with_slr_empty/GMV_MIN.json
@@ -0,0 +1,9 @@
+{
+  "uuid" : "7fdff937-8311-1bc9-adf5-00c36ee358f0",
+  "last_modified" : 1556584529314,
+  "version" : "2.6.0.20500",
+  "name" : "GMV_MIN",
+  "cube_name" : "test_kylin_cube_with_slr_empty",
+  "segments_name" : [ ],
+  "online" : true
+}
\ No newline at end of file
diff --git a/examples/test_case_data/localmeta/measure/test_kylin_cube_with_slr_empty/GMV_SUM.json b/examples/test_case_data/localmeta/measure/test_kylin_cube_with_slr_empty/GMV_SUM.json
new file mode 100644
index 0000000..3c65992
--- /dev/null
+++ b/examples/test_case_data/localmeta/measure/test_kylin_cube_with_slr_empty/GMV_SUM.json
@@ -0,0 +1,9 @@
+{
+  "uuid" : "29eb0927-5c91-8605-58d7-f3e5e31c158e",
+  "last_modified" : 1556584529310,
+  "version" : "2.6.0.20500",
+  "name" : "GMV_SUM",
+  "cube_name" : "test_kylin_cube_with_slr_empty",
+  "segments_name" : [ ],
+  "online" : true
+}
\ No newline at end of file
diff --git a/examples/test_case_data/localmeta/measure/test_kylin_cube_with_slr_empty/ITEM_COUNT_SUM.json b/examples/test_case_data/localmeta/measure/test_kylin_cube_with_slr_empty/ITEM_COUNT_SUM.json
new file mode 100644
index 0000000..efc985d
--- /dev/null
+++ b/examples/test_case_data/localmeta/measure/test_kylin_cube_with_slr_empty/ITEM_COUNT_SUM.json
@@ -0,0 +1,9 @@
+{
+  "uuid" : "1b37e35d-8504-1f0f-e5b5-4ac6edf8fb7f",
+  "last_modified" : 1556584529322,
+  "version" : "2.6.0.20500",
+  "name" : "ITEM_COUNT_SUM",
+  "cube_name" : "test_kylin_cube_with_slr_empty",
+  "segments_name" : [ ],
+  "online" : true
+}
\ No newline at end of file
diff --git a/examples/test_case_data/localmeta/measure/test_kylin_cube_with_slr_empty/TRANS_CNT.json b/examples/test_case_data/localmeta/measure/test_kylin_cube_with_slr_empty/TRANS_CNT.json
new file mode 100644
index 0000000..a2e1ed8
--- /dev/null
+++ b/examples/test_case_data/localmeta/measure/test_kylin_cube_with_slr_empty/TRANS_CNT.json
@@ -0,0 +1,9 @@
+{
+  "uuid" : "8356ff44-a4c1-2366-6dae-0f1f6425c54f",
+  "last_modified" : 1556584529320,
+  "version" : "2.6.0.20500",
+  "name" : "TRANS_CNT",
+  "cube_name" : "test_kylin_cube_with_slr_empty",
+  "segments_name" : [ ],
+  "online" : true
+}
\ No newline at end of file
diff --git a/examples/test_case_data/localmeta/measure/test_kylin_cube_with_slr_left_join_empty/GMV_MAX.json b/examples/test_case_data/localmeta/measure/test_kylin_cube_with_slr_left_join_empty/GMV_MAX.json
new file mode 100644
index 0000000..1c8388a
--- /dev/null
+++ b/examples/test_case_data/localmeta/measure/test_kylin_cube_with_slr_left_join_empty/GMV_MAX.json
@@ -0,0 +1,9 @@
+{
+  "uuid" : "ed13d130-6bd7-605c-c31b-f71c47325fca",
+  "last_modified" : 1556584529331,
+  "version" : "2.6.0.20500",
+  "name" : "GMV_MAX",
+  "cube_name" : "test_kylin_cube_with_slr_left_join_empty",
+  "segments_name" : [ ],
+  "online" : true
+}
\ No newline at end of file
diff --git a/examples/test_case_data/localmeta/measure/test_kylin_cube_with_slr_left_join_empty/GMV_MIN.json b/examples/test_case_data/localmeta/measure/test_kylin_cube_with_slr_left_join_empty/GMV_MIN.json
new file mode 100644
index 0000000..7a9f14e
--- /dev/null
+++ b/examples/test_case_data/localmeta/measure/test_kylin_cube_with_slr_left_join_empty/GMV_MIN.json
@@ -0,0 +1,9 @@
+{
+  "uuid" : "8bf0a134-802d-2a92-c332-205a098fc251",
+  "last_modified" : 1556584529329,
+  "version" : "2.6.0.20500",
+  "name" : "GMV_MIN",
+  "cube_name" : "test_kylin_cube_with_slr_left_join_empty",
+  "segments_name" : [ ],
+  "online" : true
+}
\ No newline at end of file
diff --git a/examples/test_case_data/localmeta/measure/test_kylin_cube_with_slr_left_join_empty/GMV_SUM.json b/examples/test_case_data/localmeta/measure/test_kylin_cube_with_slr_left_join_empty/GMV_SUM.json
new file mode 100644
index 0000000..017923f
--- /dev/null
+++ b/examples/test_case_data/localmeta/measure/test_kylin_cube_with_slr_left_join_empty/GMV_SUM.json
@@ -0,0 +1,9 @@
+{
+  "uuid" : "1f411a72-4601-f82f-f68f-97c885f3e467",
+  "last_modified" : 1556584529325,
+  "version" : "2.6.0.20500",
+  "name" : "GMV_SUM",
+  "cube_name" : "test_kylin_cube_with_slr_left_join_empty",
+  "segments_name" : [ ],
+  "online" : true
+}
\ No newline at end of file
diff --git a/examples/test_case_data/localmeta/measure/test_kylin_cube_with_slr_left_join_empty/ITEM_COUNT_SUM.json b/examples/test_case_data/localmeta/measure/test_kylin_cube_with_slr_left_join_empty/ITEM_COUNT_SUM.json
new file mode 100644
index 0000000..7cbda46
--- /dev/null
+++ b/examples/test_case_data/localmeta/measure/test_kylin_cube_with_slr_left_join_empty/ITEM_COUNT_SUM.json
@@ -0,0 +1,9 @@
+{
+  "uuid" : "91d44cec-11e2-0b78-7b20-fc853d542a6b",
+  "last_modified" : 1556584529337,
+  "version" : "2.6.0.20500",
+  "name" : "ITEM_COUNT_SUM",
+  "cube_name" : "test_kylin_cube_with_slr_left_join_empty",
+  "segments_name" : [ ],
+  "online" : true
+}
\ No newline at end of file
diff --git a/examples/test_case_data/localmeta/measure/test_kylin_cube_with_slr_left_join_empty/SELLER_CNT_HLL.json b/examples/test_case_data/localmeta/measure/test_kylin_cube_with_slr_left_join_empty/SELLER_CNT_HLL.json
new file mode 100644
index 0000000..a31400d
--- /dev/null
+++ b/examples/test_case_data/localmeta/measure/test_kylin_cube_with_slr_left_join_empty/SELLER_CNT_HLL.json
@@ -0,0 +1,9 @@
+{
+  "uuid" : "9febbd32-8ef7-4582-9d6f-02dfd130e35a",
+  "last_modified" : 1556584529340,
+  "version" : "2.6.0.20500",
+  "name" : "SELLER_CNT_HLL",
+  "cube_name" : "test_kylin_cube_with_slr_left_join_empty",
+  "segments_name" : [ ],
+  "online" : true
+}
\ No newline at end of file
diff --git a/examples/test_case_data/localmeta/measure/test_kylin_cube_with_slr_left_join_empty/TOP_SELLER.json b/examples/test_case_data/localmeta/measure/test_kylin_cube_with_slr_left_join_empty/TOP_SELLER.json
new file mode 100644
index 0000000..8c1a17b
--- /dev/null
+++ b/examples/test_case_data/localmeta/measure/test_kylin_cube_with_slr_left_join_empty/TOP_SELLER.json
@@ -0,0 +1,9 @@
+{
+  "uuid" : "60dc5b5f-0b38-ebe6-dab6-3cb240b6f2a0",
+  "last_modified" : 1556584529343,
+  "version" : "2.6.0.20500",
+  "name" : "TOP_SELLER",
+  "cube_name" : "test_kylin_cube_with_slr_left_join_empty",
+  "segments_name" : [ ],
+  "online" : true
+}
\ No newline at end of file
diff --git a/examples/test_case_data/localmeta/measure/test_kylin_cube_with_slr_left_join_empty/TRANS_CNT.json b/examples/test_case_data/localmeta/measure/test_kylin_cube_with_slr_left_join_empty/TRANS_CNT.json
new file mode 100644
index 0000000..92e0ae2
--- /dev/null
+++ b/examples/test_case_data/localmeta/measure/test_kylin_cube_with_slr_left_join_empty/TRANS_CNT.json
@@ -0,0 +1,9 @@
+{
+  "uuid" : "c47a5b8b-899a-9f8d-c946-aadb2d250057",
+  "last_modified" : 1556584529334,
+  "version" : "2.6.0.20500",
+  "name" : "TRANS_CNT",
+  "cube_name" : "test_kylin_cube_with_slr_left_join_empty",
+  "segments_name" : [ ],
+  "online" : true
+}
\ No newline at end of file
diff --git a/examples/test_case_data/localmeta/measure/test_kylin_cube_with_slr_left_join_ready/GMV_MAX.json b/examples/test_case_data/localmeta/measure/test_kylin_cube_with_slr_left_join_ready/GMV_MAX.json
new file mode 100644
index 0000000..4864f55
--- /dev/null
+++ b/examples/test_case_data/localmeta/measure/test_kylin_cube_with_slr_left_join_ready/GMV_MAX.json
@@ -0,0 +1,9 @@
+{
+  "uuid" : "55886eab-e710-86c8-25b6-04f81f6593f7",
+  "last_modified" : 1556584529353,
+  "version" : "2.6.0.20500",
+  "name" : "GMV_MAX",
+  "cube_name" : "test_kylin_cube_with_slr_left_join_ready",
+  "segments_name" : [ "1eaca32a-a33e-4b69-83dd-xxe8b1f8dddd" ],
+  "online" : true
+}
\ No newline at end of file
diff --git a/examples/test_case_data/localmeta/measure/test_kylin_cube_with_slr_left_join_ready/GMV_MIN.json b/examples/test_case_data/localmeta/measure/test_kylin_cube_with_slr_left_join_ready/GMV_MIN.json
new file mode 100644
index 0000000..d2a5121
--- /dev/null
+++ b/examples/test_case_data/localmeta/measure/test_kylin_cube_with_slr_left_join_ready/GMV_MIN.json
@@ -0,0 +1,9 @@
+{
+  "uuid" : "24a6c675-b5f0-2df3-86d8-a02864e3f91c",
+  "last_modified" : 1556584529350,
+  "version" : "2.6.0.20500",
+  "name" : "GMV_MIN",
+  "cube_name" : "test_kylin_cube_with_slr_left_join_ready",
+  "segments_name" : [ "1eaca32a-a33e-4b69-83dd-xxe8b1f8dddd" ],
+  "online" : true
+}
\ No newline at end of file
diff --git a/examples/test_case_data/localmeta/measure/test_kylin_cube_with_slr_left_join_ready/GMV_SUM.json b/examples/test_case_data/localmeta/measure/test_kylin_cube_with_slr_left_join_ready/GMV_SUM.json
new file mode 100644
index 0000000..cf94581
--- /dev/null
+++ b/examples/test_case_data/localmeta/measure/test_kylin_cube_with_slr_left_join_ready/GMV_SUM.json
@@ -0,0 +1,9 @@
+{
+  "uuid" : "bdee8d95-b41e-4fea-50e4-0ceee365abc5",
+  "last_modified" : 1556584529346,
+  "version" : "2.6.0.20500",
+  "name" : "GMV_SUM",
+  "cube_name" : "test_kylin_cube_with_slr_left_join_ready",
+  "segments_name" : [ "1eaca32a-a33e-4b69-83dd-xxe8b1f8dddd" ],
+  "online" : true
+}
\ No newline at end of file
diff --git a/examples/test_case_data/localmeta/measure/test_kylin_cube_with_slr_left_join_ready/ITEM_COUNT_SUM.json b/examples/test_case_data/localmeta/measure/test_kylin_cube_with_slr_left_join_ready/ITEM_COUNT_SUM.json
new file mode 100644
index 0000000..2386743
--- /dev/null
+++ b/examples/test_case_data/localmeta/measure/test_kylin_cube_with_slr_left_join_ready/ITEM_COUNT_SUM.json
@@ -0,0 +1,9 @@
+{
+  "uuid" : "b370245a-680c-19d5-b9df-5871bdada3b5",
+  "last_modified" : 1556584529359,
+  "version" : "2.6.0.20500",
+  "name" : "ITEM_COUNT_SUM",
+  "cube_name" : "test_kylin_cube_with_slr_left_join_ready",
+  "segments_name" : [ "1eaca32a-a33e-4b69-83dd-xxe8b1f8dddd" ],
+  "online" : true
+}
\ No newline at end of file
diff --git a/examples/test_case_data/localmeta/measure/test_kylin_cube_with_slr_left_join_ready/SELLER_CNT_HLL.json b/examples/test_case_data/localmeta/measure/test_kylin_cube_with_slr_left_join_ready/SELLER_CNT_HLL.json
new file mode 100644
index 0000000..4ba5320
--- /dev/null
+++ b/examples/test_case_data/localmeta/measure/test_kylin_cube_with_slr_left_join_ready/SELLER_CNT_HLL.json
@@ -0,0 +1,9 @@
+{
+  "uuid" : "45e8100c-ac2e-d3ee-3115-cfd1d195561a",
+  "last_modified" : 1556584529361,
+  "version" : "2.6.0.20500",
+  "name" : "SELLER_CNT_HLL",
+  "cube_name" : "test_kylin_cube_with_slr_left_join_ready",
+  "segments_name" : [ "1eaca32a-a33e-4b69-83dd-xxe8b1f8dddd" ],
+  "online" : true
+}
\ No newline at end of file
diff --git a/examples/test_case_data/localmeta/measure/test_kylin_cube_with_slr_left_join_ready/TOP_SELLER.json b/examples/test_case_data/localmeta/measure/test_kylin_cube_with_slr_left_join_ready/TOP_SELLER.json
new file mode 100644
index 0000000..a1daafe
--- /dev/null
+++ b/examples/test_case_data/localmeta/measure/test_kylin_cube_with_slr_left_join_ready/TOP_SELLER.json
@@ -0,0 +1,9 @@
+{
+  "uuid" : "f0cbdd45-544a-8244-06ba-fda9b5350027",
+  "last_modified" : 1556584529364,
+  "version" : "2.6.0.20500",
+  "name" : "TOP_SELLER",
+  "cube_name" : "test_kylin_cube_with_slr_left_join_ready",
+  "segments_name" : [ "1eaca32a-a33e-4b69-83dd-xxe8b1f8dddd" ],
+  "online" : true
+}
\ No newline at end of file
diff --git a/examples/test_case_data/localmeta/measure/test_kylin_cube_with_slr_left_join_ready/TRANS_CNT.json b/examples/test_case_data/localmeta/measure/test_kylin_cube_with_slr_left_join_ready/TRANS_CNT.json
new file mode 100644
index 0000000..4d78406
--- /dev/null
+++ b/examples/test_case_data/localmeta/measure/test_kylin_cube_with_slr_left_join_ready/TRANS_CNT.json
@@ -0,0 +1,9 @@
+{
+  "uuid" : "81a0ef0f-02ee-9498-e69e-7e7aaf95f5e3",
+  "last_modified" : 1556584529356,
+  "version" : "2.6.0.20500",
+  "name" : "TRANS_CNT",
+  "cube_name" : "test_kylin_cube_with_slr_left_join_ready",
+  "segments_name" : [ "1eaca32a-a33e-4b69-83dd-xxe8b1f8dddd" ],
+  "online" : true
+}
\ No newline at end of file
diff --git a/examples/test_case_data/localmeta/measure/test_kylin_cube_with_slr_ready/GMV_MAX.json b/examples/test_case_data/localmeta/measure/test_kylin_cube_with_slr_ready/GMV_MAX.json
new file mode 100644
index 0000000..92d6e22
--- /dev/null
+++ b/examples/test_case_data/localmeta/measure/test_kylin_cube_with_slr_ready/GMV_MAX.json
@@ -0,0 +1,9 @@
+{
+  "uuid" : "9354668b-57d5-fc1c-6f8e-82915ce25cf8",
+  "last_modified" : 1556584529373,
+  "version" : "2.6.0.20500",
+  "name" : "GMV_MAX",
+  "cube_name" : "test_kylin_cube_with_slr_ready",
+  "segments_name" : [ "20130331080000_20131212080000" ],
+  "online" : true
+}
\ No newline at end of file
diff --git a/examples/test_case_data/localmeta/measure/test_kylin_cube_with_slr_ready/GMV_MIN.json b/examples/test_case_data/localmeta/measure/test_kylin_cube_with_slr_ready/GMV_MIN.json
new file mode 100644
index 0000000..2a9650a
--- /dev/null
+++ b/examples/test_case_data/localmeta/measure/test_kylin_cube_with_slr_ready/GMV_MIN.json
@@ -0,0 +1,9 @@
+{
+  "uuid" : "f2d73907-61c4-cab8-36a4-2f9987112cb0",
+  "last_modified" : 1556584529371,
+  "version" : "2.6.0.20500",
+  "name" : "GMV_MIN",
+  "cube_name" : "test_kylin_cube_with_slr_ready",
+  "segments_name" : [ "20130331080000_20131212080000" ],
+  "online" : true
+}
\ No newline at end of file
diff --git a/examples/test_case_data/localmeta/measure/test_kylin_cube_with_slr_ready/GMV_SUM.json b/examples/test_case_data/localmeta/measure/test_kylin_cube_with_slr_ready/GMV_SUM.json
new file mode 100644
index 0000000..73ffb4f
--- /dev/null
+++ b/examples/test_case_data/localmeta/measure/test_kylin_cube_with_slr_ready/GMV_SUM.json
@@ -0,0 +1,9 @@
+{
+  "uuid" : "b9c5d764-2197-6c51-9bc0-0f65383b976c",
+  "last_modified" : 1556584529367,
+  "version" : "2.6.0.20500",
+  "name" : "GMV_SUM",
+  "cube_name" : "test_kylin_cube_with_slr_ready",
+  "segments_name" : [ "20130331080000_20131212080000" ],
+  "online" : true
+}
\ No newline at end of file
diff --git a/examples/test_case_data/localmeta/measure/test_kylin_cube_with_slr_ready/ITEM_COUNT_SUM.json b/examples/test_case_data/localmeta/measure/test_kylin_cube_with_slr_ready/ITEM_COUNT_SUM.json
new file mode 100644
index 0000000..708fc0d
--- /dev/null
+++ b/examples/test_case_data/localmeta/measure/test_kylin_cube_with_slr_ready/ITEM_COUNT_SUM.json
@@ -0,0 +1,9 @@
+{
+  "uuid" : "90dec7a9-966e-9a50-c587-434b181795ad",
+  "last_modified" : 1556584529379,
+  "version" : "2.6.0.20500",
+  "name" : "ITEM_COUNT_SUM",
+  "cube_name" : "test_kylin_cube_with_slr_ready",
+  "segments_name" : [ "20130331080000_20131212080000" ],
+  "online" : true
+}
\ No newline at end of file
diff --git a/examples/test_case_data/localmeta/measure/test_kylin_cube_with_slr_ready/TRANS_CNT.json b/examples/test_case_data/localmeta/measure/test_kylin_cube_with_slr_ready/TRANS_CNT.json
new file mode 100644
index 0000000..e50098f
--- /dev/null
+++ b/examples/test_case_data/localmeta/measure/test_kylin_cube_with_slr_ready/TRANS_CNT.json
@@ -0,0 +1,9 @@
+{
+  "uuid" : "adcfd0fa-850e-2714-21fd-ca85484dbbfe",
+  "last_modified" : 1556584529376,
+  "version" : "2.6.0.20500",
+  "name" : "TRANS_CNT",
+  "cube_name" : "test_kylin_cube_with_slr_ready",
+  "segments_name" : [ "20130331080000_20131212080000" ],
+  "online" : true
+}
\ No newline at end of file
diff --git a/examples/test_case_data/localmeta/measure/test_kylin_cube_with_slr_ready_2_segments/GMV_MAX.json b/examples/test_case_data/localmeta/measure/test_kylin_cube_with_slr_ready_2_segments/GMV_MAX.json
new file mode 100644
index 0000000..cd2bb45
--- /dev/null
+++ b/examples/test_case_data/localmeta/measure/test_kylin_cube_with_slr_ready_2_segments/GMV_MAX.json
@@ -0,0 +1,9 @@
+{
+  "uuid" : "3eaa2a6c-153c-0319-8ea3-2e5996cd8f0e",
+  "last_modified" : 1556584529388,
+  "version" : "2.6.0.20500",
+  "name" : "GMV_MAX",
+  "cube_name" : "test_kylin_cube_with_slr_ready_2_segments",
+  "segments_name" : [ "19691231160000_20131112000000", "20131112000000_20131212000000" ],
+  "online" : true
+}
\ No newline at end of file
diff --git a/examples/test_case_data/localmeta/measure/test_kylin_cube_with_slr_ready_2_segments/GMV_MIN.json b/examples/test_case_data/localmeta/measure/test_kylin_cube_with_slr_ready_2_segments/GMV_MIN.json
new file mode 100644
index 0000000..66939c7
--- /dev/null
+++ b/examples/test_case_data/localmeta/measure/test_kylin_cube_with_slr_ready_2_segments/GMV_MIN.json
@@ -0,0 +1,9 @@
+{
+  "uuid" : "2cc0154f-270a-b838-ace8-5ec4e721d768",
+  "last_modified" : 1556584529385,
+  "version" : "2.6.0.20500",
+  "name" : "GMV_MIN",
+  "cube_name" : "test_kylin_cube_with_slr_ready_2_segments",
+  "segments_name" : [ "19691231160000_20131112000000", "20131112000000_20131212000000" ],
+  "online" : true
+}
\ No newline at end of file
diff --git a/examples/test_case_data/localmeta/measure/test_kylin_cube_with_slr_ready_2_segments/GMV_SUM.json b/examples/test_case_data/localmeta/measure/test_kylin_cube_with_slr_ready_2_segments/GMV_SUM.json
new file mode 100644
index 0000000..a593ff9
--- /dev/null
+++ b/examples/test_case_data/localmeta/measure/test_kylin_cube_with_slr_ready_2_segments/GMV_SUM.json
@@ -0,0 +1,9 @@
+{
+  "uuid" : "bee141fa-4860-8975-7397-72f29f16b5b2",
+  "last_modified" : 1556584529382,
+  "version" : "2.6.0.20500",
+  "name" : "GMV_SUM",
+  "cube_name" : "test_kylin_cube_with_slr_ready_2_segments",
+  "segments_name" : [ "19691231160000_20131112000000", "20131112000000_20131212000000" ],
+  "online" : true
+}
\ No newline at end of file
diff --git a/examples/test_case_data/localmeta/measure/test_kylin_cube_with_slr_ready_2_segments/ITEM_COUNT_SUM.json b/examples/test_case_data/localmeta/measure/test_kylin_cube_with_slr_ready_2_segments/ITEM_COUNT_SUM.json
new file mode 100644
index 0000000..5e97979
--- /dev/null
+++ b/examples/test_case_data/localmeta/measure/test_kylin_cube_with_slr_ready_2_segments/ITEM_COUNT_SUM.json
@@ -0,0 +1,9 @@
+{
+  "uuid" : "b786963b-3774-3b0b-3f15-fc131df55a2c",
+  "last_modified" : 1556584529394,
+  "version" : "2.6.0.20500",
+  "name" : "ITEM_COUNT_SUM",
+  "cube_name" : "test_kylin_cube_with_slr_ready_2_segments",
+  "segments_name" : [ "19691231160000_20131112000000", "20131112000000_20131212000000" ],
+  "online" : true
+}
\ No newline at end of file
diff --git a/examples/test_case_data/localmeta/measure/test_kylin_cube_with_slr_ready_2_segments/TRANS_CNT.json b/examples/test_case_data/localmeta/measure/test_kylin_cube_with_slr_ready_2_segments/TRANS_CNT.json
new file mode 100644
index 0000000..8188982
--- /dev/null
+++ b/examples/test_case_data/localmeta/measure/test_kylin_cube_with_slr_ready_2_segments/TRANS_CNT.json
@@ -0,0 +1,9 @@
+{
+  "uuid" : "56a2de0f-1f19-d898-9eb1-53ad4a7404c7",
+  "last_modified" : 1556584529391,
+  "version" : "2.6.0.20500",
+  "name" : "TRANS_CNT",
+  "cube_name" : "test_kylin_cube_with_slr_ready_2_segments",
+  "segments_name" : [ "19691231160000_20131112000000", "20131112000000_20131212000000" ],
+  "online" : true
+}
\ No newline at end of file
diff --git a/examples/test_case_data/localmeta/measure/test_kylin_cube_with_slr_ready_3_segments/GMV_MAX.json b/examples/test_case_data/localmeta/measure/test_kylin_cube_with_slr_ready_3_segments/GMV_MAX.json
new file mode 100644
index 0000000..60e8459
--- /dev/null
+++ b/examples/test_case_data/localmeta/measure/test_kylin_cube_with_slr_ready_3_segments/GMV_MAX.json
@@ -0,0 +1,9 @@
+{
+  "uuid" : "caa210a4-1ab0-e3fb-4605-b50e2a05d566",
+  "last_modified" : 1556584529403,
+  "version" : "2.6.0.20500",
+  "name" : "GMV_MAX",
+  "cube_name" : "test_kylin_cube_with_slr_ready_3_segments",
+  "segments_name" : [ "19691231160000_20131112000000", "20131112000000_20131212000000" ],
+  "online" : true
+}
\ No newline at end of file
diff --git a/examples/test_case_data/localmeta/measure/test_kylin_cube_with_slr_ready_3_segments/GMV_MIN.json b/examples/test_case_data/localmeta/measure/test_kylin_cube_with_slr_ready_3_segments/GMV_MIN.json
new file mode 100644
index 0000000..736ea08
--- /dev/null
+++ b/examples/test_case_data/localmeta/measure/test_kylin_cube_with_slr_ready_3_segments/GMV_MIN.json
@@ -0,0 +1,9 @@
+{
+  "uuid" : "85973492-bcf2-cc86-efd0-b8b208201ccf",
+  "last_modified" : 1556584529400,
+  "version" : "2.6.0.20500",
+  "name" : "GMV_MIN",
+  "cube_name" : "test_kylin_cube_with_slr_ready_3_segments",
+  "segments_name" : [ "19691231160000_20131112000000", "20131112000000_20131212000000" ],
+  "online" : true
+}
\ No newline at end of file
diff --git a/examples/test_case_data/localmeta/measure/test_kylin_cube_with_slr_ready_3_segments/GMV_SUM.json b/examples/test_case_data/localmeta/measure/test_kylin_cube_with_slr_ready_3_segments/GMV_SUM.json
new file mode 100644
index 0000000..3cc7f2c
--- /dev/null
+++ b/examples/test_case_data/localmeta/measure/test_kylin_cube_with_slr_ready_3_segments/GMV_SUM.json
@@ -0,0 +1,9 @@
+{
+  "uuid" : "31655f53-c5f7-e276-5d07-4bf96b88c263",
+  "last_modified" : 1556584529397,
+  "version" : "2.6.0.20500",
+  "name" : "GMV_SUM",
+  "cube_name" : "test_kylin_cube_with_slr_ready_3_segments",
+  "segments_name" : [ "19691231160000_20131112000000", "20131112000000_20131212000000" ],
+  "online" : true
+}
\ No newline at end of file
diff --git a/examples/test_case_data/localmeta/measure/test_kylin_cube_with_slr_ready_3_segments/ITEM_COUNT_SUM.json b/examples/test_case_data/localmeta/measure/test_kylin_cube_with_slr_ready_3_segments/ITEM_COUNT_SUM.json
new file mode 100644
index 0000000..cd64ea5
--- /dev/null
+++ b/examples/test_case_data/localmeta/measure/test_kylin_cube_with_slr_ready_3_segments/ITEM_COUNT_SUM.json
@@ -0,0 +1,9 @@
+{
+  "uuid" : "c3009871-15fb-27ef-b1d1-955be0f15781",
+  "last_modified" : 1556584529409,
+  "version" : "2.6.0.20500",
+  "name" : "ITEM_COUNT_SUM",
+  "cube_name" : "test_kylin_cube_with_slr_ready_3_segments",
+  "segments_name" : [ "19691231160000_20131112000000", "20131112000000_20131212000000" ],
+  "online" : true
+}
\ No newline at end of file
diff --git a/examples/test_case_data/localmeta/measure/test_kylin_cube_with_slr_ready_3_segments/TRANS_CNT.json b/examples/test_case_data/localmeta/measure/test_kylin_cube_with_slr_ready_3_segments/TRANS_CNT.json
new file mode 100644
index 0000000..878203d
--- /dev/null
+++ b/examples/test_case_data/localmeta/measure/test_kylin_cube_with_slr_ready_3_segments/TRANS_CNT.json
@@ -0,0 +1,9 @@
+{
+  "uuid" : "43766b32-114b-5a33-4088-1d1f7684a26d",
+  "last_modified" : 1556584529406,
+  "version" : "2.6.0.20500",
+  "name" : "TRANS_CNT",
+  "cube_name" : "test_kylin_cube_with_slr_ready_3_segments",
+  "segments_name" : [ "19691231160000_20131112000000", "20131112000000_20131212000000" ],
+  "online" : true
+}
\ No newline at end of file
diff --git a/examples/test_case_data/localmeta/measure/test_kylin_cube_without_slr_empty/CAL_DT_RAW.json b/examples/test_case_data/localmeta/measure/test_kylin_cube_without_slr_empty/CAL_DT_RAW.json
new file mode 100644
index 0000000..b37a104
--- /dev/null
+++ b/examples/test_case_data/localmeta/measure/test_kylin_cube_without_slr_empty/CAL_DT_RAW.json
@@ -0,0 +1,9 @@
+{
+  "uuid" : "5f13b694-ca25-6815-604a-d28750b7e947",
+  "last_modified" : 1556584529431,
+  "version" : "2.6.0.20500",
+  "name" : "CAL_DT_RAW",
+  "cube_name" : "test_kylin_cube_without_slr_empty",
+  "segments_name" : [ ],
+  "online" : true
+}
\ No newline at end of file
diff --git a/examples/test_case_data/localmeta/measure/test_kylin_cube_without_slr_empty/GMV_MAX.json b/examples/test_case_data/localmeta/measure/test_kylin_cube_without_slr_empty/GMV_MAX.json
new file mode 100644
index 0000000..61717d7
--- /dev/null
+++ b/examples/test_case_data/localmeta/measure/test_kylin_cube_without_slr_empty/GMV_MAX.json
@@ -0,0 +1,9 @@
+{
+  "uuid" : "caa4fd81-b2cd-acd6-56e4-18a24d9e2b7a",
+  "last_modified" : 1556584529417,
+  "version" : "2.6.0.20500",
+  "name" : "GMV_MAX",
+  "cube_name" : "test_kylin_cube_without_slr_empty",
+  "segments_name" : [ ],
+  "online" : true
+}
\ No newline at end of file
diff --git a/examples/test_case_data/localmeta/measure/test_kylin_cube_without_slr_empty/GMV_MIN.json b/examples/test_case_data/localmeta/measure/test_kylin_cube_without_slr_empty/GMV_MIN.json
new file mode 100644
index 0000000..00e2d96
--- /dev/null
+++ b/examples/test_case_data/localmeta/measure/test_kylin_cube_without_slr_empty/GMV_MIN.json
@@ -0,0 +1,9 @@
+{
+  "uuid" : "d9288ca0-95a7-503e-9e04-ce0881e362ce",
+  "last_modified" : 1556584529415,
+  "version" : "2.6.0.20500",
+  "name" : "GMV_MIN",
+  "cube_name" : "test_kylin_cube_without_slr_empty",
+  "segments_name" : [ ],
+  "online" : true
+}
\ No newline at end of file
diff --git a/examples/test_case_data/localmeta/measure/test_kylin_cube_without_slr_empty/GMV_SUM.json b/examples/test_case_data/localmeta/measure/test_kylin_cube_without_slr_empty/GMV_SUM.json
new file mode 100644
index 0000000..4e127ef
--- /dev/null
+++ b/examples/test_case_data/localmeta/measure/test_kylin_cube_without_slr_empty/GMV_SUM.json
@@ -0,0 +1,9 @@
+{
+  "uuid" : "f3c0b2eb-e370-d841-609a-24eb781421de",
+  "last_modified" : 1556584529411,
+  "version" : "2.6.0.20500",
+  "name" : "GMV_SUM",
+  "cube_name" : "test_kylin_cube_without_slr_empty",
+  "segments_name" : [ ],
+  "online" : true
+}
\ No newline at end of file
diff --git a/examples/test_case_data/localmeta/measure/test_kylin_cube_without_slr_empty/ITEM_COUNT_SUM.json b/examples/test_case_data/localmeta/measure/test_kylin_cube_without_slr_empty/ITEM_COUNT_SUM.json
new file mode 100644
index 0000000..5838c15
--- /dev/null
+++ b/examples/test_case_data/localmeta/measure/test_kylin_cube_without_slr_empty/ITEM_COUNT_SUM.json
@@ -0,0 +1,9 @@
+{
+  "uuid" : "879fd068-97ac-411c-874e-9f0871cd6093",
+  "last_modified" : 1556584529423,
+  "version" : "2.6.0.20500",
+  "name" : "ITEM_COUNT_SUM",
+  "cube_name" : "test_kylin_cube_without_slr_empty",
+  "segments_name" : [ ],
+  "online" : true
+}
\ No newline at end of file
diff --git a/examples/test_case_data/localmeta/measure/test_kylin_cube_without_slr_empty/LEAF_CATEG_ID_RAW.json b/examples/test_case_data/localmeta/measure/test_kylin_cube_without_slr_empty/LEAF_CATEG_ID_RAW.json
new file mode 100644
index 0000000..40fc8ba
--- /dev/null
+++ b/examples/test_case_data/localmeta/measure/test_kylin_cube_without_slr_empty/LEAF_CATEG_ID_RAW.json
@@ -0,0 +1,9 @@
+{
+  "uuid" : "a7425727-cc16-862b-9252-d809304fb095",
+  "last_modified" : 1556584529437,
+  "version" : "2.6.0.20500",
+  "name" : "LEAF_CATEG_ID_RAW",
+  "cube_name" : "test_kylin_cube_without_slr_empty",
+  "segments_name" : [ ],
+  "online" : true
+}
\ No newline at end of file
diff --git a/examples/test_case_data/localmeta/measure/test_kylin_cube_without_slr_empty/LSTG_FORMAT_NAME_RAW.json b/examples/test_case_data/localmeta/measure/test_kylin_cube_without_slr_empty/LSTG_FORMAT_NAME_RAW.json
new file mode 100644
index 0000000..2f42ae4
--- /dev/null
+++ b/examples/test_case_data/localmeta/measure/test_kylin_cube_without_slr_empty/LSTG_FORMAT_NAME_RAW.json
@@ -0,0 +1,9 @@
+{
+  "uuid" : "75fb4890-c688-bab0-483b-ae43c3e96fe0",
+  "last_modified" : 1556584529434,
+  "version" : "2.6.0.20500",
+  "name" : "LSTG_FORMAT_NAME_RAW",
+  "cube_name" : "test_kylin_cube_without_slr_empty",
+  "segments_name" : [ ],
+  "online" : true
+}
\ No newline at end of file
diff --git a/examples/test_case_data/localmeta/measure/test_kylin_cube_without_slr_empty/PRICE_RAW.json b/examples/test_case_data/localmeta/measure/test_kylin_cube_without_slr_empty/PRICE_RAW.json
new file mode 100644
index 0000000..6bae11d
--- /dev/null
+++ b/examples/test_case_data/localmeta/measure/test_kylin_cube_without_slr_empty/PRICE_RAW.json
@@ -0,0 +1,9 @@
+{
+  "uuid" : "5bd4e9b7-bb1d-c98c-b7d8-b1c52e6d9806",
+  "last_modified" : 1556584529439,
+  "version" : "2.6.0.20500",
+  "name" : "PRICE_RAW",
+  "cube_name" : "test_kylin_cube_without_slr_empty",
+  "segments_name" : [ ],
+  "online" : true
+}
\ No newline at end of file
diff --git a/examples/test_case_data/localmeta/measure/test_kylin_cube_without_slr_empty/SITE_EXTENDED_1.json b/examples/test_case_data/localmeta/measure/test_kylin_cube_without_slr_empty/SITE_EXTENDED_1.json
new file mode 100644
index 0000000..ded7286
--- /dev/null
+++ b/examples/test_case_data/localmeta/measure/test_kylin_cube_without_slr_empty/SITE_EXTENDED_1.json
@@ -0,0 +1,9 @@
+{
+  "uuid" : "ef5aebba-f293-8c65-8139-29333c17f183",
+  "last_modified" : 1556584529426,
+  "version" : "2.6.0.20500",
+  "name" : "SITE_EXTENDED_1",
+  "cube_name" : "test_kylin_cube_without_slr_empty",
+  "segments_name" : [ ],
+  "online" : true
+}
\ No newline at end of file
diff --git a/examples/test_case_data/localmeta/measure/test_kylin_cube_without_slr_empty/SITE_EXTENDED_2.json b/examples/test_case_data/localmeta/measure/test_kylin_cube_without_slr_empty/SITE_EXTENDED_2.json
new file mode 100644
index 0000000..2882eb4
--- /dev/null
+++ b/examples/test_case_data/localmeta/measure/test_kylin_cube_without_slr_empty/SITE_EXTENDED_2.json
@@ -0,0 +1,9 @@
+{
+  "uuid" : "9cfbdd03-315c-6fe3-2150-4460dafc5cc9",
+  "last_modified" : 1556584529428,
+  "version" : "2.6.0.20500",
+  "name" : "SITE_EXTENDED_2",
+  "cube_name" : "test_kylin_cube_without_slr_empty",
+  "segments_name" : [ ],
+  "online" : true
+}
\ No newline at end of file
diff --git a/examples/test_case_data/localmeta/measure/test_kylin_cube_without_slr_empty/TRANS_CNT.json b/examples/test_case_data/localmeta/measure/test_kylin_cube_without_slr_empty/TRANS_CNT.json
new file mode 100644
index 0000000..de2b400
--- /dev/null
+++ b/examples/test_case_data/localmeta/measure/test_kylin_cube_without_slr_empty/TRANS_CNT.json
@@ -0,0 +1,9 @@
+{
+  "uuid" : "caf46641-b6ed-0b7d-c3af-29abffcdc2c0",
+  "last_modified" : 1556584529420,
+  "version" : "2.6.0.20500",
+  "name" : "TRANS_CNT",
+  "cube_name" : "test_kylin_cube_without_slr_empty",
+  "segments_name" : [ ],
+  "online" : true
+}
\ No newline at end of file
diff --git a/examples/test_case_data/localmeta/measure/test_kylin_cube_without_slr_left_join_empty/CAL_DT_RAW.json b/examples/test_case_data/localmeta/measure/test_kylin_cube_without_slr_left_join_empty/CAL_DT_RAW.json
new file mode 100644
index 0000000..dc5baab
--- /dev/null
+++ b/examples/test_case_data/localmeta/measure/test_kylin_cube_without_slr_left_join_empty/CAL_DT_RAW.json
@@ -0,0 +1,9 @@
+{
+  "uuid" : "a05eba7a-5cd1-af83-7e90-092241752532",
+  "last_modified" : 1556584529469,
+  "version" : "2.6.0.20500",
+  "name" : "CAL_DT_RAW",
+  "cube_name" : "test_kylin_cube_without_slr_left_join_empty",
+  "segments_name" : [ ],
+  "online" : true
+}
\ No newline at end of file
diff --git a/examples/test_case_data/localmeta/measure/test_kylin_cube_without_slr_left_join_empty/GMV_MAX.json b/examples/test_case_data/localmeta/measure/test_kylin_cube_without_slr_left_join_empty/GMV_MAX.json
new file mode 100644
index 0000000..8c3096a
--- /dev/null
+++ b/examples/test_case_data/localmeta/measure/test_kylin_cube_without_slr_left_join_empty/GMV_MAX.json
@@ -0,0 +1,9 @@
+{
+  "uuid" : "8e8117f7-5f84-ad42-ee99-20cf63b82726",
+  "last_modified" : 1556584529449,
+  "version" : "2.6.0.20500",
+  "name" : "GMV_MAX",
+  "cube_name" : "test_kylin_cube_without_slr_left_join_empty",
+  "segments_name" : [ ],
+  "online" : true
+}
\ No newline at end of file
diff --git a/examples/test_case_data/localmeta/measure/test_kylin_cube_without_slr_left_join_empty/GMV_MIN.json b/examples/test_case_data/localmeta/measure/test_kylin_cube_without_slr_left_join_empty/GMV_MIN.json
new file mode 100644
index 0000000..8578837
--- /dev/null
+++ b/examples/test_case_data/localmeta/measure/test_kylin_cube_without_slr_left_join_empty/GMV_MIN.json
@@ -0,0 +1,9 @@
+{
+  "uuid" : "26c85e51-2264-73d2-241f-211e6a6578c8",
+  "last_modified" : 1556584529446,
+  "version" : "2.6.0.20500",
+  "name" : "GMV_MIN",
+  "cube_name" : "test_kylin_cube_without_slr_left_join_empty",
+  "segments_name" : [ ],
+  "online" : true
+}
\ No newline at end of file
diff --git a/examples/test_case_data/localmeta/measure/test_kylin_cube_without_slr_left_join_empty/GMV_SUM.json b/examples/test_case_data/localmeta/measure/test_kylin_cube_without_slr_left_join_empty/GMV_SUM.json
new file mode 100644
index 0000000..56be699
--- /dev/null
+++ b/examples/test_case_data/localmeta/measure/test_kylin_cube_without_slr_left_join_empty/GMV_SUM.json
@@ -0,0 +1,9 @@
+{
+  "uuid" : "63e1c52e-4b7b-76d9-d88d-597b310b35c8",
+  "last_modified" : 1556584529442,
+  "version" : "2.6.0.20500",
+  "name" : "GMV_SUM",
+  "cube_name" : "test_kylin_cube_without_slr_left_join_empty",
+  "segments_name" : [ ],
+  "online" : true
+}
\ No newline at end of file
diff --git a/examples/test_case_data/localmeta/measure/test_kylin_cube_without_slr_left_join_empty/ITEM_COUNT_SUM.json b/examples/test_case_data/localmeta/measure/test_kylin_cube_without_slr_left_join_empty/ITEM_COUNT_SUM.json
new file mode 100644
index 0000000..782f05e
--- /dev/null
+++ b/examples/test_case_data/localmeta/measure/test_kylin_cube_without_slr_left_join_empty/ITEM_COUNT_SUM.json
@@ -0,0 +1,9 @@
+{
+  "uuid" : "9d5386da-4c3a-31eb-28a9-71c27803c658",
+  "last_modified" : 1556584529454,
+  "version" : "2.6.0.20500",
+  "name" : "ITEM_COUNT_SUM",
+  "cube_name" : "test_kylin_cube_without_slr_left_join_empty",
+  "segments_name" : [ ],
+  "online" : true
+}
\ No newline at end of file
diff --git a/examples/test_case_data/localmeta/measure/test_kylin_cube_without_slr_left_join_empty/LEAF_CATEG_ID_RAW.json b/examples/test_case_data/localmeta/measure/test_kylin_cube_without_slr_left_join_empty/LEAF_CATEG_ID_RAW.json
new file mode 100644
index 0000000..829b6da
--- /dev/null
+++ b/examples/test_case_data/localmeta/measure/test_kylin_cube_without_slr_left_join_empty/LEAF_CATEG_ID_RAW.json
@@ -0,0 +1,9 @@
+{
+  "uuid" : "36ece6c6-71e8-0422-b087-bd0056989dc4",
+  "last_modified" : 1556584529474,
+  "version" : "2.6.0.20500",
+  "name" : "LEAF_CATEG_ID_RAW",
+  "cube_name" : "test_kylin_cube_without_slr_left_join_empty",
+  "segments_name" : [ ],
+  "online" : true
+}
\ No newline at end of file
diff --git a/examples/test_case_data/localmeta/measure/test_kylin_cube_without_slr_left_join_empty/LSTG_FORMAT_NAME_RAW.json b/examples/test_case_data/localmeta/measure/test_kylin_cube_without_slr_left_join_empty/LSTG_FORMAT_NAME_RAW.json
new file mode 100644
index 0000000..b98f723
--- /dev/null
+++ b/examples/test_case_data/localmeta/measure/test_kylin_cube_without_slr_left_join_empty/LSTG_FORMAT_NAME_RAW.json
@@ -0,0 +1,9 @@
+{
+  "uuid" : "f8dd7d77-97d4-9478-5b5f-1823d56888d3",
+  "last_modified" : 1556584529471,
+  "version" : "2.6.0.20500",
+  "name" : "LSTG_FORMAT_NAME_RAW",
+  "cube_name" : "test_kylin_cube_without_slr_left_join_empty",
+  "segments_name" : [ ],
+  "online" : true
+}
\ No newline at end of file
diff --git a/examples/test_case_data/localmeta/measure/test_kylin_cube_without_slr_left_join_empty/PRICE_RAW.json b/examples/test_case_data/localmeta/measure/test_kylin_cube_without_slr_left_join_empty/PRICE_RAW.json
new file mode 100644
index 0000000..f8d7dc0
--- /dev/null
+++ b/examples/test_case_data/localmeta/measure/test_kylin_cube_without_slr_left_join_empty/PRICE_RAW.json
@@ -0,0 +1,9 @@
+{
+  "uuid" : "9ed21d54-9294-476b-1f4b-272bf6b7e44c",
+  "last_modified" : 1556584529477,
+  "version" : "2.6.0.20500",
+  "name" : "PRICE_RAW",
+  "cube_name" : "test_kylin_cube_without_slr_left_join_empty",
+  "segments_name" : [ ],
+  "online" : true
+}
\ No newline at end of file
diff --git a/examples/test_case_data/localmeta/measure/test_kylin_cube_without_slr_left_join_empty/SELLER_CNT_BITMAP.json b/examples/test_case_data/localmeta/measure/test_kylin_cube_without_slr_left_join_empty/SELLER_CNT_BITMAP.json
new file mode 100644
index 0000000..a010e16
--- /dev/null
+++ b/examples/test_case_data/localmeta/measure/test_kylin_cube_without_slr_left_join_empty/SELLER_CNT_BITMAP.json
@@ -0,0 +1,9 @@
+{
+  "uuid" : "7cdc1c1d-9cd2-30bd-1679-0e27c383c764",
+  "last_modified" : 1556584529457,
+  "version" : "2.6.0.20500",
+  "name" : "SELLER_CNT_BITMAP",
+  "cube_name" : "test_kylin_cube_without_slr_left_join_empty",
+  "segments_name" : [ ],
+  "online" : true
+}
\ No newline at end of file
diff --git a/examples/test_case_data/localmeta/measure/test_kylin_cube_without_slr_left_join_empty/SELLER_FORMAT_CNT.json b/examples/test_case_data/localmeta/measure/test_kylin_cube_without_slr_left_join_empty/SELLER_FORMAT_CNT.json
new file mode 100644
index 0000000..e74f46e
--- /dev/null
+++ b/examples/test_case_data/localmeta/measure/test_kylin_cube_without_slr_left_join_empty/SELLER_FORMAT_CNT.json
@@ -0,0 +1,9 @@
+{
+  "uuid" : "20ac5007-2cb6-fe5e-9fa4-be719d3d55e3",
+  "last_modified" : 1556584529463,
+  "version" : "2.6.0.20500",
+  "name" : "SELLER_FORMAT_CNT",
+  "cube_name" : "test_kylin_cube_without_slr_left_join_empty",
+  "segments_name" : [ ],
+  "online" : true
+}
\ No newline at end of file
diff --git a/examples/test_case_data/localmeta/measure/test_kylin_cube_without_slr_left_join_empty/TOP_SELLER.json b/examples/test_case_data/localmeta/measure/test_kylin_cube_without_slr_left_join_empty/TOP_SELLER.json
new file mode 100644
index 0000000..63c8cd8
--- /dev/null
+++ b/examples/test_case_data/localmeta/measure/test_kylin_cube_without_slr_left_join_empty/TOP_SELLER.json
@@ -0,0 +1,9 @@
+{
+  "uuid" : "d53f1971-95c6-2bc6-bec1-42dcfc443843",
+  "last_modified" : 1556584529466,
+  "version" : "2.6.0.20500",
+  "name" : "TOP_SELLER",
+  "cube_name" : "test_kylin_cube_without_slr_left_join_empty",
+  "segments_name" : [ ],
+  "online" : true
+}
\ No newline at end of file
diff --git a/examples/test_case_data/localmeta/measure/test_kylin_cube_without_slr_left_join_empty/TRANS_CNT.json b/examples/test_case_data/localmeta/measure/test_kylin_cube_without_slr_left_join_empty/TRANS_CNT.json
new file mode 100644
index 0000000..f721b10
--- /dev/null
+++ b/examples/test_case_data/localmeta/measure/test_kylin_cube_without_slr_left_join_empty/TRANS_CNT.json
@@ -0,0 +1,9 @@
+{
+  "uuid" : "f36f3ff5-8c9f-3226-42b8-b752e35b6332",
+  "last_modified" : 1556584529452,
+  "version" : "2.6.0.20500",
+  "name" : "TRANS_CNT",
+  "cube_name" : "test_kylin_cube_without_slr_left_join_empty",
+  "segments_name" : [ ],
+  "online" : true
+}
\ No newline at end of file
diff --git a/examples/test_case_data/localmeta/measure/test_kylin_cube_without_slr_left_join_empty/USER_COUNT_BITMAP.json b/examples/test_case_data/localmeta/measure/test_kylin_cube_without_slr_left_join_empty/USER_COUNT_BITMAP.json
new file mode 100644
index 0000000..d34ad29
--- /dev/null
+++ b/examples/test_case_data/localmeta/measure/test_kylin_cube_without_slr_left_join_empty/USER_COUNT_BITMAP.json
@@ -0,0 +1,9 @@
+{
+  "uuid" : "e75bbe76-202f-3984-41be-45b18c32b471",
+  "last_modified" : 1556584529460,
+  "version" : "2.6.0.20500",
+  "name" : "USER_COUNT_BITMAP",
+  "cube_name" : "test_kylin_cube_without_slr_left_join_empty",
+  "segments_name" : [ ],
+  "online" : true
+}
\ No newline at end of file
diff --git a/examples/test_case_data/localmeta/measure/test_kylin_cube_without_slr_left_join_ready/CAL_DT_RAW.json b/examples/test_case_data/localmeta/measure/test_kylin_cube_without_slr_left_join_ready/CAL_DT_RAW.json
new file mode 100644
index 0000000..028cf06
--- /dev/null
+++ b/examples/test_case_data/localmeta/measure/test_kylin_cube_without_slr_left_join_ready/CAL_DT_RAW.json
@@ -0,0 +1,9 @@
+{
+  "uuid" : "c32b5fe7-b588-863a-f482-e28dbba29aca",
+  "last_modified" : 1556584529506,
+  "version" : "2.6.0.20500",
+  "name" : "CAL_DT_RAW",
+  "cube_name" : "test_kylin_cube_without_slr_left_join_ready",
+  "segments_name" : [ "2accs32a-a33e-4b69-83dd-xxe8b1f8dddd" ],
+  "online" : true
+}
\ No newline at end of file
diff --git a/examples/test_case_data/localmeta/measure/test_kylin_cube_without_slr_left_join_ready/GMV_MAX.json b/examples/test_case_data/localmeta/measure/test_kylin_cube_without_slr_left_join_ready/GMV_MAX.json
new file mode 100644
index 0000000..d96ac4a
--- /dev/null
+++ b/examples/test_case_data/localmeta/measure/test_kylin_cube_without_slr_left_join_ready/GMV_MAX.json
@@ -0,0 +1,9 @@
+{
+  "uuid" : "5da0a571-2521-3361-5f4b-0e53d5c3f464",
+  "last_modified" : 1556584529487,
+  "version" : "2.6.0.20500",
+  "name" : "GMV_MAX",
+  "cube_name" : "test_kylin_cube_without_slr_left_join_ready",
+  "segments_name" : [ "2accs32a-a33e-4b69-83dd-xxe8b1f8dddd" ],
+  "online" : true
+}
\ No newline at end of file
diff --git a/examples/test_case_data/localmeta/measure/test_kylin_cube_without_slr_left_join_ready/GMV_MIN.json b/examples/test_case_data/localmeta/measure/test_kylin_cube_without_slr_left_join_ready/GMV_MIN.json
new file mode 100644
index 0000000..7f5bb83
--- /dev/null
+++ b/examples/test_case_data/localmeta/measure/test_kylin_cube_without_slr_left_join_ready/GMV_MIN.json
@@ -0,0 +1,9 @@
+{
+  "uuid" : "8c422002-a7a3-fad3-e7f1-7384a12afac5",
+  "last_modified" : 1556584529484,
+  "version" : "2.6.0.20500",
+  "name" : "GMV_MIN",
+  "cube_name" : "test_kylin_cube_without_slr_left_join_ready",
+  "segments_name" : [ "2accs32a-a33e-4b69-83dd-xxe8b1f8dddd" ],
+  "online" : true
+}
\ No newline at end of file
diff --git a/examples/test_case_data/localmeta/measure/test_kylin_cube_without_slr_left_join_ready/GMV_SUM.json b/examples/test_case_data/localmeta/measure/test_kylin_cube_without_slr_left_join_ready/GMV_SUM.json
new file mode 100644
index 0000000..6140f07
--- /dev/null
+++ b/examples/test_case_data/localmeta/measure/test_kylin_cube_without_slr_left_join_ready/GMV_SUM.json
@@ -0,0 +1,9 @@
+{
+  "uuid" : "5ed73b4a-94bb-8ec2-23dd-b36028b57ede",
+  "last_modified" : 1556584529481,
+  "version" : "2.6.0.20500",
+  "name" : "GMV_SUM",
+  "cube_name" : "test_kylin_cube_without_slr_left_join_ready",
+  "segments_name" : [ "2accs32a-a33e-4b69-83dd-xxe8b1f8dddd" ],
+  "online" : true
+}
\ No newline at end of file
diff --git a/examples/test_case_data/localmeta/measure/test_kylin_cube_without_slr_left_join_ready/ITEM_COUNT_SUM.json b/examples/test_case_data/localmeta/measure/test_kylin_cube_without_slr_left_join_ready/ITEM_COUNT_SUM.json
new file mode 100644
index 0000000..3a4e852
--- /dev/null
+++ b/examples/test_case_data/localmeta/measure/test_kylin_cube_without_slr_left_join_ready/ITEM_COUNT_SUM.json
@@ -0,0 +1,9 @@
+{
+  "uuid" : "4c4f7090-bb12-d421-9276-6504fc2319b5",
+  "last_modified" : 1556584529493,
+  "version" : "2.6.0.20500",
+  "name" : "ITEM_COUNT_SUM",
+  "cube_name" : "test_kylin_cube_without_slr_left_join_ready",
+  "segments_name" : [ "2accs32a-a33e-4b69-83dd-xxe8b1f8dddd" ],
+  "online" : true
+}
\ No newline at end of file
diff --git a/examples/test_case_data/localmeta/measure/test_kylin_cube_without_slr_left_join_ready/LEAF_CATEG_ID_RAW.json b/examples/test_case_data/localmeta/measure/test_kylin_cube_without_slr_left_join_ready/LEAF_CATEG_ID_RAW.json
new file mode 100644
index 0000000..09fd747
--- /dev/null
+++ b/examples/test_case_data/localmeta/measure/test_kylin_cube_without_slr_left_join_ready/LEAF_CATEG_ID_RAW.json
@@ -0,0 +1,9 @@
+{
+  "uuid" : "d7c59527-f762-43e8-644e-f37fa02d2b5f",
+  "last_modified" : 1556584529512,
+  "version" : "2.6.0.20500",
+  "name" : "LEAF_CATEG_ID_RAW",
+  "cube_name" : "test_kylin_cube_without_slr_left_join_ready",
+  "segments_name" : [ "2accs32a-a33e-4b69-83dd-xxe8b1f8dddd" ],
+  "online" : true
+}
\ No newline at end of file
diff --git a/examples/test_case_data/localmeta/measure/test_kylin_cube_without_slr_left_join_ready/LSTG_FORMAT_NAME_RAW.json b/examples/test_case_data/localmeta/measure/test_kylin_cube_without_slr_left_join_ready/LSTG_FORMAT_NAME_RAW.json
new file mode 100644
index 0000000..5c8e79e
--- /dev/null
+++ b/examples/test_case_data/localmeta/measure/test_kylin_cube_without_slr_left_join_ready/LSTG_FORMAT_NAME_RAW.json
@@ -0,0 +1,9 @@
+{
+  "uuid" : "3632fc8c-be1a-e8ea-3049-214a62371204",
+  "last_modified" : 1556584529509,
+  "version" : "2.6.0.20500",
+  "name" : "LSTG_FORMAT_NAME_RAW",
+  "cube_name" : "test_kylin_cube_without_slr_left_join_ready",
+  "segments_name" : [ "2accs32a-a33e-4b69-83dd-xxe8b1f8dddd" ],
+  "online" : true
+}
\ No newline at end of file
diff --git a/examples/test_case_data/localmeta/measure/test_kylin_cube_without_slr_left_join_ready/PRICE_RAW.json b/examples/test_case_data/localmeta/measure/test_kylin_cube_without_slr_left_join_ready/PRICE_RAW.json
new file mode 100644
index 0000000..78c2883
--- /dev/null
+++ b/examples/test_case_data/localmeta/measure/test_kylin_cube_without_slr_left_join_ready/PRICE_RAW.json
@@ -0,0 +1,9 @@
+{
+  "uuid" : "35d9f2df-6e1f-23f7-bb54-1b50453b02be",
+  "last_modified" : 1556584529515,
+  "version" : "2.6.0.20500",
+  "name" : "PRICE_RAW",
+  "cube_name" : "test_kylin_cube_without_slr_left_join_ready",
+  "segments_name" : [ "2accs32a-a33e-4b69-83dd-xxe8b1f8dddd" ],
+  "online" : true
+}
\ No newline at end of file
diff --git a/examples/test_case_data/localmeta/measure/test_kylin_cube_without_slr_left_join_ready/SELLER_CNT_BITMAP.json b/examples/test_case_data/localmeta/measure/test_kylin_cube_without_slr_left_join_ready/SELLER_CNT_BITMAP.json
new file mode 100644
index 0000000..6fcd298
--- /dev/null
+++ b/examples/test_case_data/localmeta/measure/test_kylin_cube_without_slr_left_join_ready/SELLER_CNT_BITMAP.json
@@ -0,0 +1,9 @@
+{
+  "uuid" : "0c3a35fb-10bc-5735-f395-42f0a6b2a9cb",
+  "last_modified" : 1556584529495,
+  "version" : "2.6.0.20500",
+  "name" : "SELLER_CNT_BITMAP",
+  "cube_name" : "test_kylin_cube_without_slr_left_join_ready",
+  "segments_name" : [ "2accs32a-a33e-4b69-83dd-xxe8b1f8dddd" ],
+  "online" : true
+}
\ No newline at end of file
diff --git a/examples/test_case_data/localmeta/measure/test_kylin_cube_without_slr_left_join_ready/SELLER_FORMAT_CNT.json b/examples/test_case_data/localmeta/measure/test_kylin_cube_without_slr_left_join_ready/SELLER_FORMAT_CNT.json
new file mode 100644
index 0000000..798a151
--- /dev/null
+++ b/examples/test_case_data/localmeta/measure/test_kylin_cube_without_slr_left_join_ready/SELLER_FORMAT_CNT.json
@@ -0,0 +1,9 @@
+{
+  "uuid" : "f7407156-e4e4-5b63-e1e1-5e48fd94d643",
+  "last_modified" : 1556584529501,
+  "version" : "2.6.0.20500",
+  "name" : "SELLER_FORMAT_CNT",
+  "cube_name" : "test_kylin_cube_without_slr_left_join_ready",
+  "segments_name" : [ "2accs32a-a33e-4b69-83dd-xxe8b1f8dddd" ],
+  "online" : true
+}
\ No newline at end of file
diff --git a/examples/test_case_data/localmeta/measure/test_kylin_cube_without_slr_left_join_ready/TOP_SELLER.json b/examples/test_case_data/localmeta/measure/test_kylin_cube_without_slr_left_join_ready/TOP_SELLER.json
new file mode 100644
index 0000000..486d02a
--- /dev/null
+++ b/examples/test_case_data/localmeta/measure/test_kylin_cube_without_slr_left_join_ready/TOP_SELLER.json
@@ -0,0 +1,9 @@
+{
+  "uuid" : "4975c9ad-4292-6354-2e6b-6cb5fd73c4eb",
+  "last_modified" : 1556584529504,
+  "version" : "2.6.0.20500",
+  "name" : "TOP_SELLER",
+  "cube_name" : "test_kylin_cube_without_slr_left_join_ready",
+  "segments_name" : [ "2accs32a-a33e-4b69-83dd-xxe8b1f8dddd" ],
+  "online" : true
+}
\ No newline at end of file
diff --git a/examples/test_case_data/localmeta/measure/test_kylin_cube_without_slr_left_join_ready/TRANS_CNT.json b/examples/test_case_data/localmeta/measure/test_kylin_cube_without_slr_left_join_ready/TRANS_CNT.json
new file mode 100644
index 0000000..977a751
--- /dev/null
+++ b/examples/test_case_data/localmeta/measure/test_kylin_cube_without_slr_left_join_ready/TRANS_CNT.json
@@ -0,0 +1,9 @@
+{
+  "uuid" : "8228b2c3-0764-4431-48d7-e6bbfd4a6ba4",
+  "last_modified" : 1556584529490,
+  "version" : "2.6.0.20500",
+  "name" : "TRANS_CNT",
+  "cube_name" : "test_kylin_cube_without_slr_left_join_ready",
+  "segments_name" : [ "2accs32a-a33e-4b69-83dd-xxe8b1f8dddd" ],
+  "online" : true
+}
\ No newline at end of file
diff --git a/examples/test_case_data/localmeta/measure/test_kylin_cube_without_slr_left_join_ready/USER_COUNT_BITMAP.json b/examples/test_case_data/localmeta/measure/test_kylin_cube_without_slr_left_join_ready/USER_COUNT_BITMAP.json
new file mode 100644
index 0000000..e85bf0d
--- /dev/null
+++ b/examples/test_case_data/localmeta/measure/test_kylin_cube_without_slr_left_join_ready/USER_COUNT_BITMAP.json
@@ -0,0 +1,9 @@
+{
+  "uuid" : "d7d39502-be4e-7b3b-2fec-20f76e8af369",
+  "last_modified" : 1556584529498,
+  "version" : "2.6.0.20500",
+  "name" : "USER_COUNT_BITMAP",
+  "cube_name" : "test_kylin_cube_without_slr_left_join_ready",
+  "segments_name" : [ "2accs32a-a33e-4b69-83dd-xxe8b1f8dddd" ],
+  "online" : true
+}
\ No newline at end of file
diff --git a/examples/test_case_data/localmeta/measure/test_kylin_cube_without_slr_left_join_ready_2_segments/CAL_DT_RAW.json b/examples/test_case_data/localmeta/measure/test_kylin_cube_without_slr_left_join_ready_2_segments/CAL_DT_RAW.json
new file mode 100644
index 0000000..fa58122
--- /dev/null
+++ b/examples/test_case_data/localmeta/measure/test_kylin_cube_without_slr_left_join_ready_2_segments/CAL_DT_RAW.json
@@ -0,0 +1,9 @@
+{
+  "uuid" : "f6eeeab7-cb6a-1aba-b315-20b2002c9966",
+  "last_modified" : 1556584529543,
+  "version" : "2.6.0.20500",
+  "name" : "CAL_DT_RAW",
+  "cube_name" : "test_kylin_cube_without_slr_left_join_ready_2_segments",
+  "segments_name" : [ "19691231160000_20131112000000", "20131112000000_20131212000000" ],
+  "online" : true
+}
\ No newline at end of file
diff --git a/examples/test_case_data/localmeta/measure/test_kylin_cube_without_slr_left_join_ready_2_segments/GMV_MAX.json b/examples/test_case_data/localmeta/measure/test_kylin_cube_without_slr_left_join_ready_2_segments/GMV_MAX.json
new file mode 100644
index 0000000..8915593
--- /dev/null
+++ b/examples/test_case_data/localmeta/measure/test_kylin_cube_without_slr_left_join_ready_2_segments/GMV_MAX.json
@@ -0,0 +1,9 @@
+{
+  "uuid" : "b766222e-9717-65ec-63c4-378149053879",
+  "last_modified" : 1556584529524,
+  "version" : "2.6.0.20500",
+  "name" : "GMV_MAX",
+  "cube_name" : "test_kylin_cube_without_slr_left_join_ready_2_segments",
+  "segments_name" : [ "19691231160000_20131112000000", "20131112000000_20131212000000" ],
+  "online" : true
+}
\ No newline at end of file
diff --git a/examples/test_case_data/localmeta/measure/test_kylin_cube_without_slr_left_join_ready_2_segments/GMV_MIN.json b/examples/test_case_data/localmeta/measure/test_kylin_cube_without_slr_left_join_ready_2_segments/GMV_MIN.json
new file mode 100644
index 0000000..ba3120b
--- /dev/null
+++ b/examples/test_case_data/localmeta/measure/test_kylin_cube_without_slr_left_join_ready_2_segments/GMV_MIN.json
@@ -0,0 +1,9 @@
+{
+  "uuid" : "91b7bf0a-f8e1-0ca1-93e1-b166a1b2e68b",
+  "last_modified" : 1556584529521,
+  "version" : "2.6.0.20500",
+  "name" : "GMV_MIN",
+  "cube_name" : "test_kylin_cube_without_slr_left_join_ready_2_segments",
+  "segments_name" : [ "19691231160000_20131112000000", "20131112000000_20131212000000" ],
+  "online" : true
+}
\ No newline at end of file
diff --git a/examples/test_case_data/localmeta/measure/test_kylin_cube_without_slr_left_join_ready_2_segments/GMV_SUM.json b/examples/test_case_data/localmeta/measure/test_kylin_cube_without_slr_left_join_ready_2_segments/GMV_SUM.json
new file mode 100644
index 0000000..08b0dd7
--- /dev/null
+++ b/examples/test_case_data/localmeta/measure/test_kylin_cube_without_slr_left_join_ready_2_segments/GMV_SUM.json
@@ -0,0 +1,9 @@
+{
+  "uuid" : "9c2e4e52-3e3a-e9de-1f21-986983d63e7e",
+  "last_modified" : 1556584529518,
+  "version" : "2.6.0.20500",
+  "name" : "GMV_SUM",
+  "cube_name" : "test_kylin_cube_without_slr_left_join_ready_2_segments",
+  "segments_name" : [ "19691231160000_20131112000000", "20131112000000_20131212000000" ],
+  "online" : true
+}
\ No newline at end of file
diff --git a/examples/test_case_data/localmeta/measure/test_kylin_cube_without_slr_left_join_ready_2_segments/ITEM_COUNT_SUM.json b/examples/test_case_data/localmeta/measure/test_kylin_cube_without_slr_left_join_ready_2_segments/ITEM_COUNT_SUM.json
new file mode 100644
index 0000000..9d7899d
--- /dev/null
+++ b/examples/test_case_data/localmeta/measure/test_kylin_cube_without_slr_left_join_ready_2_segments/ITEM_COUNT_SUM.json
@@ -0,0 +1,9 @@
+{
+  "uuid" : "0a5e6660-646d-ea92-bde9-8f8c8031e00c",
+  "last_modified" : 1556584529529,
+  "version" : "2.6.0.20500",
+  "name" : "ITEM_COUNT_SUM",
+  "cube_name" : "test_kylin_cube_without_slr_left_join_ready_2_segments",
+  "segments_name" : [ "19691231160000_20131112000000", "20131112000000_20131212000000" ],
+  "online" : true
+}
\ No newline at end of file
diff --git a/examples/test_case_data/localmeta/measure/test_kylin_cube_without_slr_left_join_ready_2_segments/LEAF_CATEG_ID_RAW.json b/examples/test_case_data/localmeta/measure/test_kylin_cube_without_slr_left_join_ready_2_segments/LEAF_CATEG_ID_RAW.json
new file mode 100644
index 0000000..efe604d
--- /dev/null
+++ b/examples/test_case_data/localmeta/measure/test_kylin_cube_without_slr_left_join_ready_2_segments/LEAF_CATEG_ID_RAW.json
@@ -0,0 +1,9 @@
+{
+  "uuid" : "5dc68682-7838-194d-10ec-c223c6ca71fb",
+  "last_modified" : 1556584529548,
+  "version" : "2.6.0.20500",
+  "name" : "LEAF_CATEG_ID_RAW",
+  "cube_name" : "test_kylin_cube_without_slr_left_join_ready_2_segments",
+  "segments_name" : [ "19691231160000_20131112000000", "20131112000000_20131212000000" ],
+  "online" : true
+}
\ No newline at end of file
diff --git a/examples/test_case_data/localmeta/measure/test_kylin_cube_without_slr_left_join_ready_2_segments/LSTG_FORMAT_NAME_RAW.json b/examples/test_case_data/localmeta/measure/test_kylin_cube_without_slr_left_join_ready_2_segments/LSTG_FORMAT_NAME_RAW.json
new file mode 100644
index 0000000..026b5c3
--- /dev/null
+++ b/examples/test_case_data/localmeta/measure/test_kylin_cube_without_slr_left_join_ready_2_segments/LSTG_FORMAT_NAME_RAW.json
@@ -0,0 +1,9 @@
+{
+  "uuid" : "3944977e-7271-b57a-8d7b-ba77d04a9be8",
+  "last_modified" : 1556584529546,
+  "version" : "2.6.0.20500",
+  "name" : "LSTG_FORMAT_NAME_RAW",
+  "cube_name" : "test_kylin_cube_without_slr_left_join_ready_2_segments",
+  "segments_name" : [ "19691231160000_20131112000000", "20131112000000_20131212000000" ],
+  "online" : true
+}
\ No newline at end of file
diff --git a/examples/test_case_data/localmeta/measure/test_kylin_cube_without_slr_left_join_ready_2_segments/PRICE_RAW.json b/examples/test_case_data/localmeta/measure/test_kylin_cube_without_slr_left_join_ready_2_segments/PRICE_RAW.json
new file mode 100644
index 0000000..af4b8e7
--- /dev/null
+++ b/examples/test_case_data/localmeta/measure/test_kylin_cube_without_slr_left_join_ready_2_segments/PRICE_RAW.json
@@ -0,0 +1,9 @@
+{
+  "uuid" : "7a74abbe-7bfb-93d2-4ec5-d2152a3958e3",
+  "last_modified" : 1556584529551,
+  "version" : "2.6.0.20500",
+  "name" : "PRICE_RAW",
+  "cube_name" : "test_kylin_cube_without_slr_left_join_ready_2_segments",
+  "segments_name" : [ "19691231160000_20131112000000", "20131112000000_20131212000000" ],
+  "online" : true
+}
\ No newline at end of file
diff --git a/examples/test_case_data/localmeta/measure/test_kylin_cube_without_slr_left_join_ready_2_segments/SELLER_CNT_BITMAP.json b/examples/test_case_data/localmeta/measure/test_kylin_cube_without_slr_left_join_ready_2_segments/SELLER_CNT_BITMAP.json
new file mode 100644
index 0000000..6658107
--- /dev/null
+++ b/examples/test_case_data/localmeta/measure/test_kylin_cube_without_slr_left_join_ready_2_segments/SELLER_CNT_BITMAP.json
@@ -0,0 +1,9 @@
+{
+  "uuid" : "dbf378e6-810b-f11d-0b96-56e9613a4d4b",
+  "last_modified" : 1556584529532,
+  "version" : "2.6.0.20500",
+  "name" : "SELLER_CNT_BITMAP",
+  "cube_name" : "test_kylin_cube_without_slr_left_join_ready_2_segments",
+  "segments_name" : [ "19691231160000_20131112000000", "20131112000000_20131212000000" ],
+  "online" : true
+}
\ No newline at end of file
diff --git a/examples/test_case_data/localmeta/measure/test_kylin_cube_without_slr_left_join_ready_2_segments/SELLER_FORMAT_CNT.json b/examples/test_case_data/localmeta/measure/test_kylin_cube_without_slr_left_join_ready_2_segments/SELLER_FORMAT_CNT.json
new file mode 100644
index 0000000..cf54e14
--- /dev/null
+++ b/examples/test_case_data/localmeta/measure/test_kylin_cube_without_slr_left_join_ready_2_segments/SELLER_FORMAT_CNT.json
@@ -0,0 +1,9 @@
+{
+  "uuid" : "410c3022-2023-453b-16a0-dbf697ee2c57",
+  "last_modified" : 1556584529537,
+  "version" : "2.6.0.20500",
+  "name" : "SELLER_FORMAT_CNT",
+  "cube_name" : "test_kylin_cube_without_slr_left_join_ready_2_segments",
+  "segments_name" : [ "19691231160000_20131112000000", "20131112000000_20131212000000" ],
+  "online" : true
+}
\ No newline at end of file
diff --git a/examples/test_case_data/localmeta/measure/test_kylin_cube_without_slr_left_join_ready_2_segments/TOP_SELLER.json b/examples/test_case_data/localmeta/measure/test_kylin_cube_without_slr_left_join_ready_2_segments/TOP_SELLER.json
new file mode 100644
index 0000000..c8bdc74
--- /dev/null
+++ b/examples/test_case_data/localmeta/measure/test_kylin_cube_without_slr_left_join_ready_2_segments/TOP_SELLER.json
@@ -0,0 +1,9 @@
+{
+  "uuid" : "780d360b-bc9e-cffe-f536-3ac3cc7e2604",
+  "last_modified" : 1556584529540,
+  "version" : "2.6.0.20500",
+  "name" : "TOP_SELLER",
+  "cube_name" : "test_kylin_cube_without_slr_left_join_ready_2_segments",
+  "segments_name" : [ "19691231160000_20131112000000", "20131112000000_20131212000000" ],
+  "online" : true
+}
\ No newline at end of file
diff --git a/examples/test_case_data/localmeta/measure/test_kylin_cube_without_slr_left_join_ready_2_segments/TRANS_CNT.json b/examples/test_case_data/localmeta/measure/test_kylin_cube_without_slr_left_join_ready_2_segments/TRANS_CNT.json
new file mode 100644
index 0000000..9e27167
--- /dev/null
+++ b/examples/test_case_data/localmeta/measure/test_kylin_cube_without_slr_left_join_ready_2_segments/TRANS_CNT.json
@@ -0,0 +1,9 @@
+{
+  "uuid" : "053bc013-f728-1b09-326f-e258639cb752",
+  "last_modified" : 1556584529526,
+  "version" : "2.6.0.20500",
+  "name" : "TRANS_CNT",
+  "cube_name" : "test_kylin_cube_without_slr_left_join_ready_2_segments",
+  "segments_name" : [ "19691231160000_20131112000000", "20131112000000_20131212000000" ],
+  "online" : true
+}
\ No newline at end of file
diff --git a/examples/test_case_data/localmeta/measure/test_kylin_cube_without_slr_left_join_ready_2_segments/USER_COUNT_BITMAP.json b/examples/test_case_data/localmeta/measure/test_kylin_cube_without_slr_left_join_ready_2_segments/USER_COUNT_BITMAP.json
new file mode 100644
index 0000000..914d50f
--- /dev/null
+++ b/examples/test_case_data/localmeta/measure/test_kylin_cube_without_slr_left_join_ready_2_segments/USER_COUNT_BITMAP.json
@@ -0,0 +1,9 @@
+{
+  "uuid" : "93ea26ad-7751-08eb-c587-6a1443038eb4",
+  "last_modified" : 1556584529535,
+  "version" : "2.6.0.20500",
+  "name" : "USER_COUNT_BITMAP",
+  "cube_name" : "test_kylin_cube_without_slr_left_join_ready_2_segments",
+  "segments_name" : [ "19691231160000_20131112000000", "20131112000000_20131212000000" ],
+  "online" : true
+}
\ No newline at end of file
diff --git a/examples/test_case_data/localmeta/measure/test_kylin_cube_without_slr_ready/CAL_DT_RAW.json b/examples/test_case_data/localmeta/measure/test_kylin_cube_without_slr_ready/CAL_DT_RAW.json
new file mode 100644
index 0000000..1e0c561
--- /dev/null
+++ b/examples/test_case_data/localmeta/measure/test_kylin_cube_without_slr_ready/CAL_DT_RAW.json
@@ -0,0 +1,9 @@
+{
+  "uuid" : "09fc721b-391b-45d7-2a76-1bd2cd8cf9e7",
+  "last_modified" : 1556584529575,
+  "version" : "2.6.0.20500",
+  "name" : "CAL_DT_RAW",
+  "cube_name" : "test_kylin_cube_without_slr_ready",
+  "segments_name" : [ "67f668f6-dcff-4cb6-a89b-77f1119df8fa" ],
+  "online" : true
+}
\ No newline at end of file
diff --git a/examples/test_case_data/localmeta/measure/test_kylin_cube_without_slr_ready/GMV_MAX.json b/examples/test_case_data/localmeta/measure/test_kylin_cube_without_slr_ready/GMV_MAX.json
new file mode 100644
index 0000000..55fbadb
--- /dev/null
+++ b/examples/test_case_data/localmeta/measure/test_kylin_cube_without_slr_ready/GMV_MAX.json
@@ -0,0 +1,9 @@
+{
+  "uuid" : "ce7b3353-e8fb-4ba9-9d7c-d6462e171ef4",
+  "last_modified" : 1556584529560,
+  "version" : "2.6.0.20500",
+  "name" : "GMV_MAX",
+  "cube_name" : "test_kylin_cube_without_slr_ready",
+  "segments_name" : [ "67f668f6-dcff-4cb6-a89b-77f1119df8fa" ],
+  "online" : true
+}
\ No newline at end of file
diff --git a/examples/test_case_data/localmeta/measure/test_kylin_cube_without_slr_ready/GMV_MIN.json b/examples/test_case_data/localmeta/measure/test_kylin_cube_without_slr_ready/GMV_MIN.json
new file mode 100644
index 0000000..648ff1e
--- /dev/null
+++ b/examples/test_case_data/localmeta/measure/test_kylin_cube_without_slr_ready/GMV_MIN.json
@@ -0,0 +1,9 @@
+{
+  "uuid" : "4dc3ed3c-f80c-91a5-5dc5-ab1ecd911d4a",
+  "last_modified" : 1556584529558,
+  "version" : "2.6.0.20500",
+  "name" : "GMV_MIN",
+  "cube_name" : "test_kylin_cube_without_slr_ready",
+  "segments_name" : [ "67f668f6-dcff-4cb6-a89b-77f1119df8fa" ],
+  "online" : true
+}
\ No newline at end of file
diff --git a/examples/test_case_data/localmeta/measure/test_kylin_cube_without_slr_ready/GMV_SUM.json b/examples/test_case_data/localmeta/measure/test_kylin_cube_without_slr_ready/GMV_SUM.json
new file mode 100644
index 0000000..cef677a
--- /dev/null
+++ b/examples/test_case_data/localmeta/measure/test_kylin_cube_without_slr_ready/GMV_SUM.json
@@ -0,0 +1,9 @@
+{
+  "uuid" : "6cc73d0e-c87f-17d8-b685-a5aa691db892",
+  "last_modified" : 1556584529554,
+  "version" : "2.6.0.20500",
+  "name" : "GMV_SUM",
+  "cube_name" : "test_kylin_cube_without_slr_ready",
+  "segments_name" : [ "67f668f6-dcff-4cb6-a89b-77f1119df8fa" ],
+  "online" : true
+}
\ No newline at end of file
diff --git a/examples/test_case_data/localmeta/measure/test_kylin_cube_without_slr_ready/ITEM_COUNT_SUM.json b/examples/test_case_data/localmeta/measure/test_kylin_cube_without_slr_ready/ITEM_COUNT_SUM.json
new file mode 100644
index 0000000..9a6bb60
--- /dev/null
+++ b/examples/test_case_data/localmeta/measure/test_kylin_cube_without_slr_ready/ITEM_COUNT_SUM.json
@@ -0,0 +1,9 @@
+{
+  "uuid" : "18b49642-aba2-2fc8-c0ba-71a79d385f4b",
+  "last_modified" : 1556584529566,
+  "version" : "2.6.0.20500",
+  "name" : "ITEM_COUNT_SUM",
+  "cube_name" : "test_kylin_cube_without_slr_ready",
+  "segments_name" : [ "67f668f6-dcff-4cb6-a89b-77f1119df8fa" ],
+  "online" : true
+}
\ No newline at end of file
diff --git a/examples/test_case_data/localmeta/measure/test_kylin_cube_without_slr_ready/LEAF_CATEG_ID_RAW.json b/examples/test_case_data/localmeta/measure/test_kylin_cube_without_slr_ready/LEAF_CATEG_ID_RAW.json
new file mode 100644
index 0000000..ce9febf
--- /dev/null
+++ b/examples/test_case_data/localmeta/measure/test_kylin_cube_without_slr_ready/LEAF_CATEG_ID_RAW.json
@@ -0,0 +1,9 @@
+{
+  "uuid" : "c5e9dd01-add7-4632-3870-c14ffdc7d0c2",
+  "last_modified" : 1556584529581,
+  "version" : "2.6.0.20500",
+  "name" : "LEAF_CATEG_ID_RAW",
+  "cube_name" : "test_kylin_cube_without_slr_ready",
+  "segments_name" : [ "67f668f6-dcff-4cb6-a89b-77f1119df8fa" ],
+  "online" : true
+}
\ No newline at end of file
diff --git a/examples/test_case_data/localmeta/measure/test_kylin_cube_without_slr_ready/LSTG_FORMAT_NAME_RAW.json b/examples/test_case_data/localmeta/measure/test_kylin_cube_without_slr_ready/LSTG_FORMAT_NAME_RAW.json
new file mode 100644
index 0000000..229e19d
--- /dev/null
+++ b/examples/test_case_data/localmeta/measure/test_kylin_cube_without_slr_ready/LSTG_FORMAT_NAME_RAW.json
@@ -0,0 +1,9 @@
+{
+  "uuid" : "9dc41f7e-338f-0329-df89-156c6b9f7b6e",
+  "last_modified" : 1556584529578,
+  "version" : "2.6.0.20500",
+  "name" : "LSTG_FORMAT_NAME_RAW",
+  "cube_name" : "test_kylin_cube_without_slr_ready",
+  "segments_name" : [ "67f668f6-dcff-4cb6-a89b-77f1119df8fa" ],
+  "online" : true
+}
\ No newline at end of file
diff --git a/examples/test_case_data/localmeta/measure/test_kylin_cube_without_slr_ready/PRICE_RAW.json b/examples/test_case_data/localmeta/measure/test_kylin_cube_without_slr_ready/PRICE_RAW.json
new file mode 100644
index 0000000..c1489ab
--- /dev/null
+++ b/examples/test_case_data/localmeta/measure/test_kylin_cube_without_slr_ready/PRICE_RAW.json
@@ -0,0 +1,9 @@
+{
+  "uuid" : "2f4a4b92-2d9a-2330-ea72-d960884a30ff",
+  "last_modified" : 1556584529584,
+  "version" : "2.6.0.20500",
+  "name" : "PRICE_RAW",
+  "cube_name" : "test_kylin_cube_without_slr_ready",
+  "segments_name" : [ "67f668f6-dcff-4cb6-a89b-77f1119df8fa" ],
+  "online" : true
+}
\ No newline at end of file
diff --git a/examples/test_case_data/localmeta/measure/test_kylin_cube_without_slr_ready/SITE_EXTENDED_1.json b/examples/test_case_data/localmeta/measure/test_kylin_cube_without_slr_ready/SITE_EXTENDED_1.json
new file mode 100644
index 0000000..f796f59
--- /dev/null
+++ b/examples/test_case_data/localmeta/measure/test_kylin_cube_without_slr_ready/SITE_EXTENDED_1.json
@@ -0,0 +1,9 @@
+{
+  "uuid" : "bdd8d928-64fe-0e2c-7413-607e0550d292",
+  "last_modified" : 1556584529569,
+  "version" : "2.6.0.20500",
+  "name" : "SITE_EXTENDED_1",
+  "cube_name" : "test_kylin_cube_without_slr_ready",
+  "segments_name" : [ "67f668f6-dcff-4cb6-a89b-77f1119df8fa" ],
+  "online" : true
+}
\ No newline at end of file
diff --git a/examples/test_case_data/localmeta/measure/test_kylin_cube_without_slr_ready/SITE_EXTENDED_2.json b/examples/test_case_data/localmeta/measure/test_kylin_cube_without_slr_ready/SITE_EXTENDED_2.json
new file mode 100644
index 0000000..7429e00
--- /dev/null
+++ b/examples/test_case_data/localmeta/measure/test_kylin_cube_without_slr_ready/SITE_EXTENDED_2.json
@@ -0,0 +1,9 @@
+{
+  "uuid" : "3aa75562-1b8d-0167-e4e5-0aea0dcdae9b",
+  "last_modified" : 1556584529572,
+  "version" : "2.6.0.20500",
+  "name" : "SITE_EXTENDED_2",
+  "cube_name" : "test_kylin_cube_without_slr_ready",
+  "segments_name" : [ "67f668f6-dcff-4cb6-a89b-77f1119df8fa" ],
+  "online" : true
+}
\ No newline at end of file
diff --git a/examples/test_case_data/localmeta/measure/test_kylin_cube_without_slr_ready/TRANS_CNT.json b/examples/test_case_data/localmeta/measure/test_kylin_cube_without_slr_ready/TRANS_CNT.json
new file mode 100644
index 0000000..88ba450
--- /dev/null
+++ b/examples/test_case_data/localmeta/measure/test_kylin_cube_without_slr_ready/TRANS_CNT.json
@@ -0,0 +1,9 @@
+{
+  "uuid" : "532fb77f-237b-c42d-ca85-5e2061df6ccd",
+  "last_modified" : 1556584529563,
+  "version" : "2.6.0.20500",
+  "name" : "TRANS_CNT",
+  "cube_name" : "test_kylin_cube_without_slr_ready",
+  "segments_name" : [ "67f668f6-dcff-4cb6-a89b-77f1119df8fa" ],
+  "online" : true
+}
\ No newline at end of file
diff --git a/examples/test_case_data/localmeta/measure/test_streaming_join_table_cube/GMV_SUM.json b/examples/test_case_data/localmeta/measure/test_streaming_join_table_cube/GMV_SUM.json
new file mode 100644
index 0000000..22296a5
--- /dev/null
+++ b/examples/test_case_data/localmeta/measure/test_streaming_join_table_cube/GMV_SUM.json
@@ -0,0 +1,9 @@
+{
+  "uuid" : "0ed4b930-f590-70c4-d91e-2f27b57da613",
+  "last_modified" : 1556584529589,
+  "version" : "2.6.0.20500",
+  "name" : "GMV_SUM",
+  "cube_name" : "test_streaming_join_table_cube",
+  "segments_name" : [ ],
+  "online" : true
+}
\ No newline at end of file
diff --git a/examples/test_case_data/localmeta/measure/test_streaming_join_table_cube/ITEM_COUNT_SUM.json b/examples/test_case_data/localmeta/measure/test_streaming_join_table_cube/ITEM_COUNT_SUM.json
new file mode 100644
index 0000000..e09e12f
--- /dev/null
+++ b/examples/test_case_data/localmeta/measure/test_streaming_join_table_cube/ITEM_COUNT_SUM.json
@@ -0,0 +1,9 @@
+{
+  "uuid" : "a6863648-042c-3ae9-5bef-df1738cabf32",
+  "last_modified" : 1556584529592,
+  "version" : "2.6.0.20500",
+  "name" : "ITEM_COUNT_SUM",
+  "cube_name" : "test_streaming_join_table_cube",
+  "segments_name" : [ ],
+  "online" : true
+}
\ No newline at end of file
diff --git a/examples/test_case_data/localmeta/measure/test_streaming_join_table_cube/_COUNT_.json b/examples/test_case_data/localmeta/measure/test_streaming_join_table_cube/_COUNT_.json
new file mode 100644
index 0000000..f812058
--- /dev/null
+++ b/examples/test_case_data/localmeta/measure/test_streaming_join_table_cube/_COUNT_.json
@@ -0,0 +1,9 @@
+{
+  "uuid" : "741e4def-7a49-9cd6-a796-4db1fa7bfd6f",
+  "last_modified" : 1556584529586,
+  "version" : "2.6.0.20500",
+  "name" : "_COUNT_",
+  "cube_name" : "test_streaming_join_table_cube",
+  "segments_name" : [ ],
+  "online" : true
+}
\ No newline at end of file
diff --git a/examples/test_case_data/localmeta/measure/test_streaming_table_cube/GMV_SUM.json b/examples/test_case_data/localmeta/measure/test_streaming_table_cube/GMV_SUM.json
new file mode 100644
index 0000000..c0f8eb0
--- /dev/null
+++ b/examples/test_case_data/localmeta/measure/test_streaming_table_cube/GMV_SUM.json
@@ -0,0 +1,9 @@
+{
+  "uuid" : "a5db8d10-607d-c7a0-0f74-e48764be24be",
+  "last_modified" : 1556584529598,
+  "version" : "2.6.0.20500",
+  "name" : "GMV_SUM",
+  "cube_name" : "test_streaming_table_cube",
+  "segments_name" : [ ],
+  "online" : true
+}
\ No newline at end of file
diff --git a/examples/test_case_data/localmeta/measure/test_streaming_table_cube/ITEM_COUNT_SUM.json b/examples/test_case_data/localmeta/measure/test_streaming_table_cube/ITEM_COUNT_SUM.json
new file mode 100644
index 0000000..722f15d
--- /dev/null
+++ b/examples/test_case_data/localmeta/measure/test_streaming_table_cube/ITEM_COUNT_SUM.json
@@ -0,0 +1,9 @@
+{
+  "uuid" : "a82f3ab7-3556-fce0-59c6-4e34b439551c",
+  "last_modified" : 1556584529601,
+  "version" : "2.6.0.20500",
+  "name" : "ITEM_COUNT_SUM",
+  "cube_name" : "test_streaming_table_cube",
+  "segments_name" : [ ],
+  "online" : true
+}
\ No newline at end of file
diff --git a/examples/test_case_data/localmeta/measure/test_streaming_table_cube/_COUNT_.json b/examples/test_case_data/localmeta/measure/test_streaming_table_cube/_COUNT_.json
new file mode 100644
index 0000000..6a19b12
--- /dev/null
+++ b/examples/test_case_data/localmeta/measure/test_streaming_table_cube/_COUNT_.json
@@ -0,0 +1,9 @@
+{
+  "uuid" : "6553d4ad-b1f9-fb04-478d-dafdb3d25090",
+  "last_modified" : 1556584529595,
+  "version" : "2.6.0.20500",
+  "name" : "_COUNT_",
+  "cube_name" : "test_streaming_table_cube",
+  "segments_name" : [ ],
+  "online" : true
+}
\ No newline at end of file
diff --git a/examples/test_case_data/localmeta/measure/test_streaming_v2_cube/GMV_PERCENTILE.json b/examples/test_case_data/localmeta/measure/test_streaming_v2_cube/GMV_PERCENTILE.json
new file mode 100644
index 0000000..400157c
--- /dev/null
+++ b/examples/test_case_data/localmeta/measure/test_streaming_v2_cube/GMV_PERCENTILE.json
@@ -0,0 +1,9 @@
+{
+  "uuid" : "35256279-1a46-cfc7-2ab0-41b91c292214",
+  "last_modified" : 1556584529609,
+  "version" : "2.6.0.20500",
+  "name" : "GMV_PERCENTILE",
+  "cube_name" : "test_streaming_v2_cube",
+  "segments_name" : [ ],
+  "online" : true
+}
\ No newline at end of file
diff --git a/examples/test_case_data/localmeta/measure/test_streaming_v2_cube/GMV_SUM.json b/examples/test_case_data/localmeta/measure/test_streaming_v2_cube/GMV_SUM.json
new file mode 100644
index 0000000..1b3bd70
--- /dev/null
+++ b/examples/test_case_data/localmeta/measure/test_streaming_v2_cube/GMV_SUM.json
@@ -0,0 +1,9 @@
+{
+  "uuid" : "c46277b8-7dc4-ae73-0b11-bba802a2c795",
+  "last_modified" : 1556584529607,
+  "version" : "2.6.0.20500",
+  "name" : "GMV_SUM",
+  "cube_name" : "test_streaming_v2_cube",
+  "segments_name" : [ ],
+  "online" : true
+}
\ No newline at end of file
diff --git a/examples/test_case_data/localmeta/measure/test_streaming_v2_cube/ITEM_COUNT_SUM.json b/examples/test_case_data/localmeta/measure/test_streaming_v2_cube/ITEM_COUNT_SUM.json
new file mode 100644
index 0000000..08e5eca
--- /dev/null
+++ b/examples/test_case_data/localmeta/measure/test_streaming_v2_cube/ITEM_COUNT_SUM.json
@@ -0,0 +1,9 @@
+{
+  "uuid" : "cb694b28-727d-f9a6-0b08-6ff0d33f9017",
+  "last_modified" : 1556584529612,
+  "version" : "2.6.0.20500",
+  "name" : "ITEM_COUNT_SUM",
+  "cube_name" : "test_streaming_v2_cube",
+  "segments_name" : [ ],
+  "online" : true
+}
\ No newline at end of file
diff --git a/examples/test_case_data/localmeta/measure/test_streaming_v2_cube/_COUNT_.json b/examples/test_case_data/localmeta/measure/test_streaming_v2_cube/_COUNT_.json
new file mode 100644
index 0000000..5d29edf
--- /dev/null
+++ b/examples/test_case_data/localmeta/measure/test_streaming_v2_cube/_COUNT_.json
@@ -0,0 +1,9 @@
+{
+  "uuid" : "2d01a19a-611b-1d0a-3f73-238f469d3cea",
+  "last_modified" : 1556584529604,
+  "version" : "2.6.0.20500",
+  "name" : "_COUNT_",
+  "cube_name" : "test_streaming_v2_cube",
+  "segments_name" : [ ],
+  "online" : true
+}
\ No newline at end of file
diff --git a/examples/test_case_data/localmeta/measure/test_streaming_v2_user_info_cube/COUNTDISTINCT_LID.json b/examples/test_case_data/localmeta/measure/test_streaming_v2_user_info_cube/COUNTDISTINCT_LID.json
new file mode 100644
index 0000000..5a1329b
--- /dev/null
+++ b/examples/test_case_data/localmeta/measure/test_streaming_v2_user_info_cube/COUNTDISTINCT_LID.json
@@ -0,0 +1,9 @@
+{
+  "uuid" : "f7f7e92d-99e4-c41b-2a80-123b26b88a75",
+  "last_modified" : 1556584529632,
+  "version" : "2.6.0.20500",
+  "name" : "COUNTDISTINCT_LID",
+  "cube_name" : "test_streaming_v2_user_info_cube",
+  "segments_name" : [ ],
+  "online" : true
+}
\ No newline at end of file
diff --git a/examples/test_case_data/localmeta/measure/test_streaming_v2_user_info_cube/COUNTDISTINCT_UID.json b/examples/test_case_data/localmeta/measure/test_streaming_v2_user_info_cube/COUNTDISTINCT_UID.json
new file mode 100644
index 0000000..7690834
--- /dev/null
+++ b/examples/test_case_data/localmeta/measure/test_streaming_v2_user_info_cube/COUNTDISTINCT_UID.json
@@ -0,0 +1,9 @@
+{
+  "uuid" : "dbf5a094-9c14-394e-b844-9771a7c20751",
+  "last_modified" : 1556584529626,
+  "version" : "2.6.0.20500",
+  "name" : "COUNTDISTINCT_UID",
+  "cube_name" : "test_streaming_v2_user_info_cube",
+  "segments_name" : [ ],
+  "online" : true
+}
\ No newline at end of file
diff --git a/examples/test_case_data/localmeta/measure/test_streaming_v2_user_info_cube/MAX_EXPERIENCE.json b/examples/test_case_data/localmeta/measure/test_streaming_v2_user_info_cube/MAX_EXPERIENCE.json
new file mode 100644
index 0000000..89e5bbf
--- /dev/null
+++ b/examples/test_case_data/localmeta/measure/test_streaming_v2_user_info_cube/MAX_EXPERIENCE.json
@@ -0,0 +1,9 @@
+{
+  "uuid" : "56812a73-a635-0304-d095-22826a9b8d96",
+  "last_modified" : 1556584529621,
+  "version" : "2.6.0.20500",
+  "name" : "MAX_EXPERIENCE",
+  "cube_name" : "test_streaming_v2_user_info_cube",
+  "segments_name" : [ ],
+  "online" : true
+}
\ No newline at end of file
diff --git a/examples/test_case_data/localmeta/measure/test_streaming_v2_user_info_cube/MIN_EXPERIENCE.json b/examples/test_case_data/localmeta/measure/test_streaming_v2_user_info_cube/MIN_EXPERIENCE.json
new file mode 100644
index 0000000..aa9741d
--- /dev/null
+++ b/examples/test_case_data/localmeta/measure/test_streaming_v2_user_info_cube/MIN_EXPERIENCE.json
@@ -0,0 +1,9 @@
+{
+  "uuid" : "7ea18289-1487-a49c-d548-b924607f484c",
+  "last_modified" : 1556584529623,
+  "version" : "2.6.0.20500",
+  "name" : "MIN_EXPERIENCE",
+  "cube_name" : "test_streaming_v2_user_info_cube",
+  "segments_name" : [ ],
+  "online" : true
+}
\ No newline at end of file
diff --git a/examples/test_case_data/localmeta/measure/test_streaming_v2_user_info_cube/PERCENTILE_REPUTATION.json b/examples/test_case_data/localmeta/measure/test_streaming_v2_user_info_cube/PERCENTILE_REPUTATION.json
new file mode 100644
index 0000000..c364a82
--- /dev/null
+++ b/examples/test_case_data/localmeta/measure/test_streaming_v2_user_info_cube/PERCENTILE_REPUTATION.json
@@ -0,0 +1,9 @@
+{
+  "uuid" : "7156fe08-50ed-5e8d-3205-61fe9d6da509",
+  "last_modified" : 1556584529629,
+  "version" : "2.6.0.20500",
+  "name" : "PERCENTILE_REPUTATION",
+  "cube_name" : "test_streaming_v2_user_info_cube",
+  "segments_name" : [ ],
+  "online" : true
+}
\ No newline at end of file
diff --git a/examples/test_case_data/localmeta/measure/test_streaming_v2_user_info_cube/SUM_COINS.json b/examples/test_case_data/localmeta/measure/test_streaming_v2_user_info_cube/SUM_COINS.json
new file mode 100644
index 0000000..e6ede91
--- /dev/null
+++ b/examples/test_case_data/localmeta/measure/test_streaming_v2_user_info_cube/SUM_COINS.json
@@ -0,0 +1,9 @@
+{
+  "uuid" : "6d548cf2-dd34-2122-882d-a458aba0755b",
+  "last_modified" : 1556584529618,
+  "version" : "2.6.0.20500",
+  "name" : "SUM_COINS",
+  "cube_name" : "test_streaming_v2_user_info_cube",
+  "segments_name" : [ ],
+  "online" : true
+}
\ No newline at end of file
diff --git a/examples/test_case_data/localmeta/measure/test_streaming_v2_user_info_cube/_COUNT_.json b/examples/test_case_data/localmeta/measure/test_streaming_v2_user_info_cube/_COUNT_.json
new file mode 100644
index 0000000..ab3d274
--- /dev/null
+++ b/examples/test_case_data/localmeta/measure/test_streaming_v2_user_info_cube/_COUNT_.json
@@ -0,0 +1,9 @@
+{
+  "uuid" : "297a827e-aa66-288b-a12e-2c44ac56e42d",
+  "last_modified" : 1556584529615,
+  "version" : "2.6.0.20500",
+  "name" : "_COUNT_",
+  "cube_name" : "test_streaming_v2_user_info_cube",
+  "segments_name" : [ ],
+  "online" : true
+}
\ No newline at end of file
diff --git a/examples/test_case_data/measure/MAX_SELLER_ID.json b/examples/test_case_data/measure/MAX_SELLER_ID.json
new file mode 100644
index 0000000..bfad3fa
--- /dev/null
+++ b/examples/test_case_data/measure/MAX_SELLER_ID.json
@@ -0,0 +1,11 @@
+{
+  "name": "MAX_SELLER_ID",
+  "function": {
+    "expression": "MAX",
+    "parameter": {
+      "type": "column",
+      "value": "TEST_KYLIN_FACT.SELLER_ID"
+    },
+    "returntype": "decimal(19,4)"
+  }
+}
\ No newline at end of file
diff --git a/source-jdbc/src/test/resources/ut_meta/jdbc_source/measure/ut_jdbc_shard/BUYER_CONTACT.json b/source-jdbc/src/test/resources/ut_meta/jdbc_source/measure/ut_jdbc_shard/BUYER_CONTACT.json
new file mode 100644
index 0000000..2dea3e7
--- /dev/null
+++ b/source-jdbc/src/test/resources/ut_meta/jdbc_source/measure/ut_jdbc_shard/BUYER_CONTACT.json
@@ -0,0 +1,9 @@
+{
+  "uuid" : "64629cc9-674d-f5ba-0598-0b07c6e5a49d",
+  "last_modified" : 1556980986018,
+  "version" : "2.6.0.20500",
+  "name" : "BUYER_CONTACT",
+  "cube_name" : "ut_jdbc_shard",
+  "segments_name" : [ ],
+  "online" : true
+}
\ No newline at end of file
diff --git a/source-jdbc/src/test/resources/ut_meta/jdbc_source/measure/ut_jdbc_shard/CAL_DT_RAW.json b/source-jdbc/src/test/resources/ut_meta/jdbc_source/measure/ut_jdbc_shard/CAL_DT_RAW.json
new file mode 100644
index 0000000..d1efe45
--- /dev/null
+++ b/source-jdbc/src/test/resources/ut_meta/jdbc_source/measure/ut_jdbc_shard/CAL_DT_RAW.json
@@ -0,0 +1,9 @@
+{
+  "uuid" : "930aa6aa-9f30-1aaf-182a-814e853ca28e",
+  "last_modified" : 1556980986030,
+  "version" : "2.6.0.20500",
+  "name" : "CAL_DT_RAW",
+  "cube_name" : "ut_jdbc_shard",
+  "segments_name" : [ ],
+  "online" : true
+}
\ No newline at end of file
diff --git a/source-jdbc/src/test/resources/ut_meta/jdbc_source/measure/ut_jdbc_shard/CORR_TRANS_ID_LSTG_SITE_ID.json b/source-jdbc/src/test/resources/ut_meta/jdbc_source/measure/ut_jdbc_shard/CORR_TRANS_ID_LSTG_SITE_ID.json
new file mode 100644
index 0000000..a1bb660
--- /dev/null
+++ b/source-jdbc/src/test/resources/ut_meta/jdbc_source/measure/ut_jdbc_shard/CORR_TRANS_ID_LSTG_SITE_ID.json
@@ -0,0 +1,9 @@
+{
+  "uuid" : "16cdccf4-0766-8f5b-4105-75b552e41a59",
+  "last_modified" : 1556980986036,
+  "version" : "2.6.0.20500",
+  "name" : "CORR_TRANS_ID_LSTG_SITE_ID",
+  "cube_name" : "ut_jdbc_shard",
+  "segments_name" : [ ],
+  "online" : true
+}
\ No newline at end of file
diff --git a/source-jdbc/src/test/resources/ut_meta/jdbc_source/measure/ut_jdbc_shard/GMV_MAX.json b/source-jdbc/src/test/resources/ut_meta/jdbc_source/measure/ut_jdbc_shard/GMV_MAX.json
new file mode 100644
index 0000000..cc43703
--- /dev/null
+++ b/source-jdbc/src/test/resources/ut_meta/jdbc_source/measure/ut_jdbc_shard/GMV_MAX.json
@@ -0,0 +1,9 @@
+{
+  "uuid" : "a3139b9e-60c3-a9bc-7ff3-0a2d5c688091",
+  "last_modified" : 1556980985998,
+  "version" : "2.6.0.20500",
+  "name" : "GMV_MAX",
+  "cube_name" : "ut_jdbc_shard",
+  "segments_name" : [ ],
+  "online" : true
+}
\ No newline at end of file
diff --git a/source-jdbc/src/test/resources/ut_meta/jdbc_source/measure/ut_jdbc_shard/GMV_MIN.json b/source-jdbc/src/test/resources/ut_meta/jdbc_source/measure/ut_jdbc_shard/GMV_MIN.json
new file mode 100644
index 0000000..60be7b1
--- /dev/null
+++ b/source-jdbc/src/test/resources/ut_meta/jdbc_source/measure/ut_jdbc_shard/GMV_MIN.json
@@ -0,0 +1,9 @@
+{
+  "uuid" : "87478106-6125-9eb0-3333-14728c4f8384",
+  "last_modified" : 1556980985995,
+  "version" : "2.6.0.20500",
+  "name" : "GMV_MIN",
+  "cube_name" : "ut_jdbc_shard",
+  "segments_name" : [ ],
+  "online" : true
+}
\ No newline at end of file
diff --git a/source-jdbc/src/test/resources/ut_meta/jdbc_source/measure/ut_jdbc_shard/GMV_SUM.json b/source-jdbc/src/test/resources/ut_meta/jdbc_source/measure/ut_jdbc_shard/GMV_SUM.json
new file mode 100644
index 0000000..397f756
--- /dev/null
+++ b/source-jdbc/src/test/resources/ut_meta/jdbc_source/measure/ut_jdbc_shard/GMV_SUM.json
@@ -0,0 +1,9 @@
+{
+  "uuid" : "ebc22078-1966-272f-0893-c48f4ef71b2e",
+  "last_modified" : 1556980985991,
+  "version" : "2.6.0.20500",
+  "name" : "GMV_SUM",
+  "cube_name" : "ut_jdbc_shard",
+  "segments_name" : [ ],
+  "online" : true
+}
\ No newline at end of file
diff --git a/source-jdbc/src/test/resources/ut_meta/jdbc_source/measure/ut_jdbc_shard/GVM_PERCENTILE.json b/source-jdbc/src/test/resources/ut_meta/jdbc_source/measure/ut_jdbc_shard/GVM_PERCENTILE.json
new file mode 100644
index 0000000..63178aa
--- /dev/null
+++ b/source-jdbc/src/test/resources/ut_meta/jdbc_source/measure/ut_jdbc_shard/GVM_PERCENTILE.json
@@ -0,0 +1,9 @@
+{
+  "uuid" : "58b5b26f-03fe-305b-8cd7-e2ccf4245b44",
+  "last_modified" : 1556980986033,
+  "version" : "2.6.0.20500",
+  "name" : "GVM_PERCENTILE",
+  "cube_name" : "ut_jdbc_shard",
+  "segments_name" : [ ],
+  "online" : true
+}
\ No newline at end of file
diff --git a/source-jdbc/src/test/resources/ut_meta/jdbc_source/measure/ut_jdbc_shard/ITEM_COUNT_SUM.json b/source-jdbc/src/test/resources/ut_meta/jdbc_source/measure/ut_jdbc_shard/ITEM_COUNT_SUM.json
new file mode 100644
index 0000000..1c8cf35
--- /dev/null
+++ b/source-jdbc/src/test/resources/ut_meta/jdbc_source/measure/ut_jdbc_shard/ITEM_COUNT_SUM.json
@@ -0,0 +1,9 @@
+{
+  "uuid" : "37b51e30-fc7d-f843-06ac-35bc259e145a",
+  "last_modified" : 1556980985988,
+  "version" : "2.6.0.20500",
+  "name" : "ITEM_COUNT_SUM",
+  "cube_name" : "ut_jdbc_shard",
+  "segments_name" : [ ],
+  "online" : true
+}
\ No newline at end of file
diff --git a/source-jdbc/src/test/resources/ut_meta/jdbc_source/measure/ut_jdbc_shard/PRICE_RAW.json b/source-jdbc/src/test/resources/ut_meta/jdbc_source/measure/ut_jdbc_shard/PRICE_RAW.json
new file mode 100644
index 0000000..6d9aeaa
--- /dev/null
+++ b/source-jdbc/src/test/resources/ut_meta/jdbc_source/measure/ut_jdbc_shard/PRICE_RAW.json
@@ -0,0 +1,9 @@
+{
+  "uuid" : "4c9fc911-ecb1-2603-95d3-023f68d47b93",
+  "last_modified" : 1556980986027,
+  "version" : "2.6.0.20500",
+  "name" : "PRICE_RAW",
+  "cube_name" : "ut_jdbc_shard",
+  "segments_name" : [ ],
+  "online" : true
+}
\ No newline at end of file
diff --git a/source-jdbc/src/test/resources/ut_meta/jdbc_source/measure/ut_jdbc_shard/SELLER_CONTACT.json b/source-jdbc/src/test/resources/ut_meta/jdbc_source/measure/ut_jdbc_shard/SELLER_CONTACT.json
new file mode 100644
index 0000000..5fb92eb
--- /dev/null
+++ b/source-jdbc/src/test/resources/ut_meta/jdbc_source/measure/ut_jdbc_shard/SELLER_CONTACT.json
@@ -0,0 +1,9 @@
+{
+  "uuid" : "66ca4075-c335-4293-60d4-ef475c7a3015",
+  "last_modified" : 1556980986021,
+  "version" : "2.6.0.20500",
+  "name" : "SELLER_CONTACT",
+  "cube_name" : "ut_jdbc_shard",
+  "segments_name" : [ ],
+  "online" : true
+}
\ No newline at end of file
diff --git a/source-jdbc/src/test/resources/ut_meta/jdbc_source/measure/ut_jdbc_shard/SELLER_FORMAT_HLL.json b/source-jdbc/src/test/resources/ut_meta/jdbc_source/measure/ut_jdbc_shard/SELLER_FORMAT_HLL.json
new file mode 100644
index 0000000..8b66719
--- /dev/null
+++ b/source-jdbc/src/test/resources/ut_meta/jdbc_source/measure/ut_jdbc_shard/SELLER_FORMAT_HLL.json
@@ -0,0 +1,9 @@
+{
+  "uuid" : "d785181a-8d7e-d613-89b9-a59046932919",
+  "last_modified" : 1556980986004,
+  "version" : "2.6.0.20500",
+  "name" : "SELLER_FORMAT_HLL",
+  "cube_name" : "ut_jdbc_shard",
+  "segments_name" : [ ],
+  "online" : true
+}
\ No newline at end of file
diff --git a/source-jdbc/src/test/resources/ut_meta/jdbc_source/measure/ut_jdbc_shard/SELLER_HLL.json b/source-jdbc/src/test/resources/ut_meta/jdbc_source/measure/ut_jdbc_shard/SELLER_HLL.json
new file mode 100644
index 0000000..eef1a98
--- /dev/null
+++ b/source-jdbc/src/test/resources/ut_meta/jdbc_source/measure/ut_jdbc_shard/SELLER_HLL.json
@@ -0,0 +1,9 @@
+{
+  "uuid" : "0fee3058-d48c-c955-6a1d-27cce3ddad07",
+  "last_modified" : 1556980986001,
+  "version" : "2.6.0.20500",
+  "name" : "SELLER_HLL",
+  "cube_name" : "ut_jdbc_shard",
+  "segments_name" : [ ],
+  "online" : true
+}
\ No newline at end of file
diff --git a/source-jdbc/src/test/resources/ut_meta/jdbc_source/measure/ut_jdbc_shard/TEST_COUNT_DISTINCT_BITMAP.json b/source-jdbc/src/test/resources/ut_meta/jdbc_source/measure/ut_jdbc_shard/TEST_COUNT_DISTINCT_BITMAP.json
new file mode 100644
index 0000000..34c1c4b
--- /dev/null
+++ b/source-jdbc/src/test/resources/ut_meta/jdbc_source/measure/ut_jdbc_shard/TEST_COUNT_DISTINCT_BITMAP.json
@@ -0,0 +1,9 @@
+{
+  "uuid" : "8347f264-ba0b-e646-bb87-2a52c1aa2078",
+  "last_modified" : 1556980986012,
+  "version" : "2.6.0.20500",
+  "name" : "TEST_COUNT_DISTINCT_BITMAP",
+  "cube_name" : "ut_jdbc_shard",
+  "segments_name" : [ ],
+  "online" : true
+}
\ No newline at end of file
diff --git a/source-jdbc/src/test/resources/ut_meta/jdbc_source/measure/ut_jdbc_shard/TEST_EXTENDED_COLUMN.json b/source-jdbc/src/test/resources/ut_meta/jdbc_source/measure/ut_jdbc_shard/TEST_EXTENDED_COLUMN.json
new file mode 100644
index 0000000..c401ff9
--- /dev/null
+++ b/source-jdbc/src/test/resources/ut_meta/jdbc_source/measure/ut_jdbc_shard/TEST_EXTENDED_COLUMN.json
@@ -0,0 +1,9 @@
+{
+  "uuid" : "41d1d993-1663-0c39-3d04-41a89420dc29",
+  "last_modified" : 1556980986015,
+  "version" : "2.6.0.20500",
+  "name" : "TEST_EXTENDED_COLUMN",
+  "cube_name" : "ut_jdbc_shard",
+  "segments_name" : [ ],
+  "online" : true
+}
\ No newline at end of file
diff --git a/source-jdbc/src/test/resources/ut_meta/jdbc_source/measure/ut_jdbc_shard/TOP_SELLER.json b/source-jdbc/src/test/resources/ut_meta/jdbc_source/measure/ut_jdbc_shard/TOP_SELLER.json
new file mode 100644
index 0000000..37aa43f
--- /dev/null
+++ b/source-jdbc/src/test/resources/ut_meta/jdbc_source/measure/ut_jdbc_shard/TOP_SELLER.json
@@ -0,0 +1,9 @@
+{
+  "uuid" : "98a70b36-561b-7519-c527-6e314832cd49",
+  "last_modified" : 1556980986008,
+  "version" : "2.6.0.20500",
+  "name" : "TOP_SELLER",
+  "cube_name" : "ut_jdbc_shard",
+  "segments_name" : [ ],
+  "online" : true
+}
\ No newline at end of file
diff --git a/source-jdbc/src/test/resources/ut_meta/jdbc_source/measure/ut_jdbc_shard/TRANS_CNT.json b/source-jdbc/src/test/resources/ut_meta/jdbc_source/measure/ut_jdbc_shard/TRANS_CNT.json
new file mode 100644
index 0000000..8c7319d
--- /dev/null
+++ b/source-jdbc/src/test/resources/ut_meta/jdbc_source/measure/ut_jdbc_shard/TRANS_CNT.json
@@ -0,0 +1,9 @@
+{
+  "uuid" : "7bc0aa31-466a-5bdb-5ecb-9c668fe3df2f",
+  "last_modified" : 1556980985985,
+  "version" : "2.6.0.20500",
+  "name" : "TRANS_CNT",
+  "cube_name" : "ut_jdbc_shard",
+  "segments_name" : [ ],
+  "online" : true
+}
\ No newline at end of file
diff --git a/source-jdbc/src/test/resources/ut_meta/jdbc_source/measure/ut_jdbc_shard/TRANS_ID_RAW.json b/source-jdbc/src/test/resources/ut_meta/jdbc_source/measure/ut_jdbc_shard/TRANS_ID_RAW.json
new file mode 100644
index 0000000..9e80d63
--- /dev/null
+++ b/source-jdbc/src/test/resources/ut_meta/jdbc_source/measure/ut_jdbc_shard/TRANS_ID_RAW.json
@@ -0,0 +1,9 @@
+{
+  "uuid" : "e5f7d731-5860-7a3c-1356-b4d256fc7eb8",
+  "last_modified" : 1556980986024,
+  "version" : "2.6.0.20500",
+  "name" : "TRANS_ID_RAW",
+  "cube_name" : "ut_jdbc_shard",
+  "segments_name" : [ ],
+  "online" : true
+}
\ No newline at end of file


[kylin] 02/02: KYLIN-3986 Add hint about the absent measures after a successful query. Generate the GridTable according to MeasureInstance metadata

Posted by ni...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

nic pushed a commit to branch dynamic-measure
in repository https://gitbox.apache.org/repos/asf/kylin.git

commit 9f21f0c3de4cd4de2288655990e20ad34a4bb47c
Author: yuzhang <sh...@163.com>
AuthorDate: Tue May 7 21:04:23 2019 +0800

    KYLIN-3986 Add hint about the absent measures after a successful query. Generate the GridTable according to MeasureInstance metadata
---
 .../apache/kylin/common/MissingMeasureSegment.java |  88 +++++++++++++
 .../java/org/apache/kylin/common/QueryContext.java |   8 ++
 .../cube/gridtable/CuboidToGridTableMapping.java   |   4 +
 .../CuboidToGridTableMappingFilterNullCol.java     | 143 +++++++++++++++++++++
 .../storage/gtrecord/CubeScanRangePlanner.java     |  48 ++++++-
 .../kylin/storage/hbase/cube/v2/CubeHBaseRPC.java  |  21 ++-
 6 files changed, 305 insertions(+), 7 deletions(-)

diff --git a/core-common/src/main/java/org/apache/kylin/common/MissingMeasureSegment.java b/core-common/src/main/java/org/apache/kylin/common/MissingMeasureSegment.java
new file mode 100644
index 0000000..6a6f9d2
--- /dev/null
+++ b/core-common/src/main/java/org/apache/kylin/common/MissingMeasureSegment.java
@@ -0,0 +1,88 @@
+/*
+ * 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.common;
+
+import com.google.common.collect.Sets;
+
+import java.util.Set;
+import java.util.stream.Collectors;
+
+public class MissingMeasureSegment {
+
+    public static String getKey(String projectName, String cubeName, String segmentName) {
+        return projectName + "/" + cubeName + "/" + segmentName;
+    }
+
+    private String projectName;
+
+    private String cubeName;
+
+    private String segmentName;
+
+    private Set<String> missMeasures;
+
+    public MissingMeasureSegment(String projectName, String cubeName, String segmentName) {
+        this.projectName = projectName;
+        this.cubeName = cubeName;
+        this.segmentName = segmentName;
+    }
+
+    public String getKey() {
+        return getKey(projectName, cubeName, segmentName);
+    }
+
+    public String getMissingMsg(){
+        return cubeName + "-" + segmentName + " missing measures: " + missMeasures.stream().collect(Collectors.joining(", "));
+    }
+
+    public String getProjectName() {
+        return projectName;
+    }
+
+    public void setProjectName(String projectName) {
+        this.projectName = projectName;
+    }
+
+    public String getCubeName() {
+        return cubeName;
+    }
+
+    public void setCubeName(String cubeName) {
+        this.cubeName = cubeName;
+    }
+
+    public String getSegmentName() {
+        return segmentName;
+    }
+
+    public void setSegmentName(String segmentName) {
+        this.segmentName = segmentName;
+    }
+
+    public Set<String> getMissMeasures() {
+        if (missMeasures == null) {
+            missMeasures = Sets.newHashSet();
+        }
+        return missMeasures;
+    }
+
+    public void setMissMeasures(Set<String> missMeasures) {
+        this.missMeasures = missMeasures;
+    }
+}
diff --git a/core-common/src/main/java/org/apache/kylin/common/QueryContext.java b/core-common/src/main/java/org/apache/kylin/common/QueryContext.java
index 000f7bf..a776095 100644
--- a/core-common/src/main/java/org/apache/kylin/common/QueryContext.java
+++ b/core-common/src/main/java/org/apache/kylin/common/QueryContext.java
@@ -65,6 +65,7 @@ public class QueryContext {
 
     private List<RPCStatistics> rpcStatisticsList = Lists.newCopyOnWriteArrayList();
     private Map<Integer, CubeSegmentStatisticsResult> cubeSegmentStatisticsResultMap = Maps.newConcurrentMap();
+    private List<MissingMeasureSegment> missingMeasureSegments;
 
     QueryContext() {
         this(System.currentTimeMillis());
@@ -575,6 +576,13 @@ public class QueryContext {
         }
     }
 
+    public List<MissingMeasureSegment> getMissingMeasureSegments() {
+        if (null == missingMeasureSegments) {
+            missingMeasureSegments = Lists.newArrayListWithCapacity(5);
+        }
+        return missingMeasureSegments;
+    }
+
     public static class CubeSegmentStatisticsResult implements Serializable {
         protected static final long serialVersionUID = 1L;
 
diff --git a/core-cube/src/main/java/org/apache/kylin/cube/gridtable/CuboidToGridTableMapping.java b/core-cube/src/main/java/org/apache/kylin/cube/gridtable/CuboidToGridTableMapping.java
index 05256cc..2e6f898 100644
--- a/core-cube/src/main/java/org/apache/kylin/cube/gridtable/CuboidToGridTableMapping.java
+++ b/core-cube/src/main/java/org/apache/kylin/cube/gridtable/CuboidToGridTableMapping.java
@@ -56,6 +56,10 @@ public class CuboidToGridTableMapping {
     private int nMetrics;
     private Map<FunctionDesc, Integer> metrics2gt; // because count distinct may have a holistic version
 
+    CuboidToGridTableMapping() {
+        this.cuboid = null;
+    }
+
     public CuboidToGridTableMapping(Cuboid cuboid) {
         this.cuboid = cuboid;
         init();
diff --git a/core-cube/src/main/java/org/apache/kylin/cube/gridtable/CuboidToGridTableMappingFilterNullCol.java b/core-cube/src/main/java/org/apache/kylin/cube/gridtable/CuboidToGridTableMappingFilterNullCol.java
new file mode 100644
index 0000000..6d06ed4
--- /dev/null
+++ b/core-cube/src/main/java/org/apache/kylin/cube/gridtable/CuboidToGridTableMappingFilterNullCol.java
@@ -0,0 +1,143 @@
+/*
+ * 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.cube.gridtable;
+
+import com.google.common.collect.Lists;
+import com.google.common.collect.Maps;
+import org.apache.kylin.common.util.BitSets;
+import org.apache.kylin.common.util.ImmutableBitSet;
+import org.apache.kylin.dimension.DimensionEncoding;
+import org.apache.kylin.dimension.IDimensionEncodingMap;
+import org.apache.kylin.metadata.datatype.DataType;
+import org.apache.kylin.metadata.model.FunctionDesc;
+import org.apache.kylin.metadata.model.TblColRef;
+
+import java.util.Collection;
+import java.util.Collections;
+import java.util.List;
+import java.util.Map;
+
+
+public class CuboidToGridTableMappingFilterNullCol extends CuboidToGridTableMapping{
+
+    final private CuboidToGridTableMapping internalMapping;
+    private Collection<FunctionDesc> nullMetrics;
+    private Collection<TblColRef> nullDimensions;
+    private int nullMetricsNum;
+    private int nullDimensionsNum;
+    private ImmutableBitSet nullMetricsIdxSet;
+
+    public CuboidToGridTableMappingFilterNullCol(CuboidToGridTableMapping internalMapping, Collection<FunctionDesc> nullMetrics) {
+        this(internalMapping, nullMetrics, Collections.EMPTY_LIST);
+    }
+
+    private CuboidToGridTableMappingFilterNullCol(CuboidToGridTableMapping internalMapping, Collection<FunctionDesc> nullMetrics, Collection<TblColRef> nullDimensions) {
+        this.internalMapping = internalMapping;
+        this.nullMetrics = nullMetrics;
+        this.nullDimensions = nullDimensions;
+        this.nullMetricsNum = nullMetrics.size();
+        this.nullDimensionsNum = nullDimensions.size();
+        int[] nullMetricsIdx = internalMapping.getMetricsIndexes(nullMetrics);
+        this.nullMetricsIdxSet = new ImmutableBitSet(BitSets.valueOf(nullMetricsIdx));
+    }
+
+    @Override
+    public int getColumnCount() {
+        return internalMapping.getColumnCount() - nullMetricsNum - nullDimensionsNum;
+    }
+
+    @Override
+    public DataType[] getDataTypes() {
+        return internalMapping.getDataTypes();
+    }
+
+    @Override
+    // TODO-yuzhang filter null dimensions
+    public ImmutableBitSet getPrimaryKey() {
+        return internalMapping.getPrimaryKey();
+    }
+
+    @Override
+    public ImmutableBitSet[] getColumnBlocks() {
+        ImmutableBitSet[] result = internalMapping.getColumnBlocks();
+        result[0] = getPrimaryKey();
+        for (int i = 1; i < result.length; i++){
+            result[i] = result[i].andNot(nullMetricsIdxSet);
+        }
+        return result;
+    }
+
+    @Override
+    public int getIndexOf(TblColRef dimension) {
+        if (this.nullDimensions.contains(dimension)){
+            return -1;
+        }
+        return internalMapping.getIndexOf(dimension);
+    }
+
+    @Override
+    public int getIndexOf(FunctionDesc metric) {
+        int idx = internalMapping.getIndexOf(metric);
+        if (nullMetricsIdxSet.get(idx)){
+            return -1;
+        }else{
+            return idx;
+        }
+    }
+
+    @Override
+    public List<TblColRef> getCuboidDimensionsInGTOrder() {
+        List<TblColRef> dimsInGTOrder = Lists.newArrayList(internalMapping.getCuboidDimensionsInGTOrder());
+        dimsInGTOrder.removeAll(nullDimensions);
+        return dimsInGTOrder;
+    }
+
+    @Override
+    public DimensionEncoding[] getDimensionEncodings(IDimensionEncodingMap dimEncMap) {
+        List<TblColRef> dims = getCuboidDimensionsInGTOrder();
+        DimensionEncoding[] dimEncs = new DimensionEncoding[dims.size()];
+        for (int i = 0; i < dimEncs.length; i++) {
+            dimEncs[i] = dimEncMap.get(dims.get(i));
+        }
+        return dimEncs;
+    }
+
+    @Override
+    public Map<Integer, Integer> getDependentMetricsMap() {
+        return Collections.<Integer, Integer> emptyMap();
+    }
+
+    @Override
+    public Map<TblColRef, Integer> getDim2gt() {
+        Map<TblColRef, Integer> result = Maps.newHashMap(internalMapping.getDim2gt());
+        nullDimensions.stream().forEach(d -> result.remove(d));
+        return result;
+    }
+
+    @Override
+    public String[] makeAggrFuncs(Collection<FunctionDesc> metrics) {
+        List<FunctionDesc> metricList = Lists.newArrayListWithCapacity(metrics.size());
+        metrics.stream().forEach(m -> {
+            if (getIndexOf(m) >= 0){
+               metricList.add(m);
+            }
+        });
+        return super.makeAggrFuncs(metricList);
+    }
+}
diff --git a/core-storage/src/main/java/org/apache/kylin/storage/gtrecord/CubeScanRangePlanner.java b/core-storage/src/main/java/org/apache/kylin/storage/gtrecord/CubeScanRangePlanner.java
index 3095c8f..bd12209 100644
--- a/core-storage/src/main/java/org/apache/kylin/storage/gtrecord/CubeScanRangePlanner.java
+++ b/core-storage/src/main/java/org/apache/kylin/storage/gtrecord/CubeScanRangePlanner.java
@@ -27,8 +27,12 @@ import java.util.List;
 import java.util.Locale;
 import java.util.Map;
 import java.util.Set;
+import java.util.stream.Collectors;
 
 import org.apache.kylin.common.KylinConfig;
+import org.apache.kylin.common.MissingMeasureSegment;
+import org.apache.kylin.common.QueryContext;
+import org.apache.kylin.common.QueryContextFacade;
 import org.apache.kylin.common.debug.BackdoorToggles;
 import org.apache.kylin.common.util.ByteArray;
 import org.apache.kylin.common.util.ImmutableBitSet;
@@ -37,6 +41,7 @@ import org.apache.kylin.cube.common.FuzzyValueCombination;
 import org.apache.kylin.cube.cuboid.Cuboid;
 import org.apache.kylin.cube.gridtable.CubeGridTable;
 import org.apache.kylin.cube.gridtable.CuboidToGridTableMapping;
+import org.apache.kylin.cube.gridtable.CuboidToGridTableMappingFilterNullCol;
 import org.apache.kylin.cube.gridtable.RecordComparators;
 import org.apache.kylin.cube.gridtable.ScanRangePlannerBase;
 import org.apache.kylin.cube.kv.CubeDimEncMap;
@@ -48,10 +53,13 @@ import org.apache.kylin.gridtable.GTScanRequest;
 import org.apache.kylin.gridtable.GTScanRequestBuilder;
 import org.apache.kylin.gridtable.GTUtil;
 import org.apache.kylin.gridtable.IGTComparator;
+import org.apache.kylin.measure.MeasureInstance;
+import org.apache.kylin.measure.MeasureManager;
 import org.apache.kylin.metadata.expression.TupleExpression;
 import org.apache.kylin.metadata.filter.TupleFilter;
 import org.apache.kylin.metadata.model.DynamicFunctionDesc;
 import org.apache.kylin.metadata.model.FunctionDesc;
+import org.apache.kylin.metadata.model.MeasureDesc;
 import org.apache.kylin.metadata.model.TblColRef;
 import org.apache.kylin.storage.StorageContext;
 import org.slf4j.Logger;
@@ -88,7 +96,7 @@ public class CubeScanRangePlanner extends ScanRangePlannerBase {
         this.cubeDesc = cubeSegment.getCubeDesc();
         this.cuboid = cuboid;
 
-        final CuboidToGridTableMapping mapping = context.getMapping();
+        final CuboidToGridTableMapping mapping = filterNullGTColumn(context.getMapping(), this.cuboid, this.cubeDesc, this.cubeSegment);
 
         this.gtInfo = CubeGridTable.newGTInfo(cuboid, new CubeDimEncMap(cubeSegment), mapping);
 
@@ -387,4 +395,42 @@ public class CubeScanRangePlanner extends ScanRangePlannerBase {
         this.maxScanRanges = maxScanRanges;
     }
 
+    // filter measures(gtMetric) don't exist in this segment
+    private CuboidToGridTableMapping filterNullGTColumn(CuboidToGridTableMapping mapping, Cuboid cuboid, CubeDesc cubeDesc, CubeSegment cubeSegment) {
+        if (KylinConfig.getInstanceFromEnv().isEditableMetricCube()) {
+            List<FunctionDesc> nullMetrics = getNullMeasure(cubeDesc, cubeSegment);
+            return new CuboidToGridTableMappingFilterNullCol(mapping, nullMetrics);
+        } else {
+            return mapping;
+        }
+    }
+
+    // TODO-yuzhang find null metric according to the timestamp
+    private List<FunctionDesc> getNullMeasure(CubeDesc cubeDesc, CubeSegment cubeSegment) {
+        List<FunctionDesc> nullMetrics = Lists.newArrayListWithCapacity(cubeDesc.getMeasures().size());
+        MeasureManager measureManager = MeasureManager.getInstance(KylinConfig.getInstanceFromEnv());
+        Set<String> measuresOnSegment = measureManager.getMeasuresOnSegment(cubeSegment.getProject(), cubeSegment.getCubeDesc().getName(), cubeSegment.getName())
+                .stream()
+                .map(m -> m.getName())
+                .collect(Collectors.toSet());
+        MissingMeasureSegment mms = new MissingMeasureSegment(cubeDesc.getProject(), cubeDesc.getName(), cubeSegment.getName());
+        for (MeasureDesc measure : cubeDesc.getMeasures()){
+            if (!measuresOnSegment.contains(measure.getName())){
+                MeasureInstance measureInstance = measureManager.getMeasure(cubeDesc.getName(), measure.getName());
+                logger.debug("Current segment[{}-{}] doesn't have measure[{}], you can refresh this segment to caculate this measure. Measure[{}]'s segments: {}",
+                        cubeDesc.getName(), cubeSegment.getName(), measure.getName(), measure.getName(), measureInstance.getSegmentsName());
+                mms.getMissMeasures().add(measureInstance.getName());
+                nullMetrics.add(measure.getFunction());
+            }
+        }
+        if (mms.getMissMeasures().size() > 0) {
+            QueryContext ctx = QueryContextFacade.current();
+            if (ctx != null) {
+                ctx.getMissingMeasureSegments().add(mms);
+            }
+        }
+
+        return nullMetrics;
+    }
+
 }
diff --git a/storage-hbase/src/main/java/org/apache/kylin/storage/hbase/cube/v2/CubeHBaseRPC.java b/storage-hbase/src/main/java/org/apache/kylin/storage/hbase/cube/v2/CubeHBaseRPC.java
index 634a3cd..f030225 100644
--- a/storage-hbase/src/main/java/org/apache/kylin/storage/hbase/cube/v2/CubeHBaseRPC.java
+++ b/storage-hbase/src/main/java/org/apache/kylin/storage/hbase/cube/v2/CubeHBaseRPC.java
@@ -18,9 +18,10 @@
 
 package org.apache.kylin.storage.hbase.cube.v2;
 
-import java.util.Arrays;
 import java.util.Collections;
 import java.util.List;
+import java.util.Set;
+import java.util.stream.Collectors;
 
 import org.apache.hadoop.conf.Configuration;
 import org.apache.hadoop.hbase.HConstants;
@@ -49,6 +50,8 @@ import org.apache.kylin.gridtable.GTInfo;
 import org.apache.kylin.gridtable.GTRecord;
 import org.apache.kylin.gridtable.GTScanRange;
 import org.apache.kylin.gridtable.IGTStorage;
+import org.apache.kylin.measure.MeasureInstance;
+import org.apache.kylin.measure.MeasureManager;
 import org.apache.kylin.metadata.model.ISegment;
 import org.apache.kylin.storage.StorageContext;
 import org.apache.kylin.storage.hbase.HBaseConnection;
@@ -202,17 +205,23 @@ public abstract class CubeHBaseRPC implements IGTStorage {
 
         int colBlkIndex = 1;
         int metricOffset = fullGTInfo.getPrimaryKey().trueBitCount();
-
+        Set<String> measuresOnSegment = MeasureManager.getInstance(cubeSeg.getConfig()).getMeasuresOnSegment(cubeSeg.getProject(), cubeSeg.getCubeDesc().getName(), cubeSeg.getName())
+                .stream()
+                .map(MeasureInstance::getName)
+                .collect(Collectors.toSet());
         HBaseMappingDesc hbaseMapping = cubeSeg.getCubeDesc().getHbaseMapping();
         for (HBaseColumnFamilyDesc familyDesc : hbaseMapping.getColumnFamily()) {
             for (HBaseColumnDesc hbaseColDesc : familyDesc.getColumns()) {
                 if (selectedColBlocks.get(colBlkIndex)) {
                     int[] metricIndexes = hbaseColDesc.getMeasureIndex();
-                    Integer[] gtIndexes = new Integer[metricIndexes.length];
-                    for (int i = 0; i < gtIndexes.length; i++) {
-                        gtIndexes[i] = metricIndexes[i] + metricOffset;
+                    List<Integer> gtIndexList = Lists.newArrayListWithCapacity(metricIndexes.length);
+                    for (int i = 0; i < metricIndexes.length; i++) {
+                        String measureName = cubeSeg.getCubeDesc().getMeasures().get(metricIndexes[i]).getName();
+                        if (measuresOnSegment.contains(measureName)) {
+                            gtIndexList.add(metricIndexes[i] + metricOffset);
+                        }
                     }
-                    ret.add(Arrays.asList(gtIndexes));
+                    ret.add(gtIndexList);
                 }
                 colBlkIndex++;
             }