kylin-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From liy...@apache.org
Subject [01/10] incubator-kylin git commit: KYLIN-609 Add Hybrid as a federation of Cube and Inverted-index realization
Date Fri, 27 Feb 2015 06:28:33 GMT
Repository: incubator-kylin
Updated Branches:
  refs/heads/streaming [created] aa49da35f


KYLIN-609 Add Hybrid as a federation of Cube and Inverted-index realization

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

Branch: refs/heads/streaming
Commit: eea5b0922229a7720824f612d6690eab2e41cd91
Parents: ba4f737
Author: Shao Feng, Shi <shaoshi@ebay.com>
Authored: Fri Feb 13 15:35:03 2015 +0800
Committer: Shao Feng, Shi <shaoshi@ebay.com>
Committed: Fri Feb 13 15:35:03 2015 +0800

----------------------------------------------------------------------
 .../kylin/common/persistence/ResourceStore.java |   1 +
 .../kylin/common/restclient/Broadcaster.java    |   2 +-
 .../org/apache/kylin/cube/CubeInstance.java     |  28 ++++
 .../localmeta/hybrid/test_kylin_hybrid.json     |  16 +++
 .../localmeta/project/default.json              |  11 +-
 .../localmeta/project/onlyinner.json            |   4 -
 .../localmeta/project/onlyleft.json             |   4 -
 .../apache/kylin/invertedindex/IIInstance.java  |  27 ++++
 .../metadata/realization/IRealization.java      |  22 +--
 .../metadata/realization/RealizationType.java   |   2 +-
 .../kylin/storage/StorageEngineFactory.java     |  10 +-
 .../kylin/storage/hybrid/HybridInstance.java    | 134 +++++++++++++++++++
 .../kylin/storage/hybrid/HybridManager.java     | 130 ++++++++++++++++++
 .../storage/hybrid/HybridStorageEngine.java     |   7 +
 .../kylin/storage/hybrid/HybridManagerTest.java |  56 ++++++++
 15 files changed, 427 insertions(+), 27 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-kylin/blob/eea5b092/common/src/main/java/org/apache/kylin/common/persistence/ResourceStore.java
