blob: 16d039e370797904bb394d6a9b22eb8829687353 [file] [log] [blame]
/*
* 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.query.dataset.groupby;
import org.apache.iotdb.commons.utils.TestOnly;
import org.apache.iotdb.db.qp.physical.crud.GroupByTimeFillPlan;
import org.apache.iotdb.db.qp.physical.crud.GroupByTimePlan;
import org.apache.iotdb.db.query.aggregation.AggregateResult;
import org.apache.iotdb.db.query.context.QueryContext;
import org.apache.iotdb.db.query.executor.groupby.SlidingWindowGroupByExecutor;
import org.apache.iotdb.db.utils.timerangeiterator.ITimeRangeIterator;
import org.apache.iotdb.db.utils.timerangeiterator.TimeRangeIteratorFactory;
import org.apache.iotdb.tsfile.read.common.RowRecord;
import org.apache.iotdb.tsfile.read.common.TimeRange;
import org.apache.iotdb.tsfile.read.query.dataset.QueryDataSet;
import java.io.IOException;
import java.util.ArrayList;
import static org.apache.iotdb.db.qp.utils.DatetimeUtils.MS_TO_MONTH;
public abstract class GroupByTimeDataSet extends QueryDataSet {
protected long queryId;
protected long interval;
protected long slidingStep;
// total query [startTime, endTime)
protected long startTime;
protected long endTime;
// current interval of aggregation window [curStartTime, curEndTime)
protected TimeRange curAggrTimeRange;
protected boolean hasCachedTimeInterval;
// current interval of pre-aggregation window [curStartTime, curEndTime)
protected TimeRange curPreAggrTimeRange;
protected boolean leftCRightO;
protected boolean isIntervalByMonth = false;
protected boolean isSlidingStepByMonth = false;
ITimeRangeIterator aggrWindowIterator;
ITimeRangeIterator preAggrWindowIterator;
protected AggregateResult[] curAggregateResults;
protected SlidingWindowGroupByExecutor[] slidingWindowGroupByExecutors;
public GroupByTimeDataSet() {}
/** groupBy query. */
public GroupByTimeDataSet(QueryContext context, GroupByTimePlan groupByTimePlan) {
super(
new ArrayList<>(groupByTimePlan.getDeduplicatedPaths()),
groupByTimePlan.getDeduplicatedDataTypes(),
groupByTimePlan.isAscending());
// find the startTime of the first aggregation interval
initGroupByTimeDataSetFields(context, groupByTimePlan);
}
protected void initGroupByTimeDataSetFields(
QueryContext context, GroupByTimePlan groupByTimePlan) {
this.queryId = context.getQueryId();
this.interval = groupByTimePlan.getInterval();
this.slidingStep = groupByTimePlan.getSlidingStep();
if (groupByTimePlan instanceof GroupByTimeFillPlan) {
this.startTime = ((GroupByTimeFillPlan) groupByTimePlan).getQueryStartTime();
this.endTime = ((GroupByTimeFillPlan) groupByTimePlan).getQueryEndTime();
} else {
this.startTime = groupByTimePlan.getStartTime();
this.endTime = groupByTimePlan.getEndTime();
}
this.leftCRightO = groupByTimePlan.isLeftCRightO();
this.ascending = groupByTimePlan.isAscending();
this.isIntervalByMonth = groupByTimePlan.isIntervalByMonth();
this.isSlidingStepByMonth = groupByTimePlan.isSlidingStepByMonth();
if (isIntervalByMonth) {
interval = interval / MS_TO_MONTH;
}
if (isSlidingStepByMonth) {
slidingStep = slidingStep / MS_TO_MONTH;
}
// init TimeRangeIterator
aggrWindowIterator =
TimeRangeIteratorFactory.getTimeRangeIterator(
startTime,
endTime,
interval,
slidingStep,
ascending,
isIntervalByMonth,
isSlidingStepByMonth,
false);
preAggrWindowIterator =
TimeRangeIteratorFactory.getTimeRangeIterator(
startTime,
endTime,
interval,
slidingStep,
ascending,
isIntervalByMonth,
isSlidingStepByMonth,
true);
// find the first aggregation interval
curAggrTimeRange = aggrWindowIterator.nextTimeRange();
// find the first pre-aggregation interval
curPreAggrTimeRange = preAggrWindowIterator.nextTimeRange();
this.hasCachedTimeInterval = true;
slidingWindowGroupByExecutors = new SlidingWindowGroupByExecutor[paths.size()];
}
@Override
public boolean hasNextWithoutConstraint() {
// has cached
if (hasCachedTimeInterval) {
return true;
}
// find the next aggregation interval
if (!aggrWindowIterator.hasNextTimeRange()) {
return false;
}
curAggrTimeRange = aggrWindowIterator.nextTimeRange();
hasCachedTimeInterval = true;
return true;
}
@Override
public abstract RowRecord nextWithoutConstraint() throws IOException;
public long getStartTime() {
return startTime;
}
@TestOnly
public TimeRange nextTimePartition() {
hasCachedTimeInterval = false;
return curAggrTimeRange;
}
}