From 8b677161becc16aa930e95aa32afc0a554afc2be Mon Sep 17 00:00:00 2001 From: Zhong Date: Tue, 16 Aug 2016 17:11:22 +0800 Subject: [PATCH] KYLIN-1960: Provide a new build type called COVER --- .../java/org/apache/kylin/cube/CubeManager.java | 56 ++++++++++++++++++++++ .../apache/kylin/cube/model/CubeBuildTypeEnum.java | 7 ++- .../org/apache/kylin/rest/service/JobService.java | 3 ++ 3 files changed, 65 insertions(+), 1 deletion(-) 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 2ebf5d3..3b83dfe 100644 --- a/core-cube/src/main/java/org/apache/kylin/cube/CubeManager.java +++ b/core-cube/src/main/java/org/apache/kylin/cube/CubeManager.java @@ -19,14 +19,17 @@ package org.apache.kylin.cube; import java.io.IOException; +import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; import java.util.Collections; +import java.util.Date; import java.util.Iterator; import java.util.LinkedList; import java.util.List; import java.util.Random; +import java.util.TimeZone; import java.util.UUID; import java.util.concurrent.ConcurrentHashMap; @@ -462,6 +465,59 @@ public class CubeManager implements IRealizationProvider { return newSegment; } + public CubeSegment coverSegments(CubeInstance cube, long startDate, long endDate, long startOffset, long endOffset) throws IOException { + if (!cube.getDescriptor().getModel().getPartitionDesc().isPartitioned()) { + throw new IllegalArgumentException("The cover build type is only for those cubes with incremental building enabled"); + } + if (startDate >= endDate) { + throw new IllegalArgumentException("Among the parameters, the startDate should be larger than endDate."); + } + List existing = cube.getSegments(); + if (existing.isEmpty() && startDate != cube.getDescriptor().getPartitionDateStart()) { + throw new IllegalArgumentException("The parameter startDate should be the same as the PartitionDateStart set in cube definition!"); + } + boolean ifMatchStart = false; + for (CubeSegment segment : existing) { + if (startDate == segment.getDateRangeStart() || startDate == segment.getDateRangeEnd()) { + ifMatchStart = true; + break; + } + } + if (!ifMatchStart) { + throw new IllegalArgumentException("The parameter startDate should be match the boundary of cube segments!"); + } + boolean ifMatchEnd = false; + if (endDate > cube.getDescriptor().getPartitionDateEnd()) { + SimpleDateFormat f = new SimpleDateFormat("yyyy-MM-dd"); + f.setTimeZone(TimeZone.getTimeZone("GMT")); + throw new IllegalArgumentException("The selected date couldn't be later than cube's end date '" + f.format(new Date(cube.getDescriptor().getPartitionDateEnd())) + "'."); + } else if (endDate >= calculateStartDateForAppendSegment(cube)) { + ifMatchEnd = true; + } else { + for (CubeSegment segment : existing) { + if (endDate == segment.getDateRangeEnd()) { + ifMatchEnd = true; + break; + } + } + } + if (!ifMatchEnd) { + throw new IllegalArgumentException("The parameter endDate should be either larger than end of segments or match the end of an existing cube segment!"); + } + + checkNoBuildingSegment(cube); + + CubeSegment newSegment = newSegment(cube, startDate, endDate, startOffset, endOffset); + + validateNewSegments(cube, newSegment); + + CubeUpdate cubeBuilder = new CubeUpdate(cube); + cubeBuilder.setToAddSegs(newSegment); + updateCube(cubeBuilder); + + return newSegment; + } + public CubeSegment mergeSegments(CubeInstance cube, long startDate, long endDate, long startOffset, long endOffset, boolean force) throws IOException { if (cube.getSegments().isEmpty()) throw new IllegalArgumentException("Cube " + cube + " has no segments"); diff --git a/core-cube/src/main/java/org/apache/kylin/cube/model/CubeBuildTypeEnum.java b/core-cube/src/main/java/org/apache/kylin/cube/model/CubeBuildTypeEnum.java index e3ae214..d065011 100644 --- a/core-cube/src/main/java/org/apache/kylin/cube/model/CubeBuildTypeEnum.java +++ b/core-cube/src/main/java/org/apache/kylin/cube/model/CubeBuildTypeEnum.java @@ -35,5 +35,10 @@ public enum CubeBuildTypeEnum { /** * refresh segments */ - REFRESH + REFRESH, + + /** + * build a segment with range and delete the covered segments + */ + COVER } diff --git a/server-base/src/main/java/org/apache/kylin/rest/service/JobService.java b/server-base/src/main/java/org/apache/kylin/rest/service/JobService.java index e4fbc98..0eff9e5 100644 --- a/server-base/src/main/java/org/apache/kylin/rest/service/JobService.java +++ b/server-base/src/main/java/org/apache/kylin/rest/service/JobService.java @@ -213,6 +213,9 @@ public class JobService extends BasicService { } else if (buildType == CubeBuildTypeEnum.REFRESH) { CubeSegment refreshSeg = getCubeManager().refreshSegment(cube, startDate, endDate, startOffset, endOffset); job = EngineFactory.createBatchCubingJob(refreshSeg, submitter); + } else if (buildType == CubeBuildTypeEnum.COVER) { + CubeSegment newSeg = getCubeManager().coverSegments(cube, startDate, endDate, startOffset, endOffset); + job = EngineFactory.createBatchCubingJob(newSeg, submitter); } else { throw new JobException("invalid build type:" + buildType); } -- 2.5.4 (Apple Git-61)