You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@kylin.apache.org by xx...@apache.org on 2022/12/05 10:21:10 UTC

[kylin] 18/22: KYLIN-5323 fix segment matched to wrong model

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

xxyu pushed a commit to branch kylin5
in repository https://gitbox.apache.org/repos/asf/kylin.git

commit 5c8bb0101796c48091a7e9faecea9e479c4ca6a9
Author: binbin.zheng <bi...@kyligence.io>
AuthorDate: Thu Sep 29 18:44:26 2022 +0800

    KYLIN-5323 fix segment matched to wrong model
---
 .../cube/realization/HybridRealization.java        |  1 -
 .../metadata/realization/CapabilityResult.java     |  6 ++-
 .../kylin/query/routing/CandidateSortTest.java     | 59 ++++++++++++++++++++++
 3 files changed, 64 insertions(+), 2 deletions(-)

diff --git a/src/core-metadata/src/main/java/org/apache/kylin/metadata/cube/realization/HybridRealization.java b/src/core-metadata/src/main/java/org/apache/kylin/metadata/cube/realization/HybridRealization.java
index 0b3354bcf8..a40f4537d4 100644
--- a/src/core-metadata/src/main/java/org/apache/kylin/metadata/cube/realization/HybridRealization.java
+++ b/src/core-metadata/src/main/java/org/apache/kylin/metadata/cube/realization/HybridRealization.java
@@ -133,7 +133,6 @@ public class HybridRealization implements IRealization {
     public CapabilityResult isCapable(SQLDigest digest, List<NDataSegment> prunedSegments,
             List<NDataSegment> prunedStreamingSegments, Map<String, Set<Long>> secondStorageSegmentLayoutMap) {
         CapabilityResult result = new CapabilityResult();
-        result.cost = Integer.MAX_VALUE;
 
         resolveSegmentsOverlap(prunedStreamingSegments);
         for (IRealization realization : getRealizations()) {
diff --git a/src/core-metadata/src/main/java/org/apache/kylin/metadata/realization/CapabilityResult.java b/src/core-metadata/src/main/java/org/apache/kylin/metadata/realization/CapabilityResult.java
index 2368812646..6cad1412b7 100644
--- a/src/core-metadata/src/main/java/org/apache/kylin/metadata/realization/CapabilityResult.java
+++ b/src/core-metadata/src/main/java/org/apache/kylin/metadata/realization/CapabilityResult.java
@@ -48,10 +48,14 @@ public class CapabilityResult {
     @Setter
     private IRealizationCandidate selectedStreamingCandidate;
 
+    @Getter
+    @Setter
+    private int layoutUnmatchedColsSize;
+
     /**
      * The smaller the cost, the more capable the realization
      */
-    public int cost;
+    public int cost = Integer.MAX_VALUE;
 
     /**
      * reason of incapable
diff --git a/src/query/src/test/java/org/apache/kylin/query/routing/CandidateSortTest.java b/src/query/src/test/java/org/apache/kylin/query/routing/CandidateSortTest.java
index f0d093addb..bdb79596e4 100644
--- a/src/query/src/test/java/org/apache/kylin/query/routing/CandidateSortTest.java
+++ b/src/query/src/test/java/org/apache/kylin/query/routing/CandidateSortTest.java
@@ -25,6 +25,7 @@ import java.util.Set;
 
 import org.apache.kylin.common.KylinConfig;
 import org.apache.kylin.common.QueryContext;
+import org.apache.kylin.metadata.cube.cuboid.NLayoutCandidate;
 import org.apache.kylin.metadata.cube.model.NDataSegment;
 import org.apache.kylin.metadata.model.FunctionDesc;
 import org.apache.kylin.metadata.model.MeasureDesc;
@@ -100,6 +101,31 @@ public class CandidateSortTest {
             val model3 = mockCandidate("model0003", "modelC", 4, 4);
             sort(model1, model2, model3).assertFirst(model1);
         }
+
+        {
+            val model1 = mockCandidate("model0001", "modelA", 1, 1);
+            val model2 = mockEmptyCandidate("model0002", "modelB", 1);
+            sort(model1, model2).assertFirst(model1);
+        }
+
+        {
+            val model1 = mockStreamingCandidate("model0001", "modelA", 1, 1);
+            val model2 = mockEmptyCandidate("model0002", "modelB", 1);
+            sort(model1, model2).assertFirst(model1);
+        }
+
+        {
+            val model1 = mockHybridCandidate("model0001", "modelA", 1, 1, 2);
+            val model2 = mockEmptyCandidate("model0002", "modelB", 1);
+            sort(model1, model2).assertFirst(model1);
+        }
+
+        {
+            val model1 = mockCandidate("model0001", "modelA", 1, 3);
+            val model2 = mockStreamingCandidate("model0002", "modelB", 1, 2);
+            val model3 = mockHybridCandidate("model0003", "modelC", 1, 4, 2);
+            sort(model1, model2, model3).assertFirst(model2);
+        }
     }
 
     private interface SortedCandidate {
@@ -120,6 +146,39 @@ public class CandidateSortTest {
         candidate.realization = mockRealization(modelId, modelName, modelCost);
         val cap = new CapabilityResult();
         cap.setSelectedCandidate(() -> candidateCost);
+        cap.cost = (int) cap.getSelectedCandidate().getCost();
+        candidate.setCapability(cap);
+        return candidate;
+    }
+
+    private Candidate mockStreamingCandidate(String modelId, String modelName, int modelCost, double candidateCost) {
+        val candidate = new Candidate();
+        candidate.realization = mockRealization(modelId, modelName, modelCost);
+        val cap = new CapabilityResult();
+        cap.setSelectedStreamingCandidate(() -> candidateCost);
+        cap.cost = (int) cap.getSelectedStreamingCandidate().getCost();
+        candidate.setCapability(cap);
+        return candidate;
+    }
+
+    private Candidate mockHybridCandidate(String modelId, String modelName, int modelCost, double candidateCost,
+            double streamingCandidateCost) {
+        val candidate = new Candidate();
+        candidate.realization = mockRealization(modelId, modelName, modelCost);
+        val cap = new CapabilityResult();
+        cap.setSelectedCandidate(() -> candidateCost);
+        cap.setSelectedStreamingCandidate(() -> streamingCandidateCost);
+        cap.cost = (int) Math.min(cap.getSelectedCandidate().getCost(), cap.getSelectedStreamingCandidate().getCost());
+        candidate.setCapability(cap);
+        return candidate;
+    }
+
+    private Candidate mockEmptyCandidate(String modelId, String modelName, int modelCost) {
+        val candidate = new Candidate();
+        candidate.realization = mockRealization(modelId, modelName, modelCost);
+        val cap = new CapabilityResult();
+        cap.setSelectedCandidate(NLayoutCandidate.EMPTY);
+        cap.setSelectedStreamingCandidate(NLayoutCandidate.EMPTY);
         candidate.setCapability(cap);
         return candidate;
     }