----------------------------------------------------------------------
diff --git a/common/src/main/java/org/apache/kylin/common/persistence/ResourceStore.java b/common/src/main/java/org/apache/kylin/common/persistence/ResourceStore.java
index c5db1a5..4c02494 100644
--- a/common/src/main/java/org/apache/kylin/common/persistence/ResourceStore.java
+++ b/common/src/main/java/org/apache/kylin/common/persistence/ResourceStore.java
@@ -50,6 +50,7 @@ abstract public class ResourceStore {
     public static final String SNAPSHOT_RESOURCE_ROOT = "/table_snapshot";
     public static final String TABLE_EXD_RESOURCE_ROOT = "/table_exd";
     public static final String TABLE_RESOURCE_ROOT = "/table";
+    public static final String HYBRID_RESOURCE_ROOT = "/hybrid";
 
     private static ConcurrentHashMap<KylinConfig, ResourceStore> CACHE = new ConcurrentHashMap<KylinConfig,
ResourceStore>();
 

http://git-wip-us.apache.org/repos/asf/incubator-kylin/blob/eea5b092/common/src/main/java/org/apache/kylin/common/restclient/Broadcaster.java
----------------------------------------------------------------------
diff --git a/common/src/main/java/org/apache/kylin/common/restclient/Broadcaster.java b/common/src/main/java/org/apache/kylin/common/restclient/Broadcaster.java
index 58660ff..e9cefca 100644
--- a/common/src/main/java/org/apache/kylin/common/restclient/Broadcaster.java
+++ b/common/src/main/java/org/apache/kylin/common/restclient/Broadcaster.java
@@ -137,7 +137,7 @@ public class Broadcaster {
     }
 
     public static enum TYPE {
-        CUBE("cube"), CUBE_DESC("cube_desc"), PROJECT("project"), INVERTED_INDEX("inverted_index"),
INVERTED_INDEX_DESC("ii_desc"), TABLE("table"), DATA_MODEL("data_model");
+        CUBE("cube"), CUBE_DESC("cube_desc"), PROJECT("project"), INVERTED_INDEX("inverted_index"),
INVERTED_INDEX_DESC("ii_desc"), TABLE("table"), DATA_MODEL("data_model"), HYBRID("hybrid");
         private String text;
 
         private TYPE(String text) {

http://git-wip-us.apache.org/repos/asf/incubator-kylin/blob/eea5b092/cube/src/main/java/org/apache/kylin/cube/CubeInstance.java
----------------------------------------------------------------------
diff --git a/cube/src/main/java/org/apache/kylin/cube/CubeInstance.java b/cube/src/main/java/org/apache/kylin/cube/CubeInstance.java
index d978887..b389c9f 100644
--- a/cube/src/main/java/org/apache/kylin/cube/CubeInstance.java
+++ b/cube/src/main/java/org/apache/kylin/cube/CubeInstance.java
@@ -348,4 +348,32 @@ public class CubeInstance extends RootPersistentEntity implements IRealization
{
         this.projectName = projectName;
     }
 
+    @Override
+    public long getDateRangeStart() {
+        List<CubeSegment> readySegs = getSegments(SegmentStatusEnum.READY);
+
+        long startTime = Long.MAX_VALUE;
+        for (CubeSegment seg : readySegs) {
+            if (seg.getDateRangeStart() < startTime)
+                startTime = seg.getDateRangeStart();
+        }
+
+        return startTime;
+    }
+
+    @Override
+    public long getDateRangeEnd() {
+
+        List<CubeSegment> readySegs = getSegments(SegmentStatusEnum.READY);
+
+        long endTime = 0;
+        for (CubeSegment seg : readySegs) {
+            if (seg.getDateRangeEnd() > endTime)
+                endTime = seg.getDateRangeEnd();
+        }
+
+        return endTime;
+    }
+
+
 }

http://git-wip-us.apache.org/repos/asf/incubator-kylin/blob/eea5b092/examples/test_case_data/localmeta/hybrid/test_kylin_hybrid.json
----------------------------------------------------------------------
diff --git a/examples/test_case_data/localmeta/hybrid/test_kylin_hybrid.json b/examples/test_case_data/localmeta/hybrid/test_kylin_hybrid.json
new file mode 100644
index 0000000..a11b518
--- /dev/null
+++ b/examples/test_case_data/localmeta/hybrid/test_kylin_hybrid.json
@@ -0,0 +1,16 @@
+{
+  "uuid": "5ca78590-64b6-4367-8fb5-7500eb95fd9c",
+  "name": "test_kylin_hybrid",
+  "historyRealization": {
+    "name": "test_kylin_cube_with_slr_left_join_empty",
+    "type": "CUBE",
+    "realization": "test_kylin_cube_with_slr_left_join_empty"
+  },
+  "realTimeRealization": {
+    "name": "test_kylin_ii",
+    "type": "INVERTED_INDEX",
+    "realization": "test_kylin_ii"
+  },
+  "last_modified": 1420016227424,
+  "create_time": null
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-kylin/blob/eea5b092/examples/test_case_data/localmeta/project/default.json
----------------------------------------------------------------------
diff --git a/examples/test_case_data/localmeta/project/default.json b/examples/test_case_data/localmeta/project/default.json
index c6b8b74..dd13e20 100644
--- a/examples/test_case_data/localmeta/project/default.json
+++ b/examples/test_case_data/localmeta/project/default.json
@@ -26,12 +26,11 @@
       "name": "test_kylin_ii",
       "type": "INVERTED_INDEX",
       "realization": "test_kylin_ii"
+    },
+    {
+      "name": "test_kylin_hybrid",
+      "type": "HYBRID",
+      "realization": "test_kylin_hybrid"
     }
-  ],
-  "cubes": [
-    "test_kylin_cube_with_slr_empty",
-    "test_kylin_cube_without_slr_empty",
-    "test_kylin_cube_with_slr_left_join_empty",
-    "test_kylin_cube_without_slr_left_join_empty"
   ]
 }
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-kylin/blob/eea5b092/examples/test_case_data/localmeta/project/onlyinner.json
----------------------------------------------------------------------
diff --git a/examples/test_case_data/localmeta/project/onlyinner.json b/examples/test_case_data/localmeta/project/onlyinner.json
index b98d762..a3ab387 100644
--- a/examples/test_case_data/localmeta/project/onlyinner.json
+++ b/examples/test_case_data/localmeta/project/onlyinner.json
@@ -12,9 +12,5 @@
       "type": "CUBE",
       "realization": "test_kylin_cube_without_slr_empty"
     }
