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/07/25 11:53:19 UTC
[iotdb] branch count_time created (now 71c36e9e793)
This is an automated email from the ASF dual-hosted git repository.
jackietien pushed a change to branch count_time
in repository https://gitbox.apache.org/repos/asf/iotdb.git
at 71c36e9e793 Support scan only one time column, not considering mods file
This branch includes the following new commits:
new 71c36e9e793 Support scan only one time column, not considering mods file
The 1 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails. The revisions
listed as "add" were already present in the repository and have only
been added to this reference.
[iotdb] 01/01: Support scan only one time column, not considering mods file
Posted by ja...@apache.org.
This is an automated email from the ASF dual-hosted git repository.
jackietien pushed a commit to branch count_time
in repository https://gitbox.apache.org/repos/asf/iotdb.git
commit 71c36e9e79327a0d7b8000e73129ae4a1c6574ef
Author: JackieTien97 <ja...@gmail.com>
AuthorDate: Tue Jul 25 19:52:52 2023 +0800
Support scan only one time column, not considering mods file
---
.../execution/aggregation/AccumulatorFactory.java | 3 +-
.../execution/aggregation/Aggregator.java | 8 ++-
.../execution/aggregation/CountAccumulator.java | 1 -
...tAccumulator.java => CountTimeAccumulator.java} | 26 ++-----
.../schemaregion/utils/ResourceByPathUtils.java | 30 ++++----
.../dataregion/tsfile/TsFileResource.java | 17 -----
.../org/apache/iotdb/db/utils/FileLoaderUtils.java | 41 ++++++-----
.../execution/aggregation/AccumulatorTest.java | 44 ++++++++++++
.../file/metadata/AlignedTimeSeriesMetadata.java | 34 +++++----
.../read/reader/chunk/AlignedChunkReader.java | 4 +-
.../tsfile/read/reader/page/AlignedPageReader.java | 84 +++++++++++-----------
.../tsfile/write/chunk/AlignedChunkWriterImpl.java | 2 +-
.../thrift-commons/src/main/thrift/common.thrift | 3 +-
13 files changed, 166 insertions(+), 131 deletions(-)
diff --git a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/execution/aggregation/AccumulatorFactory.java b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/execution/aggregation/AccumulatorFactory.java
index 6527bd6af43..9fdf2fbe31b 100644
--- a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/execution/aggregation/AccumulatorFactory.java
+++ b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/execution/aggregation/AccumulatorFactory.java
@@ -31,7 +31,6 @@ import java.util.Map;
public class AccumulatorFactory {
- // TODO: Are we going to create different seriesScanOperator based on order by sequence?
public static Accumulator createAccumulator(
TAggregationType aggregationType,
TSDataType tsDataType,
@@ -71,6 +70,8 @@ public class AccumulatorFactory {
return new TimeDurationAccumulator();
case MODE:
return crateModeAccumulator(tsDataType);
+ case COUNT_TIME:
+ return new CountTimeAccumulator();
default:
throw new IllegalArgumentException("Invalid Aggregation function: " + aggregationType);
}
diff --git a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/execution/aggregation/Aggregator.java b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/execution/aggregation/Aggregator.java
index d34e67cf7e8..2fe61807c14 100644
--- a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/execution/aggregation/Aggregator.java
+++ b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/execution/aggregation/Aggregator.java
@@ -42,7 +42,7 @@ public class Aggregator {
// In some intermediate result input, inputLocation[] should include two columns
protected List<InputLocation[]> inputLocationList;
protected final AggregationStep step;
- protected final QueryExecutionMetricSet QUERY_EXECUTION_METRICS =
+ protected static final QueryExecutionMetricSet QUERY_EXECUTION_METRICS =
QueryExecutionMetricSet.getInstance();
// Used for SeriesAggregateScanOperator
@@ -53,7 +53,7 @@ public class Aggregator {
Collections.singletonList(new InputLocation[] {new InputLocation(0, 0)});
}
- // Used for aggregateOperator
+ // Used for AggregateOperator, AlignedSeriesAggregateScanOperator
public Aggregator(
Accumulator accumulator, AggregationStep step, List<InputLocation[]> inputLocationList) {
this.accumulator = accumulator;
@@ -74,7 +74,9 @@ public class Aggregator {
"RawDataAggregateOperator can only process one tsBlock input.");
Column[] timeAndValueColumn = new Column[2];
timeAndValueColumn[0] = tsBlock.getTimeColumn();
- timeAndValueColumn[1] = tsBlock.getColumn(inputLocations[0].getValueColumnIndex());
+ int index = inputLocations[0].getValueColumnIndex();
+ // for count_time, time column is also its value column
+ timeAndValueColumn[1] = index == -1 ? timeAndValueColumn[0] : tsBlock.getColumn(index);
accumulator.addInput(timeAndValueColumn, bitMap, lastIndex);
}
} finally {
diff --git a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/execution/aggregation/CountAccumulator.java b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/execution/aggregation/CountAccumulator.java
index 1de4da9f198..870b8fbb47b 100644
--- a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/execution/aggregation/CountAccumulator.java
+++ b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/execution/aggregation/CountAccumulator.java
@@ -36,7 +36,6 @@ public class CountAccumulator implements Accumulator {
}
// Column should be like: | Time | Value |
-
@Override
public void addInput(Column[] column, BitMap bitMap, int lastIndex) {
int curPositionCount = column[0].getPositionCount();
diff --git a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/execution/aggregation/CountAccumulator.java b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/execution/aggregation/CountTimeAccumulator.java
similarity index 81%
copy from iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/execution/aggregation/CountAccumulator.java
copy to iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/execution/aggregation/CountTimeAccumulator.java
index 1de4da9f198..e29a3b63ca9 100644
--- a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/execution/aggregation/CountAccumulator.java
+++ b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/execution/aggregation/CountTimeAccumulator.java
@@ -7,7 +7,7 @@
* "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
+ * 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
@@ -27,34 +27,18 @@ import org.apache.iotdb.tsfile.utils.BitMap;
import static com.google.common.base.Preconditions.checkArgument;
-public class CountAccumulator implements Accumulator {
+public class CountTimeAccumulator implements Accumulator {
private long countValue = 0;
- public CountAccumulator() {
+ public CountTimeAccumulator() {
// do nothing
}
- // Column should be like: | Time | Value |
-
+ // Column should be like: | Time | Time |
@Override
public void addInput(Column[] column, BitMap bitMap, int lastIndex) {
- int curPositionCount = column[0].getPositionCount();
-
- if (!column[1].mayHaveNull()
- && lastIndex == curPositionCount - 1
- && ((bitMap == null) || bitMap.isAllMarked())) {
- countValue += curPositionCount;
- } else {
- for (int i = 0; i <= lastIndex; i++) {
- if (bitMap != null && !bitMap.isMarked(i)) {
- continue;
- }
- if (!column[1].isNull(i)) {
- countValue++;
- }
- }
- }
+ countValue += column[0].getPositionCount();
}
// partialResult should be like: | partialCountValue1 |
diff --git a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/schemaengine/schemaregion/utils/ResourceByPathUtils.java b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/schemaengine/schemaregion/utils/ResourceByPathUtils.java
index ff0eed48431..f17c3f90da5 100644
--- a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/schemaengine/schemaregion/utils/ResourceByPathUtils.java
+++ b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/schemaengine/schemaregion/utils/ResourceByPathUtils.java
@@ -56,6 +56,7 @@ import org.apache.iotdb.tsfile.write.writer.RestorableTsFileIOWriter;
import java.io.IOException;
import java.io.Serializable;
import java.util.ArrayList;
+import java.util.Collections;
import java.util.List;
import java.util.Map;
@@ -116,8 +117,7 @@ class AlignedResourceByPathUtils extends ResourceByPathUtils {
*/
@Override
public AlignedTimeSeriesMetadata generateTimeSeriesMetadata(
- List<ReadOnlyMemChunk> readOnlyMemChunk, List<IChunkMetadata> chunkMetadataList)
- throws IOException {
+ List<ReadOnlyMemChunk> readOnlyMemChunk, List<IChunkMetadata> chunkMetadataList) {
TimeseriesMetadata timeTimeSeriesMetadata = new TimeseriesMetadata();
timeTimeSeriesMetadata.setOffsetOfChunkMetaDataList(-1);
timeTimeSeriesMetadata.setDataSizeOfChunkMetaDataList(-1);
@@ -278,17 +278,23 @@ class AlignedResourceByPathUtils extends ResourceByPathUtils {
}
for (int i = 0; i < timeChunkMetadataList.size(); i++) {
- List<IChunkMetadata> valueChunkMetadata = new ArrayList<>();
- // if all the sub sensors doesn't exist, it will be false
- boolean exits = false;
- for (List<ChunkMetadata> chunkMetadata : valueChunkMetadataList) {
- boolean currentExist = i < chunkMetadata.size();
- exits = (exits || currentExist);
- valueChunkMetadata.add(currentExist ? chunkMetadata.get(i) : null);
- }
- if (exits) {
+ // only need time column
+ if (partialPath.getMeasurementList().isEmpty()) {
chunkMetadataList.add(
- new AlignedChunkMetadata(timeChunkMetadataList.get(i), valueChunkMetadata));
+ new AlignedChunkMetadata(timeChunkMetadataList.get(i), Collections.emptyList()));
+ } else {
+ List<IChunkMetadata> valueChunkMetadata = new ArrayList<>();
+ // if all the sub sensors doesn't exist, it will be false
+ boolean exits = false;
+ for (List<ChunkMetadata> chunkMetadata : valueChunkMetadataList) {
+ boolean currentExist = i < chunkMetadata.size();
+ exits = (exits || currentExist);
+ valueChunkMetadata.add(currentExist ? chunkMetadata.get(i) : null);
+ }
+ if (exits) {
+ chunkMetadataList.add(
+ new AlignedChunkMetadata(timeChunkMetadataList.get(i), valueChunkMetadata));
+ }
}
}
diff --git a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/storageengine/dataregion/tsfile/TsFileResource.java b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/storageengine/dataregion/tsfile/TsFileResource.java
index 32c8fa9ab26..ccb6e0e2a06 100644
--- a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/storageengine/dataregion/tsfile/TsFileResource.java
+++ b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/storageengine/dataregion/tsfile/TsFileResource.java
@@ -205,23 +205,6 @@ public class TsFileResource {
this.tierLevel = new AtomicInteger(0);
}
- /** unsealed TsFile, for read */
- public TsFileResource(
- PartialPath path,
- List<ReadOnlyMemChunk> readOnlyMemChunk,
- List<IChunkMetadata> chunkMetadataList,
- TsFileResource originTsFileResource)
- throws IOException {
- this.file = originTsFileResource.file;
- this.timeIndex = originTsFileResource.timeIndex;
- this.pathToReadOnlyMemChunkMap.put(path, readOnlyMemChunk);
- this.pathToChunkMetadataListMap.put(path, chunkMetadataList);
- this.originTsFileResource = originTsFileResource;
- this.version = originTsFileResource.version;
- this.isSeq = originTsFileResource.isSeq;
- this.tierLevel = originTsFileResource.tierLevel;
- }
-
/** unsealed TsFile, for read */
public TsFileResource(
Map<PartialPath, List<ReadOnlyMemChunk>> pathToReadOnlyMemChunkMap,
diff --git a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/utils/FileLoaderUtils.java b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/utils/FileLoaderUtils.java
index 28bb8f82930..083ad26b0cf 100644
--- a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/utils/FileLoaderUtils.java
+++ b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/utils/FileLoaderUtils.java
@@ -47,6 +47,7 @@ import org.apache.iotdb.tsfile.write.writer.TsFileIOWriter;
import java.io.IOException;
import java.util.ArrayList;
+import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
@@ -273,25 +274,33 @@ public class FileLoaderUtils {
resource.getTimeIndexType() != 1,
isDebug);
if (timeColumn != null) {
- List<TimeseriesMetadata> valueTimeSeriesMetadataList =
- new ArrayList<>(valueMeasurementList.size());
- // if all the queried aligned sensors does not exist, we will return null
- boolean exist = false;
- for (String valueMeasurement : valueMeasurementList) {
- TimeseriesMetadata valueColumn =
- cache.get(
- new TimeSeriesMetadataCacheKey(filePath, deviceId, valueMeasurement),
- allSensors,
- resource.getTimeIndexType() != 1,
- isDebug);
- exist = (exist || (valueColumn != null));
- valueTimeSeriesMetadataList.add(valueColumn);
- }
- if (exist) {
+ // only need time column, like count_time aggregation
+ if (valueMeasurementList.isEmpty()) {
alignedTimeSeriesMetadata =
- new AlignedTimeSeriesMetadata(timeColumn, valueTimeSeriesMetadataList);
+ new AlignedTimeSeriesMetadata(timeColumn, Collections.emptyList());
alignedTimeSeriesMetadata.setChunkMetadataLoader(
new DiskAlignedChunkMetadataLoader(resource, alignedPath, context, filter));
+ } else {
+ List<TimeseriesMetadata> valueTimeSeriesMetadataList =
+ new ArrayList<>(valueMeasurementList.size());
+ // if all the queried aligned sensors does not exist, we will return null
+ boolean exist = false;
+ for (String valueMeasurement : valueMeasurementList) {
+ TimeseriesMetadata valueColumn =
+ cache.get(
+ new TimeSeriesMetadataCacheKey(filePath, deviceId, valueMeasurement),
+ allSensors,
+ resource.getTimeIndexType() != 1,
+ isDebug);
+ exist = (exist || (valueColumn != null));
+ valueTimeSeriesMetadataList.add(valueColumn);
+ }
+ if (exist) {
+ alignedTimeSeriesMetadata =
+ new AlignedTimeSeriesMetadata(timeColumn, valueTimeSeriesMetadataList);
+ alignedTimeSeriesMetadata.setChunkMetadataLoader(
+ new DiskAlignedChunkMetadataLoader(resource, alignedPath, context, filter));
+ }
}
}
return alignedTimeSeriesMetadata;
diff --git a/iotdb-core/datanode/src/test/java/org/apache/iotdb/db/queryengine/execution/aggregation/AccumulatorTest.java b/iotdb-core/datanode/src/test/java/org/apache/iotdb/db/queryengine/execution/aggregation/AccumulatorTest.java
index 57915a27f29..c5458553b00 100644
--- a/iotdb-core/datanode/src/test/java/org/apache/iotdb/db/queryengine/execution/aggregation/AccumulatorTest.java
+++ b/iotdb-core/datanode/src/test/java/org/apache/iotdb/db/queryengine/execution/aggregation/AccumulatorTest.java
@@ -22,6 +22,7 @@ package org.apache.iotdb.db.queryengine.execution.aggregation;
import org.apache.iotdb.common.rpc.thrift.TAggregationType;
import org.apache.iotdb.tsfile.file.metadata.enums.TSDataType;
import org.apache.iotdb.tsfile.file.metadata.statistics.Statistics;
+import org.apache.iotdb.tsfile.file.metadata.statistics.TimeStatistics;
import org.apache.iotdb.tsfile.read.common.block.TsBlock;
import org.apache.iotdb.tsfile.read.common.block.TsBlockBuilder;
import org.apache.iotdb.tsfile.read.common.block.column.Column;
@@ -158,6 +159,49 @@ public class AccumulatorTest {
Assert.assertEquals(1, finalResult.build().getLong(0));
}
+ @Test
+ public void countTimeAccumulatorTest() {
+ Accumulator countTimeAccumulator =
+ AccumulatorFactory.createAccumulator(
+ TAggregationType.COUNT_TIME,
+ TSDataType.DOUBLE,
+ Collections.emptyList(),
+ Collections.emptyMap(),
+ true);
+ Assert.assertEquals(TSDataType.INT64, countTimeAccumulator.getIntermediateType()[0]);
+ Assert.assertEquals(TSDataType.INT64, countTimeAccumulator.getFinalType());
+ // check returning null while no data
+ ColumnBuilder[] intermediateResult = new ColumnBuilder[1];
+ intermediateResult[0] = new LongColumnBuilder(null, 1);
+ countTimeAccumulator.outputIntermediate(intermediateResult);
+ Assert.assertEquals(0, intermediateResult[0].build().getLong(0));
+ ColumnBuilder finalResult = new LongColumnBuilder(null, 1);
+ countTimeAccumulator.outputFinal(finalResult);
+ Assert.assertEquals(0, finalResult.build().getLong(0));
+
+ Column[] timeAndValueColumn = getTimeAndValueColumn(0);
+ timeAndValueColumn[1] = timeAndValueColumn[0];
+ countTimeAccumulator.addInput(timeAndValueColumn, null, rawData.getPositionCount() - 1);
+ Assert.assertFalse(countTimeAccumulator.hasFinalResult());
+ intermediateResult[0] = new LongColumnBuilder(null, 1);
+ countTimeAccumulator.outputIntermediate(intermediateResult);
+ Assert.assertEquals(100, intermediateResult[0].build().getLong(0));
+
+ // add intermediate result as input
+ countTimeAccumulator.addIntermediate(new Column[] {intermediateResult[0].build()});
+ finalResult = new LongColumnBuilder(null, 1);
+ countTimeAccumulator.outputFinal(finalResult);
+ Assert.assertEquals(200, finalResult.build().getLong(0));
+
+ countTimeAccumulator.reset();
+ TimeStatistics timeStatistics = new TimeStatistics();
+ timeStatistics.update(100L);
+ countTimeAccumulator.addStatistics(timeStatistics);
+ finalResult = new LongColumnBuilder(null, 1);
+ countTimeAccumulator.outputFinal(finalResult);
+ Assert.assertEquals(1, finalResult.build().getLong(0));
+ }
+
@Test
public void extremeAccumulatorTest() {
Accumulator extremeAccumulator =
diff --git a/iotdb-core/tsfile/src/main/java/org/apache/iotdb/tsfile/file/metadata/AlignedTimeSeriesMetadata.java b/iotdb-core/tsfile/src/main/java/org/apache/iotdb/tsfile/file/metadata/AlignedTimeSeriesMetadata.java
index e1d32300654..79d20588418 100644
--- a/iotdb-core/tsfile/src/main/java/org/apache/iotdb/tsfile/file/metadata/AlignedTimeSeriesMetadata.java
+++ b/iotdb-core/tsfile/src/main/java/org/apache/iotdb/tsfile/file/metadata/AlignedTimeSeriesMetadata.java
@@ -23,6 +23,7 @@ import org.apache.iotdb.tsfile.file.metadata.statistics.Statistics;
import org.apache.iotdb.tsfile.read.controller.IChunkMetadataLoader;
import java.util.ArrayList;
+import java.util.Collections;
import java.util.List;
public class AlignedTimeSeriesMetadata implements ITimeSeriesMetadata {
@@ -135,20 +136,25 @@ public class AlignedTimeSeriesMetadata implements ITimeSeriesMetadata {
List<IChunkMetadata> timeChunkMetadata, List<List<IChunkMetadata>> valueChunkMetadataList) {
List<AlignedChunkMetadata> res = new ArrayList<>();
for (int i = 0; i < timeChunkMetadata.size(); i++) {
- List<IChunkMetadata> chunkMetadataList = new ArrayList<>();
- // only at least one sensor exits, we add the AlignedChunkMetadata to the list
- boolean exits = false;
- for (List<IChunkMetadata> chunkMetadata : valueChunkMetadataList) {
- IChunkMetadata v =
- chunkMetadata == null
- || chunkMetadata.get(i).getStatistics().getCount() == 0 // empty chunk
- ? null
- : chunkMetadata.get(i);
- exits = (exits || v != null);
- chunkMetadataList.add(v);
- }
- if (exits) {
- res.add(new AlignedChunkMetadata(timeChunkMetadata.get(i), chunkMetadataList));
+ // only need time column
+ if (valueTimeseriesMetadataList.isEmpty()) {
+ res.add(new AlignedChunkMetadata(timeChunkMetadata.get(i), Collections.emptyList()));
+ } else {
+ List<IChunkMetadata> chunkMetadataList = new ArrayList<>();
+ // only at least one sensor exits, we add the AlignedChunkMetadata to the list
+ boolean exits = false;
+ for (List<IChunkMetadata> chunkMetadata : valueChunkMetadataList) {
+ IChunkMetadata v =
+ chunkMetadata == null
+ || chunkMetadata.get(i).getStatistics().getCount() == 0 // empty chunk
+ ? null
+ : chunkMetadata.get(i);
+ exits = (exits || v != null);
+ chunkMetadataList.add(v);
+ }
+ if (exits) {
+ res.add(new AlignedChunkMetadata(timeChunkMetadata.get(i), chunkMetadataList));
+ }
}
}
return res;
diff --git a/iotdb-core/tsfile/src/main/java/org/apache/iotdb/tsfile/read/reader/chunk/AlignedChunkReader.java b/iotdb-core/tsfile/src/main/java/org/apache/iotdb/tsfile/read/reader/chunk/AlignedChunkReader.java
index 86bd53f5616..56f669155c2 100644
--- a/iotdb-core/tsfile/src/main/java/org/apache/iotdb/tsfile/read/reader/chunk/AlignedChunkReader.java
+++ b/iotdb-core/tsfile/src/main/java/org/apache/iotdb/tsfile/read/reader/chunk/AlignedChunkReader.java
@@ -145,7 +145,7 @@ public class AlignedChunkReader implements IChunkReader {
PageHeader timePageHeader;
List<PageHeader> valuePageHeaderList = new ArrayList<>();
- boolean exits = false;
+ boolean exits = valueChunkDataBufferList.isEmpty();
// this chunk has only one page
if ((timeChunkHeader.getChunkType() & 0x3F) == MetaMarker.ONLY_ONE_PAGE_CHUNK_HEADER) {
timePageHeader = PageHeader.deserializeFrom(timeChunkDataBuffer, timeChunkStatistics);
@@ -221,7 +221,7 @@ public class AlignedChunkReader implements IChunkReader {
List<ByteBuffer> valuePageDataList = new ArrayList<>();
List<TSDataType> valueDataTypeList = new ArrayList<>();
List<Decoder> valueDecoderList = new ArrayList<>();
- boolean exist = false;
+ boolean exist = valuePageHeader.isEmpty();
for (int i = 0; i < valuePageHeader.size(); i++) {
if (valuePageHeader.get(i) == null
|| valuePageHeader.get(i).getUncompressedSize() == 0) { // Empty Page
diff --git a/iotdb-core/tsfile/src/main/java/org/apache/iotdb/tsfile/read/reader/page/AlignedPageReader.java b/iotdb-core/tsfile/src/main/java/org/apache/iotdb/tsfile/read/reader/page/AlignedPageReader.java
index 8064db9748f..c0f1f0c91c8 100644
--- a/iotdb-core/tsfile/src/main/java/org/apache/iotdb/tsfile/read/reader/page/AlignedPageReader.java
+++ b/iotdb-core/tsfile/src/main/java/org/apache/iotdb/tsfile/read/reader/page/AlignedPageReader.java
@@ -163,40 +163,43 @@ public class AlignedPageReader implements IPageReader, IAlignedPageReader {
}
}
- // using bitMap in valuePageReaders to indicate whether columns of current row are all null.
- byte[] bitmask = new byte[(timeBatch.length - 1) / 8 + 1];
- Arrays.fill(bitmask, (byte) 0x00);
- boolean[][] isDeleted = new boolean[valueCount][timeBatch.length];
- for (int columnIndex = 0; columnIndex < valueCount; columnIndex++) {
- ValuePageReader pageReader = valuePageReaderList.get(columnIndex);
- if (pageReader != null) {
- byte[] bitmap = pageReader.getBitmap();
- pageReader.fillIsDeleted(timeBatch, isDeleted[columnIndex]);
+ boolean[][] isDeleted = null;
+ if (valueCount != 0) {
+ // using bitMap in valuePageReaders to indicate whether columns of current row are all null.
+ byte[] bitmask = new byte[(timeBatch.length - 1) / 8 + 1];
+ Arrays.fill(bitmask, (byte) 0x00);
+ isDeleted = new boolean[valueCount][timeBatch.length];
+ for (int columnIndex = 0; columnIndex < valueCount; columnIndex++) {
+ ValuePageReader pageReader = valuePageReaderList.get(columnIndex);
+ if (pageReader != null) {
+ byte[] bitmap = pageReader.getBitmap();
+ pageReader.fillIsDeleted(timeBatch, isDeleted[columnIndex]);
- for (int i = 0, n = isDeleted[columnIndex].length; i < n; i++) {
- if (isDeleted[columnIndex][i]) {
- int shift = i % 8;
- bitmap[i / 8] = (byte) (bitmap[i / 8] & (~(MASK >>> shift)));
+ for (int i = 0, n = isDeleted[columnIndex].length; i < n; i++) {
+ if (isDeleted[columnIndex][i]) {
+ int shift = i % 8;
+ bitmap[i / 8] = (byte) (bitmap[i / 8] & (~(MASK >>> shift)));
+ }
+ }
+ for (int i = 0, n = bitmask.length; i < n; i++) {
+ bitmask[i] = (byte) (bitmap[i] | bitmask[i]);
}
- }
- for (int i = 0, n = bitmask.length; i < n; i++) {
- bitmask[i] = (byte) (bitmap[i] | bitmask[i]);
}
}
- }
- for (int i = 0, n = bitmask.length; i < n; i++) {
- if (bitmask[i] == (byte) 0xFF) {
- // 8 rows are not all null, do nothing
- } else if (bitmask[i] == (byte) 0x00) {
- for (int j = 0; j < 8 && (i * 8 + j < keepCurrentRow.length); j++) {
- keepCurrentRow[i * 8 + j] = false;
- }
- } else {
- for (int j = 0; j < 8 && (i * 8 + j < keepCurrentRow.length); j++) {
- if (((bitmask[i] & 0xFF) & (MASK >>> j)) == 0) {
+ for (int i = 0, n = bitmask.length; i < n; i++) {
+ if (bitmask[i] == (byte) 0xFF) {
+ // 8 rows are not all null, do nothing
+ } else if (bitmask[i] == (byte) 0x00) {
+ for (int j = 0; j < 8 && (i * 8 + j < keepCurrentRow.length); j++) {
keepCurrentRow[i * 8 + j] = false;
}
+ } else {
+ for (int j = 0; j < 8 && (i * 8 + j < keepCurrentRow.length); j++) {
+ if (((bitmask[i] & 0xFF) & (MASK >>> j)) == 0) {
+ keepCurrentRow[i * 8 + j] = false;
+ }
+ }
}
}
}
@@ -204,21 +207,18 @@ public class AlignedPageReader implements IPageReader, IAlignedPageReader {
// construct time column
int readEndIndex = timeBatch.length;
for (int i = 0; i < timeBatch.length; i++) {
- if (!keepCurrentRow[i]) {
- continue;
- }
- if (paginationController.hasCurOffset()) {
- paginationController.consumeOffset();
- keepCurrentRow[i] = false;
- continue;
- }
- if (paginationController.hasCurLimit()) {
- builder.getTimeColumnBuilder().writeLong(timeBatch[i]);
- builder.declarePosition();
- paginationController.consumeLimit();
- } else {
- readEndIndex = i;
- break;
+ if (keepCurrentRow[i]) {
+ if (paginationController.hasCurOffset()) {
+ paginationController.consumeOffset();
+ keepCurrentRow[i] = false;
+ } else if (paginationController.hasCurLimit()) {
+ builder.getTimeColumnBuilder().writeLong(timeBatch[i]);
+ builder.declarePosition();
+ paginationController.consumeLimit();
+ } else {
+ readEndIndex = i;
+ break;
+ }
}
}
diff --git a/iotdb-core/tsfile/src/main/java/org/apache/iotdb/tsfile/write/chunk/AlignedChunkWriterImpl.java b/iotdb-core/tsfile/src/main/java/org/apache/iotdb/tsfile/write/chunk/AlignedChunkWriterImpl.java
index fbf124eba5a..c4fba7b1472 100644
--- a/iotdb-core/tsfile/src/main/java/org/apache/iotdb/tsfile/write/chunk/AlignedChunkWriterImpl.java
+++ b/iotdb-core/tsfile/src/main/java/org/apache/iotdb/tsfile/write/chunk/AlignedChunkWriterImpl.java
@@ -49,7 +49,7 @@ public class AlignedChunkWriterImpl implements IChunkWriter {
// Used for batch writing
private long remainingPointsNumber;
- /** @param schema schema of this measurement */
+ // TestOnly
public AlignedChunkWriterImpl(VectorMeasurementSchema schema) {
timeChunkWriter =
new TimeChunkWriter(
diff --git a/iotdb-protocol/thrift-commons/src/main/thrift/common.thrift b/iotdb-protocol/thrift-commons/src/main/thrift/common.thrift
index 2c07f7493c0..d602c505319 100644
--- a/iotdb-protocol/thrift-commons/src/main/thrift/common.thrift
+++ b/iotdb-protocol/thrift-commons/src/main/thrift/common.thrift
@@ -178,7 +178,8 @@ enum TAggregationType {
EXTREME,
COUNT_IF,
TIME_DURATION,
- MODE
+ MODE,
+ COUNT_TIME
}
// for MLNode