| /* |
| * 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.iotdb.db.queryengine.execution.operator.window; |
| |
| import org.apache.iotdb.db.queryengine.execution.aggregation.Aggregator; |
| |
| import org.apache.tsfile.block.column.ColumnBuilder; |
| import org.apache.tsfile.enums.TSDataType; |
| import org.apache.tsfile.read.common.block.TsBlock; |
| import org.apache.tsfile.read.common.block.TsBlockBuilder; |
| import org.apache.tsfile.read.common.block.column.TimeColumnBuilder; |
| |
| import java.util.ArrayList; |
| import java.util.Arrays; |
| import java.util.List; |
| |
| /** |
| * Used to customize all the type of window managers, such as TimeWindowManager, |
| * SessionWindowManager. |
| */ |
| public interface IWindowManager { |
| |
| /** |
| * Judge whether the current window is initialized. |
| * |
| * @return whether the current window is initialized |
| */ |
| boolean isCurWindowInit(); |
| |
| /** Used to initialize the status of window. */ |
| void initCurWindow(); |
| |
| /** |
| * Used to determine whether there is a next window. |
| * |
| * @return whether there is a next window |
| */ |
| boolean hasNext(boolean hasMoreData); |
| |
| /** Used to mark the current window has got last point. */ |
| void next(); |
| |
| /** |
| * Used to get current window. |
| * |
| * @return current window |
| */ |
| IWindow getCurWindow(); |
| |
| /** |
| * Used to skip some points through the window attributes, such as timeRange and so on. |
| * |
| * @param inputTsBlock a TsBlock |
| * @return a new TsBlock which skips some points |
| */ |
| TsBlock skipPointsOutOfCurWindow(TsBlock inputTsBlock); |
| |
| /** |
| * Used to determine whether the current window overlaps with TsBlock. |
| * |
| * @param inputTsBlock a TsBlock |
| * @return whether the current window overlaps with TsBlock |
| */ |
| default boolean satisfiedCurWindow(TsBlock inputTsBlock) { |
| return true; |
| } |
| |
| /** |
| * Used to determine whether there are extra points for the next window. |
| * |
| * @param inputTsBlock a TsBlock |
| * @return whether there are extra points for the next window |
| */ |
| default boolean isTsBlockOutOfBound(TsBlock inputTsBlock) { |
| return false; |
| } |
| |
| /** |
| * According to the Aggregator list, we could obtain all the aggregation result column type list. |
| * |
| * @param aggregators the list of aggregators |
| * @return Aggregation result column type list. |
| */ |
| default List<TSDataType> getResultDataTypes(List<Aggregator> aggregators) { |
| List<TSDataType> dataTypes = new ArrayList<>(); |
| for (Aggregator aggregator : aggregators) { |
| dataTypes.addAll(Arrays.asList(aggregator.getOutputType())); |
| } |
| return dataTypes; |
| } |
| |
| /** |
| * Used to create the aggregation resultSet. |
| * |
| * <p>For the implementation, we should consider whether we need to add endTime column and event |
| * column in the resultSet besides the aggregation columns. |
| * |
| * @param aggregators the list of aggregators |
| * @return TsBlockBuilder of resultSet |
| */ |
| TsBlockBuilder createResultTsBlockBuilder(List<Aggregator> aggregators); |
| |
| /** |
| * Used to append a row of aggregation result into the resultSet. |
| * |
| * <p>For the implementation, similar to the method createResultTsBlockBuilder, we should consider |
| * whether we need to add endTime column and event column in the resultSet besides the aggregation |
| * columns. |
| * |
| * @param resultTsBlockBuilder tsBlockBuilder for resultSet |
| * @param aggregators the list of aggregators |
| */ |
| void appendAggregationResult(TsBlockBuilder resultTsBlockBuilder, List<Aggregator> aggregators); |
| |
| /** |
| * Especially for TimeWindow, if there are no points belong to last TimeWindow, the last |
| * TimeWindow will not initialize window and aggregators in the aggregation frame. |
| * |
| * @return whether the window is TimeWindow and the last TimeWindow has not been initialized |
| */ |
| default boolean notInitializedLastTimeWindow() { |
| return false; |
| } |
| |
| /** |
| * When endTime is required in resultSet, operator should skip the points in last window directly |
| * instead of a default lazy way to get the endTime for constructing the result tsBlock. |
| * |
| * <p>For the windows like TimeWindow which has already cached endTime, this method always return |
| * false. |
| */ |
| boolean needSkipInAdvance(); |
| |
| /** |
| * When controlColumn is null, this method determined whether we should consider that row. if |
| * ignoringNull is false, null will be considered as a normal value in window. |
| */ |
| boolean isIgnoringNull(); |
| |
| /** |
| * output the result in aggregators to columnBuilders. |
| * |
| * @param endTime if the window doesn't need to output endTime, just assign -1 to endTime. |
| */ |
| default void outputAggregators( |
| List<Aggregator> aggregators, |
| TsBlockBuilder resultTsBlockBuilder, |
| long startTime, |
| long endTime) { |
| TimeColumnBuilder timeColumnBuilder = resultTsBlockBuilder.getTimeColumnBuilder(); |
| timeColumnBuilder.writeLong(startTime); |
| |
| ColumnBuilder[] columnBuilders = resultTsBlockBuilder.getValueColumnBuilders(); |
| int columnIndex = 0; |
| if (endTime != -1) { |
| columnBuilders[0].writeLong(endTime); |
| columnIndex = 1; |
| } |
| for (Aggregator aggregator : aggregators) { |
| ColumnBuilder[] columnBuilder = new ColumnBuilder[aggregator.getOutputType().length]; |
| columnBuilder[0] = columnBuilders[columnIndex++]; |
| if (columnBuilder.length > 1) { |
| columnBuilder[1] = columnBuilders[columnIndex++]; |
| } |
| aggregator.outputResult(columnBuilder); |
| } |
| resultTsBlockBuilder.declarePosition(); |
| } |
| } |