-  ],
-  "cubes": [
-    "test_kylin_cube_with_slr_empty",
-    "test_kylin_cube_without_slr_empty"
   ]
 }
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-kylin/blob/eea5b092/examples/test_case_data/localmeta/project/onlyleft.json
----------------------------------------------------------------------
diff --git a/examples/test_case_data/localmeta/project/onlyleft.json b/examples/test_case_data/localmeta/project/onlyleft.json
index 9569eea..014ff4b 100644
--- a/examples/test_case_data/localmeta/project/onlyleft.json
+++ b/examples/test_case_data/localmeta/project/onlyleft.json
@@ -12,9 +12,5 @@
       "type": "CUBE",
       "realization": "test_kylin_cube_without_slr_left_join_empty"
     }
-  ],
-  "cubes": [
-    "test_kylin_cube_with_slr_left_join_empty",
-    "test_kylin_cube_without_slr_left_join_empty"
   ]
 }
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-kylin/blob/eea5b092/invertedindex/src/main/java/org/apache/kylin/invertedindex/IIInstance.java
----------------------------------------------------------------------
diff --git a/invertedindex/src/main/java/org/apache/kylin/invertedindex/IIInstance.java b/invertedindex/src/main/java/org/apache/kylin/invertedindex/IIInstance.java
index eeb06ed..07e27a3 100644
--- a/invertedindex/src/main/java/org/apache/kylin/invertedindex/IIInstance.java
+++ b/invertedindex/src/main/java/org/apache/kylin/invertedindex/IIInstance.java
@@ -310,4 +310,31 @@ public class IIInstance extends RootPersistentEntity implements IRealization
{
         this.projectName = projectName;
     }
 
+    @Override
+    public long getDateRangeStart() {
+        List<IISegment> readySegs = getSegments(SegmentStatusEnum.READY);
+
+        long startTime = Long.MAX_VALUE;
+        for (IISegment seg : readySegs) {
+            if (seg.getDateRangeStart() < startTime)
+                startTime = seg.getDateRangeStart();
+        }
+
+        return startTime;
+    }
+
+    @Override
+    public long getDateRangeEnd() {
+
+        List<IISegment> readySegs = getSegments(SegmentStatusEnum.READY);
+
+        long endTime = 0;
+        for (IISegment seg : readySegs) {
+            if (seg.getDateRangeEnd() > endTime)
+                endTime = seg.getDateRangeEnd();
+        }
+
+        return endTime;
+    }
+
 }

http://git-wip-us.apache.org/repos/asf/incubator-kylin/blob/eea5b092/metadata/src/main/java/org/apache/kylin/metadata/realization/IRealization.java
----------------------------------------------------------------------
diff --git a/metadata/src/main/java/org/apache/kylin/metadata/realization/IRealization.java
b/metadata/src/main/java/org/apache/kylin/metadata/realization/IRealization.java
index d1571ce..2febba0 100644
--- a/metadata/src/main/java/org/apache/kylin/metadata/realization/IRealization.java
+++ b/metadata/src/main/java/org/apache/kylin/metadata/realization/IRealization.java
@@ -18,11 +18,11 @@
 
 package org.apache.kylin.metadata.realization;
 
-import java.util.List;
-
 import org.apache.kylin.metadata.model.MeasureDesc;
 import org.apache.kylin.metadata.model.TblColRef;
 
