This is an automated email from the ASF dual-hosted git repository.
justinchen 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 629860ade15 fix: Updated TSFile version to fix Load failure in
creating aligned time series (#16502)
629860ade15 is described below
commit 629860ade15ed223ecc543e341b17b480acf7960
Author: Zhenyu Luo <[email protected]>
AuthorDate: Mon Oct 13 15:30:13 2025 +0800
fix: Updated TSFile version to fix Load failure in creating aligned time
series (#16502)
* Updated TSFile version to fix Load failure in creating aligned time series
* add UT
* update
---
.../load/TimeseriesMetadataIteratorTest.java | 173 +++++++++++++++++++++
1 file changed, 173 insertions(+)
diff --git
a/iotdb-core/datanode/src/test/java/org/apache/iotdb/db/queryengine/plan/analyze/load/TimeseriesMetadataIteratorTest.java
b/iotdb-core/datanode/src/test/java/org/apache/iotdb/db/queryengine/plan/analyze/load/TimeseriesMetadataIteratorTest.java
new file mode 100644
index 00000000000..b368f187328
--- /dev/null
+++
b/iotdb-core/datanode/src/test/java/org/apache/iotdb/db/queryengine/plan/analyze/load/TimeseriesMetadataIteratorTest.java
@@ -0,0 +1,173 @@
+/*
+ * 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.plan.analyze.load;
+
+import org.apache.tsfile.enums.TSDataType;
+import org.apache.tsfile.file.metadata.IDeviceID;
+import org.apache.tsfile.file.metadata.TimeseriesMetadata;
+import org.apache.tsfile.read.TsFileSequenceReader;
+import org.apache.tsfile.read.TsFileSequenceReaderTimeseriesMetadataIterator;
+import org.apache.tsfile.write.TsFileWriter;
+import org.apache.tsfile.write.record.Tablet;
+import org.apache.tsfile.write.schema.IMeasurementSchema;
+import org.apache.tsfile.write.schema.MeasurementSchema;
+import org.junit.Assert;
+import org.junit.Test;
+
+import java.io.File;
+import java.nio.charset.StandardCharsets;
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+public class TimeseriesMetadataIteratorTest {
+
+ private static final int DEVICE_COUNT = 1000;
+
+ private static final int COLUMN_COUNT = 3;
+
+ private static final long FIXED_TIMESTAMP = 1L;
+
+ @Test
+ public void testTimeseriesMetadataIterator() throws Exception {
+ String outputPath = "testTsFile.tsfile";
+ File file = createTsFile(outputPath);
+
+ IDeviceID iDeviceID = null;
+ Set<IDeviceID> set = new HashSet<>();
+ try (TsFileSequenceReader reader = new
TsFileSequenceReader(file.getAbsolutePath())) {
+ TsFileSequenceReaderTimeseriesMetadataIterator iterator =
+ new TsFileSequenceReaderTimeseriesMetadataIterator(reader, true, 2);
+ while (iterator.hasNext()) {
+ Map<IDeviceID, List<TimeseriesMetadata>> map = iterator.next();
+ for (Map.Entry<IDeviceID, List<TimeseriesMetadata>> entry :
map.entrySet()) {
+ if (iDeviceID != null) {
+ if (!iDeviceID.equals(entry.getKey())) {
+ if (set.contains(iDeviceID)) {
+ Assert.fail("time series metadata iterator needs to be ordered
by device id");
+ }
+ set.add(iDeviceID);
+ }
+ }
+ iDeviceID = entry.getKey();
+ }
+ }
+ } finally {
+ if (file.exists()) {
+ file.delete();
+ }
+ }
+ }
+
+ public static File createTsFile(String outputPath) throws Exception {
+ File file = new File(outputPath);
+ if (file.exists()) {
+ file.delete();
+ }
+
+ try (TsFileWriter tsFileWriter = new TsFileWriter(file)) {
+ createSchema(tsFileWriter);
+ for (int deviceIndex = 0; deviceIndex < DEVICE_COUNT; deviceIndex++) {
+ String deviceId = "root.d." + "device" + deviceIndex;
+ Tablet tablet = createTablet(deviceId);
+
+ tsFileWriter.writeAligned(tablet);
+ tsFileWriter.flush();
+ }
+ }
+
+ return file;
+ }
+
+ private static void createSchema(TsFileWriter tsFileWriter) throws Exception
{
+ List<IMeasurementSchema> schemaList = new ArrayList<>();
+ for (int colIndex = 0; colIndex < COLUMN_COUNT; colIndex++) {
+ String measurementName = "s" + colIndex;
+ TSDataType dataType = getDataType(colIndex);
+ schemaList.add(new MeasurementSchema(measurementName, dataType));
+ }
+ for (int deviceIndex = 0; deviceIndex < DEVICE_COUNT; deviceIndex++) {
+ tsFileWriter.registerAlignedTimeseries("root.d." + "device" +
deviceIndex, schemaList);
+ }
+ }
+
+ private static TSDataType getDataType(int colIndex) {
+ TSDataType[] types = {
+ TSDataType.INT32,
+ TSDataType.INT64,
+ TSDataType.FLOAT,
+ TSDataType.DOUBLE,
+ TSDataType.BOOLEAN,
+ TSDataType.TEXT
+ };
+ return types[colIndex % types.length];
+ }
+
+ private static Tablet createTablet(String deviceId) {
+ List<IMeasurementSchema> schemaList = new ArrayList<>();
+
+ for (int colIndex = 0; colIndex < COLUMN_COUNT; colIndex++) {
+ String measurementName = "s" + colIndex;
+ TSDataType dataType = getDataType(colIndex);
+
+ schemaList.add(new MeasurementSchema(measurementName, dataType));
+ }
+
+ Tablet tablet = new Tablet(deviceId, schemaList, 1);
+
+ tablet.initBitMaps();
+
+ tablet.addTimestamp(0, FIXED_TIMESTAMP);
+
+ for (int colIndex = 0; colIndex < COLUMN_COUNT; colIndex++) {
+ String measurementName = "s" + colIndex;
+ TSDataType dataType = getDataType(colIndex);
+
+ Object value = generateValue(dataType, colIndex);
+ tablet.addValue(measurementName, 0, value);
+ }
+
+ tablet.setRowSize(1);
+
+ return tablet;
+ }
+
+ private static Object generateValue(TSDataType dataType, int colIndex) {
+ switch (dataType) {
+ case INT32:
+ return colIndex % 1000;
+ case INT64:
+ return (long) (colIndex * 1000);
+ case FLOAT:
+ return (float) (colIndex * 0.1);
+ case DOUBLE:
+ return (double) (colIndex * 0.01);
+ case BOOLEAN:
+ return colIndex % 2 == 0;
+ case TEXT:
+ return new org.apache.tsfile.utils.Binary(
+ ("value_" + colIndex).getBytes(StandardCharsets.UTF_8));
+ default:
+ return colIndex;
+ }
+ }
+}