You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@iotdb.apache.org by ja...@apache.org on 2023/01/05 02:10:38 UTC
[iotdb] branch master updated: [IOTDB-5308] Limit the output tsblock's size of each operator[Part1]
This is an automated email from the ASF dual-hosted git repository.
jackietien pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/iotdb.git
The following commit(s) were added to refs/heads/master by this push:
new df78367ee6 [IOTDB-5308] Limit the output tsblock's size of each operator[Part1]
df78367ee6 is described below
commit df78367ee6ac6a83f6c61a032bb2718b86126057
Author: Xiangwei Wei <34...@users.noreply.github.com>
AuthorDate: Thu Jan 5 10:10:32 2023 +0800
[IOTDB-5308] Limit the output tsblock's size of each operator[Part1]
---
.../apache/iotdb/db/it/IoTDBFloatPrecisionIT.java | 3 -
.../mpp/execution/operator/AbstractOperator.java | 94 ++++++++++++++++++++++
.../operator/process/AbstractProcessOperator.java | 24 ++++++
.../process/join/RowBasedTimeJoinOperator.java | 35 ++++----
.../operator/process/join/TimeJoinOperator.java | 31 +++----
.../source/AbstractDataSourceOperator.java | 32 ++++++++
.../AbstractSeriesAggregationScanOperator.java | 21 +----
.../operator/source/AbstractSourceOperator.java | 33 ++++++++
.../operator/source/AlignedSeriesScanOperator.java | 50 +++++-------
.../operator/source/SeriesScanOperator.java | 41 +++-------
.../mpp/execution/operator/OperatorMemoryTest.java | 28 ++++---
.../iotdb/tsfile/read/common/block/TsBlock.java | 9 +++
.../read/common/block/column/BinaryColumn.java | 5 ++
.../read/common/block/column/BooleanColumn.java | 5 ++
.../tsfile/read/common/block/column/Column.java | 2 +
.../read/common/block/column/DoubleColumn.java | 5 ++
.../read/common/block/column/FloatColumn.java | 5 ++
.../tsfile/read/common/block/column/IntColumn.java | 5 ++
.../read/common/block/column/LongColumn.java | 5 ++
.../read/common/block/column/NullColumn.java | 5 ++
.../block/column/RunLengthEncodedColumn.java | 5 ++
.../read/common/block/column/TimeColumn.java | 5 ++
22 files changed, 330 insertions(+), 118 deletions(-)
diff --git a/integration-test/src/test/java/org/apache/iotdb/db/it/IoTDBFloatPrecisionIT.java b/integration-test/src/test/java/org/apache/iotdb/db/it/IoTDBFloatPrecisionIT.java
index 8c85dbbcba..b9cb021564 100644
--- a/integration-test/src/test/java/org/apache/iotdb/db/it/IoTDBFloatPrecisionIT.java
+++ b/integration-test/src/test/java/org/apache/iotdb/db/it/IoTDBFloatPrecisionIT.java
@@ -42,7 +42,6 @@ import java.util.List;
import static org.apache.iotdb.db.constant.TestConstant.TIMESTAMP_STR;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
/**
@@ -108,8 +107,6 @@ public class IoTDBFloatPrecisionIT {
public void selectAllSQLTest() {
try (Connection connection = EnvFactory.getEnv().getConnection();
Statement statement = connection.createStatement()) {
- boolean hasResultSet = statement.execute("select * from root.**");
- assertTrue(hasResultSet);
int cnt;
try (ResultSet resultSet = statement.executeQuery("select * from root.**")) {
assertNotNull(resultSet);
diff --git a/server/src/main/java/org/apache/iotdb/db/mpp/execution/operator/AbstractOperator.java b/server/src/main/java/org/apache/iotdb/db/mpp/execution/operator/AbstractOperator.java
new file mode 100644
index 0000000000..8e5dc25271
--- /dev/null
+++ b/server/src/main/java/org/apache/iotdb/db/mpp/execution/operator/AbstractOperator.java
@@ -0,0 +1,94 @@
+/*
+ * 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.mpp.execution.operator;
+
+import org.apache.iotdb.tsfile.common.conf.TSFileDescriptor;
+import org.apache.iotdb.tsfile.read.common.block.TsBlock;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public abstract class AbstractOperator implements Operator {
+
+ private static final Logger LOGGER = LoggerFactory.getLogger(AbstractOperator.class);
+ protected OperatorContext operatorContext;
+
+ protected long maxReturnSize =
+ TSFileDescriptor.getInstance().getConfig().getMaxTsBlockSizeInBytes();
+ protected int maxTupleSizeOfTsBlock = -1;
+ protected TsBlock resultTsBlock;
+ protected TsBlock retainedTsBlock;
+ protected int startOffset = 0;
+
+ public void initializeMaxTsBlockLength(TsBlock tsBlock) {
+ if (maxTupleSizeOfTsBlock != -1) {
+ return;
+ }
+ long oneTupleSize =
+ (tsBlock.getRetainedSizeInBytes() - tsBlock.getTotalInstanceSize())
+ / tsBlock.getPositionCount();
+ if (oneTupleSize > maxReturnSize) {
+ // make sure at least one-tuple-at-a-time
+ this.maxTupleSizeOfTsBlock = 1;
+ LOGGER.warn("Only one tuple can be sent each time caused by limited memory");
+ } else {
+ this.maxTupleSizeOfTsBlock = (int) (maxReturnSize / oneTupleSize);
+ }
+ LOGGER.debug("maxTupleSizeOfTsBlock is:{}", maxTupleSizeOfTsBlock);
+ }
+
+ public TsBlock checkTsBlockSizeAndGetResult() {
+ if (resultTsBlock == null) {
+ throw new IllegalArgumentException("Result tsBlock cannot be null");
+ }
+ if (maxTupleSizeOfTsBlock == -1) {
+ initializeMaxTsBlockLength(resultTsBlock);
+ }
+
+ if (resultTsBlock.getPositionCount() <= maxTupleSizeOfTsBlock) {
+ TsBlock res = resultTsBlock;
+ resultTsBlock = null;
+ return res;
+ } else {
+ retainedTsBlock = resultTsBlock;
+ resultTsBlock = null;
+ return getResultFromRetainedTsBlock();
+ }
+ }
+
+ public TsBlock getResultFromRetainedTsBlock() {
+ TsBlock res;
+ if (retainedTsBlock.getPositionCount() - startOffset <= maxTupleSizeOfTsBlock) {
+ res = retainedTsBlock.subTsBlock(startOffset);
+ retainedTsBlock = null;
+ startOffset = 0;
+ } else {
+ res = retainedTsBlock.getRegion(startOffset, maxTupleSizeOfTsBlock);
+ startOffset += maxTupleSizeOfTsBlock;
+ }
+ LOGGER.debug("Current tsBlock size is : {}", res.getRetainedSizeInBytes());
+ return res;
+ }
+
+ @Override
+ public OperatorContext getOperatorContext() {
+ return operatorContext;
+ }
+}
diff --git a/server/src/main/java/org/apache/iotdb/db/mpp/execution/operator/process/AbstractProcessOperator.java b/server/src/main/java/org/apache/iotdb/db/mpp/execution/operator/process/AbstractProcessOperator.java
new file mode 100644
index 0000000000..2e024256aa
--- /dev/null
+++ b/server/src/main/java/org/apache/iotdb/db/mpp/execution/operator/process/AbstractProcessOperator.java
@@ -0,0 +1,24 @@
+/*
+ * 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.mpp.execution.operator.process;
+
+import org.apache.iotdb.db.mpp.execution.operator.AbstractOperator;
+
+public abstract class AbstractProcessOperator extends AbstractOperator implements ProcessOperator {}
diff --git a/server/src/main/java/org/apache/iotdb/db/mpp/execution/operator/process/join/RowBasedTimeJoinOperator.java b/server/src/main/java/org/apache/iotdb/db/mpp/execution/operator/process/join/RowBasedTimeJoinOperator.java
index 1c4211d003..910e08b86d 100644
--- a/server/src/main/java/org/apache/iotdb/db/mpp/execution/operator/process/join/RowBasedTimeJoinOperator.java
+++ b/server/src/main/java/org/apache/iotdb/db/mpp/execution/operator/process/join/RowBasedTimeJoinOperator.java
@@ -20,7 +20,7 @@ package org.apache.iotdb.db.mpp.execution.operator.process.join;
import org.apache.iotdb.db.mpp.execution.operator.Operator;
import org.apache.iotdb.db.mpp.execution.operator.OperatorContext;
-import org.apache.iotdb.db.mpp.execution.operator.process.ProcessOperator;
+import org.apache.iotdb.db.mpp.execution.operator.process.AbstractProcessOperator;
import org.apache.iotdb.db.mpp.execution.operator.process.join.merge.ColumnMerger;
import org.apache.iotdb.db.mpp.execution.operator.process.join.merge.TimeComparator;
import org.apache.iotdb.db.mpp.plan.statement.component.Ordering;
@@ -39,9 +39,7 @@ import java.util.List;
import static com.google.common.base.Preconditions.checkArgument;
import static com.google.common.util.concurrent.Futures.successfulAsList;
-public class RowBasedTimeJoinOperator implements ProcessOperator {
-
- private final OperatorContext operatorContext;
+public class RowBasedTimeJoinOperator extends AbstractProcessOperator {
private final List<Operator> children;
@@ -104,11 +102,11 @@ public class RowBasedTimeJoinOperator implements ProcessOperator {
this.tsBlockBuilder = new TsBlockBuilder(dataTypes);
this.mergers = mergers;
this.comparator = comparator;
- }
-
- @Override
- public OperatorContext getOperatorContext() {
- return operatorContext;
+ this.maxReturnSize =
+ Math.min(
+ maxReturnSize,
+ (1L + outputColumnCount)
+ * TSFileDescriptor.getInstance().getConfig().getPageSizeInByte());
}
@Override
@@ -127,6 +125,9 @@ public class RowBasedTimeJoinOperator implements ProcessOperator {
@Override
public TsBlock next() {
+ if (retainedTsBlock != null) {
+ return getResultFromRetainedTsBlock();
+ }
tsBlockBuilder.reset();
// end time for returned TsBlock this time, it's the min/max end time among all the children
// TsBlocks order by asc/desc
@@ -198,7 +199,9 @@ public class RowBasedTimeJoinOperator implements ProcessOperator {
}
tsBlockBuilder.declarePosition();
} while (currentTime < currentEndTime && !timeSelector.isEmpty());
- return tsBlockBuilder.build();
+
+ resultTsBlock = tsBlockBuilder.build();
+ return checkTsBlockSizeAndGetResult();
}
@Override
@@ -206,6 +209,9 @@ public class RowBasedTimeJoinOperator implements ProcessOperator {
if (finished) {
return false;
}
+ if (retainedTsBlock != null) {
+ return true;
+ }
for (int i = 0; i < inputOperatorsCount; i++) {
if (!empty(i)) {
return true;
@@ -233,8 +239,11 @@ public class RowBasedTimeJoinOperator implements ProcessOperator {
if (finished) {
return true;
}
- finished = true;
+ if (retainedTsBlock != null) {
+ return false;
+ }
+ finished = true;
for (int i = 0; i < inputOperatorsCount; i++) {
// has more tsBlock output from children[i] or has cached tsBlock in inputTsBlocks[i]
if (!noMoreTsBlocks[i] || !empty(i)) {
@@ -262,9 +271,7 @@ public class RowBasedTimeJoinOperator implements ProcessOperator {
@Override
public long calculateMaxReturnSize() {
- // time + all value columns
- return (1L + outputColumnCount)
- * TSFileDescriptor.getInstance().getConfig().getPageSizeInByte();
+ return maxReturnSize;
}
@Override
diff --git a/server/src/main/java/org/apache/iotdb/db/mpp/execution/operator/process/join/TimeJoinOperator.java b/server/src/main/java/org/apache/iotdb/db/mpp/execution/operator/process/join/TimeJoinOperator.java
index 18bcd8836a..fdd91d52b0 100644
--- a/server/src/main/java/org/apache/iotdb/db/mpp/execution/operator/process/join/TimeJoinOperator.java
+++ b/server/src/main/java/org/apache/iotdb/db/mpp/execution/operator/process/join/TimeJoinOperator.java
@@ -20,12 +20,11 @@ package org.apache.iotdb.db.mpp.execution.operator.process.join;
import org.apache.iotdb.db.mpp.execution.operator.Operator;
import org.apache.iotdb.db.mpp.execution.operator.OperatorContext;
-import org.apache.iotdb.db.mpp.execution.operator.process.ProcessOperator;
+import org.apache.iotdb.db.mpp.execution.operator.process.AbstractProcessOperator;
import org.apache.iotdb.db.mpp.execution.operator.process.join.merge.ColumnMerger;
import org.apache.iotdb.db.mpp.execution.operator.process.join.merge.TimeComparator;
import org.apache.iotdb.db.mpp.plan.statement.component.Ordering;
import org.apache.iotdb.db.utils.datastructure.TimeSelector;
-import org.apache.iotdb.tsfile.common.conf.TSFileDescriptor;
import org.apache.iotdb.tsfile.file.metadata.enums.TSDataType;
import org.apache.iotdb.tsfile.read.common.block.TsBlock;
import org.apache.iotdb.tsfile.read.common.block.TsBlockBuilder;
@@ -39,9 +38,8 @@ import java.util.List;
import static com.google.common.base.Preconditions.checkArgument;
import static com.google.common.util.concurrent.Futures.successfulAsList;
-public class TimeJoinOperator implements ProcessOperator {
-
- private final OperatorContext operatorContext;
+@Deprecated
+public class TimeJoinOperator extends AbstractProcessOperator {
private final List<Operator> children;
@@ -106,11 +104,6 @@ public class TimeJoinOperator implements ProcessOperator {
this.comparator = comparator;
}
- @Override
- public OperatorContext getOperatorContext() {
- return operatorContext;
- }
-
@Override
public ListenableFuture<?> isBlocked() {
List<ListenableFuture<?>> listenableFutures = new ArrayList<>();
@@ -127,6 +120,9 @@ public class TimeJoinOperator implements ProcessOperator {
@Override
public TsBlock next() {
+ if (retainedTsBlock != null) {
+ return getResultFromRetainedTsBlock();
+ }
tsBlockBuilder.reset();
// end time for returned TsBlock this time, it's the min/max end time among all the children
// TsBlocks order by asc/desc
@@ -197,7 +193,9 @@ public class TimeJoinOperator implements ProcessOperator {
// update inputIndex using shadowInputIndex
System.arraycopy(shadowInputIndex, 0, inputIndex, 0, inputOperatorsCount);
- return tsBlockBuilder.build();
+ resultTsBlock = tsBlockBuilder.build();
+
+ return checkTsBlockSizeAndGetResult();
}
@Override
@@ -205,6 +203,9 @@ public class TimeJoinOperator implements ProcessOperator {
if (finished) {
return false;
}
+ if (retainedTsBlock != null) {
+ return true;
+ }
for (int i = 0; i < inputOperatorsCount; i++) {
if (!empty(i)) {
return true;
@@ -232,8 +233,11 @@ public class TimeJoinOperator implements ProcessOperator {
if (finished) {
return true;
}
- finished = true;
+ if (retainedTsBlock != null) {
+ return false;
+ }
+ finished = true;
for (int i = 0; i < inputOperatorsCount; i++) {
// has more tsBlock output from children[i] or has cached tsBlock in inputTsBlocks[i]
if (!noMoreTsBlocks[i] || !empty(i)) {
@@ -262,8 +266,7 @@ public class TimeJoinOperator implements ProcessOperator {
@Override
public long calculateMaxReturnSize() {
// time + all value columns
- return (1L + outputColumnCount)
- * TSFileDescriptor.getInstance().getConfig().getPageSizeInByte();
+ return maxReturnSize;
}
@Override
diff --git a/server/src/main/java/org/apache/iotdb/db/mpp/execution/operator/source/AbstractDataSourceOperator.java b/server/src/main/java/org/apache/iotdb/db/mpp/execution/operator/source/AbstractDataSourceOperator.java
new file mode 100644
index 0000000000..c810d61b64
--- /dev/null
+++ b/server/src/main/java/org/apache/iotdb/db/mpp/execution/operator/source/AbstractDataSourceOperator.java
@@ -0,0 +1,32 @@
+/*
+ * 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.mpp.execution.operator.source;
+
+import org.apache.iotdb.db.engine.querycontext.QueryDataSource;
+
+public abstract class AbstractDataSourceOperator extends AbstractSourceOperator
+ implements DataSourceOperator {
+ protected SeriesScanUtil seriesScanUtil;
+
+ @Override
+ public void initQueryDataSource(QueryDataSource dataSource) {
+ seriesScanUtil.initQueryDataSource(dataSource);
+ }
+}
diff --git a/server/src/main/java/org/apache/iotdb/db/mpp/execution/operator/source/AbstractSeriesAggregationScanOperator.java b/server/src/main/java/org/apache/iotdb/db/mpp/execution/operator/source/AbstractSeriesAggregationScanOperator.java
index ed6c92c199..467b895216 100644
--- a/server/src/main/java/org/apache/iotdb/db/mpp/execution/operator/source/AbstractSeriesAggregationScanOperator.java
+++ b/server/src/main/java/org/apache/iotdb/db/mpp/execution/operator/source/AbstractSeriesAggregationScanOperator.java
@@ -19,7 +19,6 @@
package org.apache.iotdb.db.mpp.execution.operator.source;
-import org.apache.iotdb.db.engine.querycontext.QueryDataSource;
import org.apache.iotdb.db.mpp.aggregation.Aggregator;
import org.apache.iotdb.db.mpp.aggregation.timerangeiterator.ITimeRangeIterator;
import org.apache.iotdb.db.mpp.execution.operator.OperatorContext;
@@ -43,14 +42,11 @@ import static org.apache.iotdb.db.mpp.execution.operator.AggregationUtil.appendA
import static org.apache.iotdb.db.mpp.execution.operator.AggregationUtil.calculateAggregationFromRawData;
import static org.apache.iotdb.db.mpp.execution.operator.AggregationUtil.isAllAggregatorsHasFinalResult;
-public abstract class AbstractSeriesAggregationScanOperator implements DataSourceOperator {
+public abstract class AbstractSeriesAggregationScanOperator extends AbstractDataSourceOperator {
- protected final PlanNodeId sourceId;
- protected final OperatorContext operatorContext;
protected final boolean ascending;
protected final boolean isGroupByQuery;
- protected SeriesScanUtil seriesScanUtil;
protected int subSensorSize;
protected TsBlock inputTsBlock;
@@ -101,21 +97,6 @@ public abstract class AbstractSeriesAggregationScanOperator implements DataSourc
this.maxReturnSize = maxReturnSize;
}
- @Override
- public PlanNodeId getSourceId() {
- return sourceId;
- }
-
- @Override
- public OperatorContext getOperatorContext() {
- return operatorContext;
- }
-
- @Override
- public void initQueryDataSource(QueryDataSource dataSource) {
- seriesScanUtil.initQueryDataSource(dataSource);
- }
-
@Override
public long calculateMaxPeekMemory() {
return maxRetainedSize + maxReturnSize;
diff --git a/server/src/main/java/org/apache/iotdb/db/mpp/execution/operator/source/AbstractSourceOperator.java b/server/src/main/java/org/apache/iotdb/db/mpp/execution/operator/source/AbstractSourceOperator.java
new file mode 100644
index 0000000000..8a4bf66d36
--- /dev/null
+++ b/server/src/main/java/org/apache/iotdb/db/mpp/execution/operator/source/AbstractSourceOperator.java
@@ -0,0 +1,33 @@
+/*
+ * 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.mpp.execution.operator.source;
+
+import org.apache.iotdb.db.mpp.execution.operator.AbstractOperator;
+import org.apache.iotdb.db.mpp.plan.planner.plan.node.PlanNodeId;
+
+public abstract class AbstractSourceOperator extends AbstractOperator implements SourceOperator {
+
+ protected PlanNodeId sourceId;
+
+ @Override
+ public PlanNodeId getSourceId() {
+ return sourceId;
+ }
+}
diff --git a/server/src/main/java/org/apache/iotdb/db/mpp/execution/operator/source/AlignedSeriesScanOperator.java b/server/src/main/java/org/apache/iotdb/db/mpp/execution/operator/source/AlignedSeriesScanOperator.java
index 9caaeeac60..388f5340f9 100644
--- a/server/src/main/java/org/apache/iotdb/db/mpp/execution/operator/source/AlignedSeriesScanOperator.java
+++ b/server/src/main/java/org/apache/iotdb/db/mpp/execution/operator/source/AlignedSeriesScanOperator.java
@@ -19,7 +19,6 @@
package org.apache.iotdb.db.mpp.execution.operator.source;
import org.apache.iotdb.commons.path.AlignedPath;
-import org.apache.iotdb.db.engine.querycontext.QueryDataSource;
import org.apache.iotdb.db.mpp.execution.operator.OperatorContext;
import org.apache.iotdb.db.mpp.plan.planner.plan.node.PlanNodeId;
import org.apache.iotdb.tsfile.common.conf.TSFileDescriptor;
@@ -35,17 +34,12 @@ import java.io.IOException;
import java.util.HashSet;
import java.util.concurrent.TimeUnit;
-public class AlignedSeriesScanOperator implements DataSourceOperator {
-
- private final OperatorContext operatorContext;
- private final AlignedSeriesScanUtil seriesScanUtil;
- private final PlanNodeId sourceId;
+public class AlignedSeriesScanOperator extends AbstractDataSourceOperator {
private final TsBlockBuilder builder;
+ private final int valueColumnCount;
private boolean finished = false;
- private final long maxReturnSize;
-
public AlignedSeriesScanOperator(
PlanNodeId sourceId,
AlignedPath seriesPath,
@@ -64,26 +58,30 @@ public class AlignedSeriesScanOperator implements DataSourceOperator {
valueFilter,
ascending);
// time + all value columns
- this.maxReturnSize =
- (1L + seriesPath.getMeasurementList().size())
- * TSFileDescriptor.getInstance().getConfig().getPageSizeInByte();
this.builder = new TsBlockBuilder(seriesScanUtil.getTsDataTypeList());
- }
-
- @Override
- public OperatorContext getOperatorContext() {
- return operatorContext;
+ this.valueColumnCount = seriesPath.getColumnNum();
+ this.maxReturnSize =
+ Math.min(
+ maxReturnSize,
+ (1L + valueColumnCount)
+ * TSFileDescriptor.getInstance().getConfig().getPageSizeInByte());
}
@Override
public TsBlock next() {
- TsBlock block = builder.build();
+ if (retainedTsBlock != null) {
+ return getResultFromRetainedTsBlock();
+ }
+ resultTsBlock = builder.build();
builder.reset();
- return block;
+ return checkTsBlockSizeAndGetResult();
}
@Override
public boolean hasNext() {
+ if (retainedTsBlock != null) {
+ return true;
+ }
try {
// start stopwatch
@@ -131,7 +129,9 @@ public class AlignedSeriesScanOperator implements DataSourceOperator {
@Override
public long calculateMaxPeekMemory() {
- return maxReturnSize;
+ return Math.max(
+ maxReturnSize,
+ (1L + valueColumnCount) * TSFileDescriptor.getInstance().getConfig().getPageSizeInByte());
}
@Override
@@ -141,7 +141,7 @@ public class AlignedSeriesScanOperator implements DataSourceOperator {
@Override
public long calculateRetainedSizeAfterCallingNext() {
- return 0L;
+ return calculateMaxPeekMemory() - calculateMaxReturnSize();
}
private boolean readFileData() throws IOException {
@@ -205,14 +205,4 @@ public class AlignedSeriesScanOperator implements DataSourceOperator {
private boolean isEmpty(TsBlock tsBlock) {
return tsBlock == null || tsBlock.isEmpty();
}
-
- @Override
- public PlanNodeId getSourceId() {
- return sourceId;
- }
-
- @Override
- public void initQueryDataSource(QueryDataSource dataSource) {
- seriesScanUtil.initQueryDataSource(dataSource);
- }
}
diff --git a/server/src/main/java/org/apache/iotdb/db/mpp/execution/operator/source/SeriesScanOperator.java b/server/src/main/java/org/apache/iotdb/db/mpp/execution/operator/source/SeriesScanOperator.java
index fd831fcd6a..681ffb2628 100644
--- a/server/src/main/java/org/apache/iotdb/db/mpp/execution/operator/source/SeriesScanOperator.java
+++ b/server/src/main/java/org/apache/iotdb/db/mpp/execution/operator/source/SeriesScanOperator.java
@@ -19,7 +19,6 @@
package org.apache.iotdb.db.mpp.execution.operator.source;
import org.apache.iotdb.commons.path.PartialPath;
-import org.apache.iotdb.db.engine.querycontext.QueryDataSource;
import org.apache.iotdb.db.mpp.execution.operator.OperatorContext;
import org.apache.iotdb.db.mpp.plan.planner.plan.node.PlanNodeId;
import org.apache.iotdb.tsfile.common.conf.TSFileDescriptor;
@@ -36,17 +35,11 @@ import java.io.IOException;
import java.util.Set;
import java.util.concurrent.TimeUnit;
-public class SeriesScanOperator implements DataSourceOperator {
+public class SeriesScanOperator extends AbstractDataSourceOperator {
- private final OperatorContext operatorContext;
- private final SeriesScanUtil seriesScanUtil;
- private final PlanNodeId sourceId;
private final TsBlockBuilder builder;
-
private boolean finished = false;
- private final long maxReturnSize;
-
public SeriesScanOperator(
PlanNodeId sourceId,
PartialPath seriesPath,
@@ -67,24 +60,26 @@ public class SeriesScanOperator implements DataSourceOperator {
timeFilter,
valueFilter,
ascending);
- this.maxReturnSize = TSFileDescriptor.getInstance().getConfig().getPageSizeInByte();
+ this.maxReturnSize =
+ Math.min(maxReturnSize, TSFileDescriptor.getInstance().getConfig().getPageSizeInByte());
this.builder = new TsBlockBuilder(seriesScanUtil.getTsDataTypeList());
}
- @Override
- public OperatorContext getOperatorContext() {
- return operatorContext;
- }
-
@Override
public TsBlock next() {
- TsBlock block = builder.build();
+ if (retainedTsBlock != null) {
+ return getResultFromRetainedTsBlock();
+ }
+ resultTsBlock = builder.build();
builder.reset();
- return block;
+ return checkTsBlockSizeAndGetResult();
}
@Override
public boolean hasNext() {
+ if (retainedTsBlock != null) {
+ return true;
+ }
try {
// start stopwatch
@@ -132,7 +127,7 @@ public class SeriesScanOperator implements DataSourceOperator {
@Override
public long calculateMaxPeekMemory() {
- return maxReturnSize;
+ return Math.max(maxReturnSize, TSFileDescriptor.getInstance().getConfig().getPageSizeInByte());
}
@Override
@@ -142,7 +137,7 @@ public class SeriesScanOperator implements DataSourceOperator {
@Override
public long calculateRetainedSizeAfterCallingNext() {
- return 0L;
+ return calculateMaxPeekMemory() - calculateMaxReturnSize();
}
private boolean readFileData() throws IOException {
@@ -203,14 +198,4 @@ public class SeriesScanOperator implements DataSourceOperator {
private boolean isEmpty(TsBlock tsBlock) {
return tsBlock == null || tsBlock.isEmpty();
}
-
- @Override
- public PlanNodeId getSourceId() {
- return sourceId;
- }
-
- @Override
- public void initQueryDataSource(QueryDataSource dataSource) {
- seriesScanUtil.initQueryDataSource(dataSource);
- }
}
diff --git a/server/src/test/java/org/apache/iotdb/db/mpp/execution/operator/OperatorMemoryTest.java b/server/src/test/java/org/apache/iotdb/db/mpp/execution/operator/OperatorMemoryTest.java
index c4bd641e2d..7a9e1aa662 100644
--- a/server/src/test/java/org/apache/iotdb/db/mpp/execution/operator/OperatorMemoryTest.java
+++ b/server/src/test/java/org/apache/iotdb/db/mpp/execution/operator/OperatorMemoryTest.java
@@ -195,14 +195,20 @@ public class OperatorMemoryTest {
null,
true);
- assertEquals(
- 4 * TSFileDescriptor.getInstance().getConfig().getPageSizeInByte(),
- seriesScanOperator.calculateMaxPeekMemory());
- assertEquals(
- 4 * TSFileDescriptor.getInstance().getConfig().getPageSizeInByte(),
- seriesScanOperator.calculateMaxReturnSize());
+ long maxPeekMemory =
+ Math.max(
+ TSFileDescriptor.getInstance().getConfig().getMaxTsBlockSizeInBytes(),
+ 4 * TSFileDescriptor.getInstance().getConfig().getPageSizeInByte());
+ long maxReturnMemory =
+ Math.min(
+ TSFileDescriptor.getInstance().getConfig().getMaxTsBlockSizeInBytes(),
+ 4 * TSFileDescriptor.getInstance().getConfig().getPageSizeInByte());
+ assertEquals(maxPeekMemory, seriesScanOperator.calculateMaxPeekMemory());
+ assertEquals(maxReturnMemory, seriesScanOperator.calculateMaxReturnSize());
- assertEquals(0, seriesScanOperator.calculateRetainedSizeAfterCallingNext());
+ assertEquals(
+ maxPeekMemory - maxReturnMemory,
+ seriesScanOperator.calculateRetainedSizeAfterCallingNext());
} catch (IllegalPathException e) {
e.printStackTrace();
@@ -416,7 +422,9 @@ public class OperatorMemoryTest {
dataTypeList.add(TSDataType.INT32);
dataTypeList.add(TSDataType.INT32);
long expectedMaxReturnSize =
- 3L * TSFileDescriptor.getInstance().getConfig().getPageSizeInByte();
+ Math.min(
+ TSFileDescriptor.getInstance().getConfig().getMaxTsBlockSizeInBytes(),
+ 3L * TSFileDescriptor.getInstance().getConfig().getPageSizeInByte());
long expectedMaxPeekMemory = 0;
long childrenMaxPeekMemory = 0;
@@ -469,7 +477,9 @@ public class OperatorMemoryTest {
dataTypeList.add(TSDataType.INT32);
dataTypeList.add(TSDataType.INT32);
long expectedMaxReturnSize =
- 3L * TSFileDescriptor.getInstance().getConfig().getPageSizeInByte();
+ Math.min(
+ TSFileDescriptor.getInstance().getConfig().getMaxTsBlockSizeInBytes(),
+ 3L * TSFileDescriptor.getInstance().getConfig().getPageSizeInByte());
long expectedMaxPeekMemory = 0;
long childrenMaxPeekMemory = 0;
diff --git a/tsfile/src/main/java/org/apache/iotdb/tsfile/read/common/block/TsBlock.java b/tsfile/src/main/java/org/apache/iotdb/tsfile/read/common/block/TsBlock.java
index 3c2f6a58d6..9f37f4b780 100644
--- a/tsfile/src/main/java/org/apache/iotdb/tsfile/read/common/block/TsBlock.java
+++ b/tsfile/src/main/java/org/apache/iotdb/tsfile/read/common/block/TsBlock.java
@@ -479,6 +479,15 @@ public class TsBlock {
return retainedSizeInBytes;
}
+ public int getTotalInstanceSize() {
+ int totalInstanceSize = INSTANCE_SIZE;
+ totalInstanceSize += timeColumn.getInstanceSize();
+ for (Column column : valueColumns) {
+ totalInstanceSize += column.getInstanceSize();
+ }
+ return totalInstanceSize;
+ }
+
private static int determinePositionCount(Column... columns) {
requireNonNull(columns, "columns is null");
if (columns.length == 0) {
diff --git a/tsfile/src/main/java/org/apache/iotdb/tsfile/read/common/block/column/BinaryColumn.java b/tsfile/src/main/java/org/apache/iotdb/tsfile/read/common/block/column/BinaryColumn.java
index aeca614dfe..0aa80cff18 100644
--- a/tsfile/src/main/java/org/apache/iotdb/tsfile/read/common/block/column/BinaryColumn.java
+++ b/tsfile/src/main/java/org/apache/iotdb/tsfile/read/common/block/column/BinaryColumn.java
@@ -162,4 +162,9 @@ public class BinaryColumn implements Column {
}
}
}
+
+ @Override
+ public int getInstanceSize() {
+ return INSTANCE_SIZE;
+ }
}
diff --git a/tsfile/src/main/java/org/apache/iotdb/tsfile/read/common/block/column/BooleanColumn.java b/tsfile/src/main/java/org/apache/iotdb/tsfile/read/common/block/column/BooleanColumn.java
index 9da7b58b04..39995db4e1 100644
--- a/tsfile/src/main/java/org/apache/iotdb/tsfile/read/common/block/column/BooleanColumn.java
+++ b/tsfile/src/main/java/org/apache/iotdb/tsfile/read/common/block/column/BooleanColumn.java
@@ -160,4 +160,9 @@ public class BooleanColumn implements Column {
}
}
}
+
+ @Override
+ public int getInstanceSize() {
+ return INSTANCE_SIZE;
+ }
}
diff --git a/tsfile/src/main/java/org/apache/iotdb/tsfile/read/common/block/column/Column.java b/tsfile/src/main/java/org/apache/iotdb/tsfile/read/common/block/column/Column.java
index fe2af36fca..203ea58b25 100644
--- a/tsfile/src/main/java/org/apache/iotdb/tsfile/read/common/block/column/Column.java
+++ b/tsfile/src/main/java/org/apache/iotdb/tsfile/read/common/block/column/Column.java
@@ -149,4 +149,6 @@ public interface Column {
/** reverse the column */
void reverse();
+
+ int getInstanceSize();
}
diff --git a/tsfile/src/main/java/org/apache/iotdb/tsfile/read/common/block/column/DoubleColumn.java b/tsfile/src/main/java/org/apache/iotdb/tsfile/read/common/block/column/DoubleColumn.java
index 56f0cc7de2..c7966f1653 100644
--- a/tsfile/src/main/java/org/apache/iotdb/tsfile/read/common/block/column/DoubleColumn.java
+++ b/tsfile/src/main/java/org/apache/iotdb/tsfile/read/common/block/column/DoubleColumn.java
@@ -161,4 +161,9 @@ public class DoubleColumn implements Column {
}
}
}
+
+ @Override
+ public int getInstanceSize() {
+ return INSTANCE_SIZE;
+ }
}
diff --git a/tsfile/src/main/java/org/apache/iotdb/tsfile/read/common/block/column/FloatColumn.java b/tsfile/src/main/java/org/apache/iotdb/tsfile/read/common/block/column/FloatColumn.java
index bb3e180ab1..cd96c17812 100644
--- a/tsfile/src/main/java/org/apache/iotdb/tsfile/read/common/block/column/FloatColumn.java
+++ b/tsfile/src/main/java/org/apache/iotdb/tsfile/read/common/block/column/FloatColumn.java
@@ -159,4 +159,9 @@ public class FloatColumn implements Column {
}
}
}
+
+ @Override
+ public int getInstanceSize() {
+ return INSTANCE_SIZE;
+ }
}
diff --git a/tsfile/src/main/java/org/apache/iotdb/tsfile/read/common/block/column/IntColumn.java b/tsfile/src/main/java/org/apache/iotdb/tsfile/read/common/block/column/IntColumn.java
index 38cf078a9f..b0ac59aef5 100644
--- a/tsfile/src/main/java/org/apache/iotdb/tsfile/read/common/block/column/IntColumn.java
+++ b/tsfile/src/main/java/org/apache/iotdb/tsfile/read/common/block/column/IntColumn.java
@@ -159,4 +159,9 @@ public class IntColumn implements Column {
}
}
}
+
+ @Override
+ public int getInstanceSize() {
+ return INSTANCE_SIZE;
+ }
}
diff --git a/tsfile/src/main/java/org/apache/iotdb/tsfile/read/common/block/column/LongColumn.java b/tsfile/src/main/java/org/apache/iotdb/tsfile/read/common/block/column/LongColumn.java
index a67fef0fa1..cf7e64da5d 100644
--- a/tsfile/src/main/java/org/apache/iotdb/tsfile/read/common/block/column/LongColumn.java
+++ b/tsfile/src/main/java/org/apache/iotdb/tsfile/read/common/block/column/LongColumn.java
@@ -159,4 +159,9 @@ public class LongColumn implements Column {
}
}
}
+
+ @Override
+ public int getInstanceSize() {
+ return INSTANCE_SIZE;
+ }
}
diff --git a/tsfile/src/main/java/org/apache/iotdb/tsfile/read/common/block/column/NullColumn.java b/tsfile/src/main/java/org/apache/iotdb/tsfile/read/common/block/column/NullColumn.java
index d9307d44c0..b50bc77a2f 100644
--- a/tsfile/src/main/java/org/apache/iotdb/tsfile/read/common/block/column/NullColumn.java
+++ b/tsfile/src/main/java/org/apache/iotdb/tsfile/read/common/block/column/NullColumn.java
@@ -117,4 +117,9 @@ public class NullColumn implements Column {
throw new IllegalArgumentException("Unknown data type: " + dataType);
}
}
+
+ @Override
+ public int getInstanceSize() {
+ return INSTANCE_SIZE;
+ }
}
diff --git a/tsfile/src/main/java/org/apache/iotdb/tsfile/read/common/block/column/RunLengthEncodedColumn.java b/tsfile/src/main/java/org/apache/iotdb/tsfile/read/common/block/column/RunLengthEncodedColumn.java
index b512b9f252..54174d4776 100644
--- a/tsfile/src/main/java/org/apache/iotdb/tsfile/read/common/block/column/RunLengthEncodedColumn.java
+++ b/tsfile/src/main/java/org/apache/iotdb/tsfile/read/common/block/column/RunLengthEncodedColumn.java
@@ -208,4 +208,9 @@ public class RunLengthEncodedColumn implements Column {
public void reverse() {
// do nothing because the underlying column has only one value
}
+
+ @Override
+ public int getInstanceSize() {
+ return INSTANCE_SIZE;
+ }
}
diff --git a/tsfile/src/main/java/org/apache/iotdb/tsfile/read/common/block/column/TimeColumn.java b/tsfile/src/main/java/org/apache/iotdb/tsfile/read/common/block/column/TimeColumn.java
index 4245bff643..ee6e6d3699 100644
--- a/tsfile/src/main/java/org/apache/iotdb/tsfile/read/common/block/column/TimeColumn.java
+++ b/tsfile/src/main/java/org/apache/iotdb/tsfile/read/common/block/column/TimeColumn.java
@@ -142,4 +142,9 @@ public class TimeColumn implements Column {
public long[] getTimes() {
return values;
}
+
+ @Override
+ public int getInstanceSize() {
+ return INSTANCE_SIZE;
+ }
}