+import java.util.List;
+
 public interface IRealization {
 
     public boolean isCapable(SQLDigest digest);
@@ -32,11 +32,11 @@ public interface IRealization {
      * is to answer the query.
      *
      * @return -1 if the realization cannot fulfill the query;
-     *         or a number between 0-100 if the realization can answer the query, the smaller
-     *         the number, the more efficient the realization.
-     *         Especially,
-     *           0 - means the realization has the exact result pre-calculated, no less no
more;
-     *         100 - means the realization will scan the full table with little or no indexing.
+     * or a number between 0-100 if the realization can answer the query, the smaller
+     * the number, the more efficient the realization.
+     * Especially,
+     * 0 - means the realization has the exact result pre-calculated, no less no more;
+     * 100 - means the realization will scan the full table with little or no indexing.
      */
     public int getCost(SQLDigest digest);
 
@@ -58,9 +58,13 @@ public interface IRealization {
     public String getName();
 
     public String getCanonicalName();
-    
+
     public String getProjectName();
-    
+
     public void setProjectName(String prjName);
 
+    public long getDateRangeStart();
+
+    public long getDateRangeEnd();
+
 }

http://git-wip-us.apache.org/repos/asf/incubator-kylin/blob/eea5b092/metadata/src/main/java/org/apache/kylin/metadata/realization/RealizationType.java
----------------------------------------------------------------------
diff --git a/metadata/src/main/java/org/apache/kylin/metadata/realization/RealizationType.java
b/metadata/src/main/java/org/apache/kylin/metadata/realization/RealizationType.java
index 64e3ab7..1b5dbc5 100644
--- a/metadata/src/main/java/org/apache/kylin/metadata/realization/RealizationType.java
+++ b/metadata/src/main/java/org/apache/kylin/metadata/realization/RealizationType.java
@@ -24,5 +24,5 @@ package org.apache.kylin.metadata.realization;
 
 //TODO: change to String for plugin
 public enum RealizationType {
-    CUBE, INVERTED_INDEX
+    CUBE, INVERTED_INDEX, HYBRID
 }

http://git-wip-us.apache.org/repos/asf/incubator-kylin/blob/eea5b092/storage/src/main/java/org/apache/kylin/storage/StorageEngineFactory.java
----------------------------------------------------------------------
diff --git a/storage/src/main/java/org/apache/kylin/storage/StorageEngineFactory.java b/storage/src/main/java/org/apache/kylin/storage/StorageEngineFactory.java
index 5eb4ea3..2d179bd 100644
--- a/storage/src/main/java/org/apache/kylin/storage/StorageEngineFactory.java
+++ b/storage/src/main/java/org/apache/kylin/storage/StorageEngineFactory.java
@@ -20,10 +20,12 @@ package org.apache.kylin.storage;
 
 import org.apache.kylin.cube.CubeInstance;
 import org.apache.kylin.invertedindex.IIInstance;
-import org.apache.kylin.metadata.realization.RealizationType;
 import org.apache.kylin.metadata.realization.IRealization;
+import org.apache.kylin.metadata.realization.RealizationType;
 import org.apache.kylin.storage.hbase.CubeStorageEngine;
 import org.apache.kylin.storage.hbase.InvertedIndexStorageEngine;
+import org.apache.kylin.storage.hybrid.HybridInstance;
+import org.apache.kylin.storage.hybrid.HybridStorageEngine;
 
 /**
  * @author xjiang
@@ -33,9 +35,13 @@ public class StorageEngineFactory {
     public static IStorageEngine getStorageEngine(IRealization realization) {
         if (realization.getType() == RealizationType.INVERTED_INDEX) {
             return new InvertedIndexStorageEngine((IIInstance) realization);
-        } else {
+        }
+
+        if (realization.getType() == RealizationType.CUBE) {
             return new CubeStorageEngine((CubeInstance) realization);
         }
+
+        return new HybridStorageEngine((HybridInstance) realization);
     }
 
 }

http://git-wip-us.apache.org/repos/asf/incubator-kylin/blob/eea5b092/storage/src/main/java/org/apache/kylin/storage/hybrid/HybridInstance.java
----------------------------------------------------------------------
diff --git a/storage/src/main/java/org/apache/kylin/storage/hybrid/HybridInstance.java b/storage/src/main/java/org/apache/kylin/storage/hybrid/HybridInstance.java
new file mode 100644
index 0000000..657a912
--- /dev/null
+++ b/storage/src/main/java/org/apache/kylin/storage/hybrid/HybridInstance.java
@@ -0,0 +1,134 @@
+package org.apache.kylin.storage.hybrid;
+
+import com.fasterxml.jackson.annotation.JsonAutoDetect;
+import com.fasterxml.jackson.annotation.JsonIgnore;
+import com.fasterxml.jackson.annotation.JsonProperty;
+import org.apache.kylin.common.KylinConfig;
+import org.apache.kylin.common.persistence.RootPersistentEntity;
+import org.apache.kylin.metadata.model.MeasureDesc;
+import org.apache.kylin.metadata.model.TblColRef;
+import org.apache.kylin.metadata.project.RealizationEntry;
+import org.apache.kylin.metadata.realization.IRealization;
+import org.apache.kylin.metadata.realization.RealizationRegistry;
+import org.apache.kylin.metadata.realization.RealizationType;
+import org.apache.kylin.metadata.realization.SQLDigest;
+
+import java.util.List;
+import java.util.UUID;
+
+/**
+ * Created by shaoshi on 2/13/15.
+ */
+
+@JsonAutoDetect(fieldVisibility = JsonAutoDetect.Visibility.NONE, getterVisibility = JsonAutoDetect.Visibility.NONE,
isGetterVisibility = JsonAutoDetect.Visibility.NONE, setterVisibility = JsonAutoDetect.Visibility.NONE)
+public class HybridInstance extends RootPersistentEntity implements IRealization {
+
+    @JsonIgnore
+    private KylinConfig config;
+
+    @JsonProperty("name")
+    private String name;
+
+    @JsonProperty("historyRealization")
+    private RealizationEntry historyRealization;
+
+    @JsonProperty("realTimeRealization")
+    private RealizationEntry realTimeRealization;
+
+    private IRealization historyRealizationInstance;
+    private IRealization realTimeRealizationInstance;
+    private String projectName;
+
+    public void init() {
+        RealizationRegistry registry = RealizationRegistry.getInstance(config);
+        historyRealizationInstance = registry.getRealization(historyRealization.getType(),
historyRealization.getRealization());
+        realTimeRealizationInstance = registry.getRealization(realTimeRealizationInstance.getType(),
historyRealization.getRealization());
+
+    }
+
+    @Override
+    public boolean isCapable(SQLDigest digest) {
+        return historyRealizationInstance.isCapable(digest) || realTimeRealizationInstance.isCapable(digest);
+    }
+
+    @Override
+    public int getCost(SQLDigest digest) {
+        int cost = Math.min(historyRealizationInstance.getCost(digest), realTimeRealizationInstance.getCost(digest))
- 1;
+
+        return cost < 0 ? 0 : cost;
+    }
+
+    @Override
+    public RealizationType getType() {
+        return RealizationType.HYBRID;
+    }
+
+    @Override
+    public String getFactTable() {
+        return null;
+    }
+
+    @Override
+    public List<TblColRef> getAllColumns() {
+        return null;
+    }
+
+    @Override
+    public List<MeasureDesc> getMeasures() {
+        return null;
+    }
+
+    @Override
+    public boolean isReady() {
+        return historyRealizationInstance.isReady() || realTimeRealizationInstance.isReady();
+    }
+
+    @Override
+    public String getName() {
+        return name;
+    }
+
+    public void setName(String name) {
+        this.name = name;
+    }
+
+
+    @Override
+    public String getCanonicalName() {
+        return getType() + "[name=" + name + "]";
+    }
+
+    @Override
+    public String getProjectName() {
+        return projectName;
+    }
+
+    @Override
+    public void setProjectName(String prjName) {
+        projectName = prjName;
+    }
+
+    public KylinConfig getConfig() {
+        return config;
+    }
+
+    public void setConfig(KylinConfig config) {
+        this.config = config;
+    }
+
+    public RealizationEntry getHistoryRealization() {
+        return historyRealization;
+    }
+
+    public RealizationEntry getRealTimeRealization() {
+        return realTimeRealization;
+    }
+
+    public IRealization getHistoryRealizationInstance() {
+        return historyRealizationInstance;
+    }
+
+    public IRealization getRealTimeRealizationInstance() {
+        return realTimeRealizationInstance;
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-kylin/blob/eea5b092/storage/src/main/java/org/apache/kylin/storage/hybrid/HybridManager.java
----------------------------------------------------------------------
diff --git a/storage/src/main/java/org/apache/kylin/storage/hybrid/HybridManager.java b/storage/src/main/java/org/apache/kylin/storage/hybrid/HybridManager.java
new file mode 100644
index 0000000..20f5545
--- /dev/null
+++ b/storage/src/main/java/org/apache/kylin/storage/hybrid/HybridManager.java
@@ -0,0 +1,130 @@
+package org.apache.kylin.storage.hybrid;
+
+import org.apache.commons.lang3.StringUtils;
+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.restclient.Broadcaster;
+import org.apache.kylin.common.restclient.CaseInsensitiveStringCache;
+import org.apache.kylin.metadata.realization.IRealization;
+import org.apache.kylin.metadata.realization.IRealizationProvider;
+import org.apache.kylin.metadata.realization.RealizationType;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.io.IOException;
+import java.util.List;
+import java.util.concurrent.ConcurrentHashMap;
+
+/**
+ * Created by shaoshi on 2/13/15.
+ */
+public class HybridManager implements IRealizationProvider {
+    public static final Serializer<HybridInstance> HYBRID_SERIALIZER = new JsonSerializer<HybridInstance>(HybridInstance.class);
+
+    private static final Logger logger = LoggerFactory.getLogger(HybridManager.class);
+
+    // static cached instances
+    private static final ConcurrentHashMap<KylinConfig, HybridManager> CACHE = new
ConcurrentHashMap<KylinConfig, HybridManager>();
+
+    public static HybridManager getInstance(KylinConfig config) {
+        HybridManager r = CACHE.get(config);
+        if (r != null) {
+            return r;
+        }
+
+        synchronized (HybridManager.class) {
+            r = CACHE.get(config);
+            if (r != null) {
+                return r;
+            }
+            try {
+                r = new HybridManager(config);
+                CACHE.put(config, r);
+                if (CACHE.size() > 1) {
+                    logger.warn("More than one Hybrid Manager singleton exist");
+                }
+                return r;
+            } catch (IOException e) {
+                throw new IllegalStateException("Failed to init Hybrid Manager from " + config,
e);
+            }
+        }
+    }
+
+    public static void clearCache() {
+        CACHE.clear();
+    }
+
+    // ============================================================================
+
+    private KylinConfig config;
+
+    private CaseInsensitiveStringCache<HybridInstance> hybridMap = new CaseInsensitiveStringCache<HybridInstance>(Broadcaster.TYPE.HYBRID);
+
+    private HybridManager(KylinConfig config) throws IOException {
+        logger.info("Initializing HybridManager with config " + config);
+        this.config = config;
+
+        loadAllHybridInstance();
+    }
+
+    private void loadAllHybridInstance() throws IOException {
+        ResourceStore store = getStore();
+        List<String> paths = store.collectResourceRecursively(ResourceStore.HYBRID_RESOURCE_ROOT,
".json");
+
+        logger.debug("Loading Hybrid from folder " + store.getReadableResourcePath(ResourceStore.HYBRID_RESOURCE_ROOT));
+
+        for (String path : paths) {
+            loadHybridInstance(path);
+        }
+
+        logger.debug("Loaded " + paths.size() + " Hybrid(s)");
+    }
+
+    private synchronized HybridInstance loadHybridInstance(String path) throws IOException
{
+        ResourceStore store = getStore();
+
+        HybridInstance hybridInstance = null;
+        try {
+            hybridInstance = store.getResource(path, HybridInstance.class, HYBRID_SERIALIZER);
+            hybridInstance.setConfig(config);
+
+            if (StringUtils.isBlank(hybridInstance.getName()))
+                throw new IllegalStateException("HybridInstance name must not be blank, at
" + path);
+
+            if (hybridInstance.getHistoryRealization() == null || hybridInstance.getRealTimeRealization()
== null) {
+
+                throw new IllegalStateException("HybridInstance must have both historyRealization
and realTimeRealization set, at " + path);
+            }
+
+            hybridInstance.init();
+
+            final String name = hybridInstance.getName();
+            hybridMap.putLocal(name, hybridInstance);
+
+            return hybridInstance;
+        } catch (Exception e) {
+            logger.error("Error during load hybrid instance " + path, e);
+            return null;
+        }
+    }
+
+    @Override
+    public RealizationType getRealizationType() {
+        return RealizationType.HYBRID;
+    }
+
+    @Override
+    public IRealization getRealization(String name) {
+        return getHybridInstance(name);
+    }
+
+    public HybridInstance getHybridInstance(String name) {
+        return hybridMap.get(name);
+    }
+
+    private ResourceStore getStore() {
+        return ResourceStore.getStore(this.config);
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-kylin/blob/eea5b092/storage/src/main/java/org/apache/kylin/storage/hybrid/HybridStorageEngine.java
----------------------------------------------------------------------
diff --git a/storage/src/main/java/org/apache/kylin/storage/hybrid/HybridStorageEngine.java
b/storage/src/main/java/org/apache/kylin/storage/hybrid/HybridStorageEngine.java
new file mode 100644
index 0000000..5efa6e1
--- /dev/null
+++ b/storage/src/main/java/org/apache/kylin/storage/hybrid/HybridStorageEngine.java
@@ -0,0 +1,7 @@
+package org.apache.kylin.storage.hybrid;
+
+/**
+ * Created by shaoshi on 2/13/15.
+ */
+public class HybridStorageEngine {
+}

http://git-wip-us.apache.org/repos/asf/incubator-kylin/blob/eea5b092/storage/src/test/java/org/apache/kylin/storage/hybrid/HybridManagerTest.java
----------------------------------------------------------------------
diff --git a/storage/src/test/java/org/apache/kylin/storage/hybrid/HybridManagerTest.java
b/storage/src/test/java/org/apache/kylin/storage/hybrid/HybridManagerTest.java
new file mode 100644
index 0000000..1f1fd39
--- /dev/null
+++ b/storage/src/test/java/org/apache/kylin/storage/hybrid/HybridManagerTest.java
@@ -0,0 +1,56 @@
+package org.apache.kylin.storage.hybrid;
+
+import org.apache.kylin.common.KylinConfig;
+import org.apache.kylin.common.persistence.ResourceStore;
+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.model.CubeDesc;
+import org.apache.kylin.invertedindex.IIInstance;
+import org.apache.kylin.metadata.project.ProjectInstance;
+import org.apache.kylin.metadata.project.ProjectManager;
+import org.apache.kylin.metadata.realization.IRealization;
+import org.junit.After;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
+
+/**
+ * Created by shaoshi on 2/13/15.
+ */
+public class HybridManagerTest extends LocalFileMetadataTestCase {
+
+    @Before
+    public void setUp() throws Exception {
+        this.createTestMetadata();
+    }
+
+    @After
+    public void after() throws Exception {
+        this.cleanupTestMetadata();
+    }
+
+    @Test
+    public void testBasics() throws Exception {
+        HybridInstance cube = getHybridManager().getHybridInstance("test_kylin_hybrid");
+
+        System.out.println(JsonUtil.writeValueAsIndentString(cube));
+
+        IRealization history = cube.getHistoryRealizationInstance();
+        IRealization realTime = cube.getRealTimeRealizationInstance();
+
+        Assert.assertTrue(history instanceof CubeInstance);
+        Assert.assertTrue(realTime instanceof IIInstance);
+
+    }
+
+
+    public HybridManager getHybridManager() {
+        return HybridManager.getInstance(getTestConfig());
+    }
+}


Mime
View raw message