You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@iotdb.apache.org by qi...@apache.org on 2020/04/15 09:35:56 UTC

[incubator-iotdb] branch master updated: [IOTDB-594] Correct the use of Unseq file's TimeseriesMetadata (#1050)

This is an automated email from the ASF dual-hosted git repository.

qiaojialin pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/incubator-iotdb.git


The following commit(s) were added to refs/heads/master by this push:
     new 66be65a  [IOTDB-594] Correct the use of Unseq file's TimeseriesMetadata (#1050)
66be65a is described below

commit 66be65a2cda665c33983175b21f8eeefb451fe46
Author: Jackie Tien <Ja...@foxmail.com>
AuthorDate: Wed Apr 15 17:35:48 2020 +0800

    [IOTDB-594] Correct the use of Unseq file's TimeseriesMetadata (#1050)
    
    * correct the update way of TimeseriesMetadata Statistics for unseq file
---
 .../iotdb/db/query/reader/series/SeriesReader.java |   2 +
 .../IoTDBMultiOverlappedChunkInUnseqIT.java        | 109 +++++++++++++++++++++
 .../file/metadata/statistics/BinaryStatistics.java |  24 +++--
 .../metadata/statistics/BooleanStatistics.java     |  24 +++--
 .../file/metadata/statistics/DoubleStatistics.java |  30 +++++-
 .../file/metadata/statistics/FloatStatistics.java  |  31 ++++--
 .../metadata/statistics/IntegerStatistics.java     |  31 ++++--
 .../file/metadata/statistics/LongStatistics.java   |  31 ++++--
 .../file/metadata/statistics/Statistics.java       |   1 +
 .../metadata/statistics/BooleanStatisticsTest.java |  29 +++++-
 .../metadata/statistics/DoubleStatisticsTest.java  |  32 +++++-
 .../metadata/statistics/FloatStatisticsTest.java   |  38 +++++--
 .../metadata/statistics/IntegerStatisticsTest.java |  32 +++++-
 .../metadata/statistics/LongStatisticsTest.java    |  36 +++++--
 .../metadata/statistics/StringStatisticsTest.java  |  36 +++++--
 15 files changed, 412 insertions(+), 74 deletions(-)

diff --git a/server/src/main/java/org/apache/iotdb/db/query/reader/series/SeriesReader.java b/server/src/main/java/org/apache/iotdb/db/query/reader/series/SeriesReader.java
index bd4469b..cedd326 100644
--- a/server/src/main/java/org/apache/iotdb/db/query/reader/series/SeriesReader.java
+++ b/server/src/main/java/org/apache/iotdb/db/query/reader/series/SeriesReader.java
@@ -584,6 +584,7 @@ class SeriesReader {
           .loadTimeSeriesMetadata(unseqFileResource.remove(0), seriesPath, context, getAnyFilter(),
               allSensors);
       if (timeseriesMetadata != null) {
+        timeseriesMetadata.getStatistics().setCanUseStatistics(false);
         unSeqTimeSeriesMetadata.add(timeseriesMetadata);
       }
     }
@@ -639,6 +640,7 @@ class SeriesReader {
     while (!unseqFileResource.isEmpty() && endTime >= unseqFileResource.get(0).getStartTimeMap().get(seriesPath.getDevice())) {
       TimeseriesMetadata timeseriesMetadata = FileLoaderUtils.loadTimeSeriesMetadata(unseqFileResource.remove(0), seriesPath, context, getAnyFilter(), allSensors);
       if (timeseriesMetadata != null) {
+        timeseriesMetadata.getStatistics().setCanUseStatistics(false);
         unSeqTimeSeriesMetadata.add(timeseriesMetadata);
       }
     }
diff --git a/server/src/test/java/org/apache/iotdb/db/integration/IoTDBMultiOverlappedChunkInUnseqIT.java b/server/src/test/java/org/apache/iotdb/db/integration/IoTDBMultiOverlappedChunkInUnseqIT.java
new file mode 100644
index 0000000..294481d
--- /dev/null
+++ b/server/src/test/java/org/apache/iotdb/db/integration/IoTDBMultiOverlappedChunkInUnseqIT.java
@@ -0,0 +1,109 @@
+/*
+ * 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.integration;
+
+import org.apache.iotdb.db.conf.IoTDBDescriptor;
+import org.apache.iotdb.db.utils.EnvironmentUtils;
+import org.apache.iotdb.jdbc.Config;
+import org.junit.AfterClass;
+import org.junit.BeforeClass;
+import org.junit.Test;
+
+import java.sql.Connection;
+import java.sql.DriverManager;
+import java.sql.ResultSet;
+import java.sql.Statement;
+
+import static org.apache.iotdb.db.constant.TestConstant.count;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.fail;
+
+/**
+ * Notice that, all test begins with "IoTDB" is integration test. All test which will start the
+ * IoTDB server should be defined as integration test.
+ */
+public class IoTDBMultiOverlappedChunkInUnseqIT {
+
+  private static long beforeMemtableSizeThreshold;
+
+  @BeforeClass
+  public static void setUp() throws Exception {
+    EnvironmentUtils.closeStatMonitor();
+    beforeMemtableSizeThreshold = IoTDBDescriptor.getInstance().getConfig().getMemtableSizeThreshold();
+    IoTDBDescriptor.getInstance().getConfig().setMemtableSizeThreshold(1024);
+    EnvironmentUtils.envSetUp();
+    Class.forName(Config.JDBC_DRIVER_NAME);
+    insertData();
+  }
+
+  @AfterClass
+  public static void tearDown() throws Exception {
+    // recovery value
+    EnvironmentUtils.cleanEnv();
+    IoTDBDescriptor.getInstance().getConfig().setMemtableSizeThreshold(beforeMemtableSizeThreshold);
+  }
+
+  @Test
+  public void selectOverlappedPageTest() {
+
+    try (Connection connection = DriverManager
+            .getConnection(Config.IOTDB_URL_PREFIX + "127.0.0.1:6667/", "root", "root");
+         Statement statement = connection.createStatement()) {
+      String sql = "select count(s0) from root.vehicle.d0 where time < 1000000";
+      ResultSet resultSet = statement.executeQuery(sql);
+      while (resultSet.next()) {
+        String ans = resultSet.getString(count("root.vehicle.d0.s0"));
+        assertEquals("1000", ans);
+      }
+    } catch (Exception e) {
+      e.printStackTrace();
+      fail(e.getMessage());
+    }
+  }
+
+  private static void insertData() {
+    try (Connection connection = DriverManager
+            .getConnection(Config.IOTDB_URL_PREFIX + "127.0.0.1:6667/", "root", "root");
+         Statement statement = connection.createStatement()) {
+
+      statement.execute("CREATE TIMESERIES root.vehicle.d0.s0 WITH DATATYPE=INT32, ENCODING=RLE");
+
+      String sql = String
+              .format("insert into root.vehicle.d0(timestamp,s0) values(%s,%s)", 1000000, 1000000);
+      statement.execute(sql);
+
+      statement.execute("flush");
+      for (long time = 1; time <= 1000; time++) {
+        sql = String
+                .format("insert into root.vehicle.d0(timestamp,s0) values(%s,%s)", time, time);
+        statement.execute(sql);
+      }
+      for (long time = 2; time <= 1000; time++) {
+        sql = String
+                .format("insert into root.vehicle.d0(timestamp,s0) values(%s,%s)", time, 1000);
+        statement.execute(sql);
+      }
+      statement.execute("flush");
+    } catch (Exception e) {
+      e.printStackTrace();
+      fail(e.getMessage());
+    }
+  }
+}
\ No newline at end of file
diff --git a/tsfile/src/main/java/org/apache/iotdb/tsfile/file/metadata/statistics/BinaryStatistics.java b/tsfile/src/main/java/org/apache/iotdb/tsfile/file/metadata/statistics/BinaryStatistics.java
index 09e5883..40173b5 100644
--- a/tsfile/src/main/java/org/apache/iotdb/tsfile/file/metadata/statistics/BinaryStatistics.java
+++ b/tsfile/src/main/java/org/apache/iotdb/tsfile/file/metadata/statistics/BinaryStatistics.java
@@ -18,16 +18,16 @@
  */
 package org.apache.iotdb.tsfile.file.metadata.statistics;
 
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStream;
-import java.nio.ByteBuffer;
-
 import org.apache.iotdb.tsfile.exception.filter.StatisticsClassException;
 import org.apache.iotdb.tsfile.file.metadata.enums.TSDataType;
 import org.apache.iotdb.tsfile.utils.Binary;
 import org.apache.iotdb.tsfile.utils.ReadWriteIOUtils;
 
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.nio.ByteBuffer;
+
 /**
  * Statistics for string type.
  */
@@ -61,6 +61,18 @@ public class BinaryStatistics extends Statistics<Binary> {
     this.lastValue = lastValue;
   }
 
+  private void updateStats(Binary firstValue, Binary lastValue, long startTime, long endTime) {
+    // only if endTime greater or equals to the current endTime need we update the last value
+    // only if startTime less or equals to the current startTime need we update the first value
+    // otherwise, just ignore
+    if (startTime <= this.getStartTime()) {
+      this.firstValue = firstValue;
+    }
+    if (endTime >= this.getEndTime()) {
+      this.lastValue = lastValue;
+    }
+  }
+
   @Override
   public void setMinMaxFromBytes(byte[] minBytes, byte[] maxBytes) {
   }
@@ -97,7 +109,7 @@ public class BinaryStatistics extends Statistics<Binary> {
       initializeStats(stringStats.getFirstValue(), stringStats.getLastValue());
       isEmpty = false;
     } else {
-      updateStats(stringStats.getFirstValue(), stringStats.getLastValue());
+      updateStats(stringStats.getFirstValue(), stringStats.getLastValue(), stats.getStartTime(), stats.getEndTime());
     }
   }
 
diff --git a/tsfile/src/main/java/org/apache/iotdb/tsfile/file/metadata/statistics/BooleanStatistics.java b/tsfile/src/main/java/org/apache/iotdb/tsfile/file/metadata/statistics/BooleanStatistics.java
index abab02d..d298055 100644
--- a/tsfile/src/main/java/org/apache/iotdb/tsfile/file/metadata/statistics/BooleanStatistics.java
+++ b/tsfile/src/main/java/org/apache/iotdb/tsfile/file/metadata/statistics/BooleanStatistics.java
@@ -18,16 +18,16 @@
  */
 package org.apache.iotdb.tsfile.file.metadata.statistics;
 
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStream;
-import java.nio.ByteBuffer;
-
 import org.apache.iotdb.tsfile.exception.filter.StatisticsClassException;
 import org.apache.iotdb.tsfile.file.metadata.enums.TSDataType;
 import org.apache.iotdb.tsfile.utils.BytesUtils;
 import org.apache.iotdb.tsfile.utils.ReadWriteIOUtils;
 
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.nio.ByteBuffer;
+
 public class BooleanStatistics extends Statistics<Boolean> {
 
   private boolean firstValue;
@@ -58,6 +58,18 @@ public class BooleanStatistics extends Statistics<Boolean> {
     this.lastValue = lastValue;
   }
 
+  private void updateStats(boolean firstValue, boolean lastValue, long startTime, long endTime) {
+    // only if endTime greater or equals to the current endTime need we update the last value
+    // only if startTime less or equals to the current startTime need we update the first value
+    // otherwise, just ignore
+    if (startTime <= this.getStartTime()) {
+      this.firstValue = firstValue;
+    }
+    if (endTime >= this.getEndTime()) {
+      this.lastValue = lastValue;
+    }
+  }
+
   @Override
   void updateStats(boolean value) {
     if (isEmpty) {
@@ -136,7 +148,7 @@ public class BooleanStatistics extends Statistics<Boolean> {
       initializeStats(boolStats.getFirstValue(), boolStats.getLastValue());
       isEmpty = false;
     } else {
-      updateStats(boolStats.getFirstValue(), boolStats.getLastValue());
+      updateStats(boolStats.getFirstValue(), boolStats.getLastValue(), stats.getStartTime(), stats.getEndTime());
     }
   }
 
diff --git a/tsfile/src/main/java/org/apache/iotdb/tsfile/file/metadata/statistics/DoubleStatistics.java b/tsfile/src/main/java/org/apache/iotdb/tsfile/file/metadata/statistics/DoubleStatistics.java
index c3f29ca..6b87fc8 100644
--- a/tsfile/src/main/java/org/apache/iotdb/tsfile/file/metadata/statistics/DoubleStatistics.java
+++ b/tsfile/src/main/java/org/apache/iotdb/tsfile/file/metadata/statistics/DoubleStatistics.java
@@ -18,13 +18,14 @@
  */
 package org.apache.iotdb.tsfile.file.metadata.statistics;
 
+import org.apache.iotdb.tsfile.file.metadata.enums.TSDataType;
+import org.apache.iotdb.tsfile.utils.BytesUtils;
+import org.apache.iotdb.tsfile.utils.ReadWriteIOUtils;
+
 import java.io.IOException;
 import java.io.InputStream;
 import java.io.OutputStream;
 import java.nio.ByteBuffer;
-import org.apache.iotdb.tsfile.file.metadata.enums.TSDataType;
-import org.apache.iotdb.tsfile.utils.BytesUtils;
-import org.apache.iotdb.tsfile.utils.ReadWriteIOUtils;
 
 public class DoubleStatistics extends Statistics<Double> {
 
@@ -72,6 +73,25 @@ public class DoubleStatistics extends Statistics<Double> {
     this.lastValue = lastValue;
   }
 
+  private void updateStats(double minValue, double maxValue, double firstValue, double lastValue, double sumValue, long startTime, long endTime) {
+    if (minValue < this.minValue) {
+      this.minValue = minValue;
+    }
+    if (maxValue > this.maxValue) {
+      this.maxValue = maxValue;
+    }
+    this.sumValue += sumValue;
+    // only if endTime greater or equals to the current endTime need we update the last value
+    // only if startTime less or equals to the current startTime need we update the first value
+    // otherwise, just ignore
+    if (startTime <= this.getStartTime()) {
+      this.firstValue = firstValue;
+    }
+    if (endTime >= this.getEndTime()) {
+      this.lastValue = lastValue;
+    }
+  }
+
   @Override
   public void setMinMaxFromBytes(byte[] minBytes, byte[] maxBytes) {
     minValue = BytesUtils.bytesToDouble(minBytes);
@@ -128,8 +148,8 @@ public class DoubleStatistics extends Statistics<Double> {
           doubleStats.getLastValue(), doubleStats.getSumValue());
       isEmpty = false;
     } else {
-      updateStats(doubleStats.getMinValue(), doubleStats.getMaxValue(),
-          doubleStats.getLastValue(), doubleStats.getSumValue());
+      updateStats(doubleStats.getMinValue(), doubleStats.getMaxValue(), doubleStats.getFirstValue(),
+          doubleStats.getLastValue(), doubleStats.getSumValue(), stats.getStartTime(), stats.getEndTime());
     }
   }
 
diff --git a/tsfile/src/main/java/org/apache/iotdb/tsfile/file/metadata/statistics/FloatStatistics.java b/tsfile/src/main/java/org/apache/iotdb/tsfile/file/metadata/statistics/FloatStatistics.java
index f33559e..16ce7be 100644
--- a/tsfile/src/main/java/org/apache/iotdb/tsfile/file/metadata/statistics/FloatStatistics.java
+++ b/tsfile/src/main/java/org/apache/iotdb/tsfile/file/metadata/statistics/FloatStatistics.java
@@ -18,15 +18,15 @@
  */
 package org.apache.iotdb.tsfile.file.metadata.statistics;
 
+import org.apache.iotdb.tsfile.file.metadata.enums.TSDataType;
+import org.apache.iotdb.tsfile.utils.BytesUtils;
+import org.apache.iotdb.tsfile.utils.ReadWriteIOUtils;
+
 import java.io.IOException;
 import java.io.InputStream;
 import java.io.OutputStream;
 import java.nio.ByteBuffer;
 
-import org.apache.iotdb.tsfile.file.metadata.enums.TSDataType;
-import org.apache.iotdb.tsfile.utils.BytesUtils;
-import org.apache.iotdb.tsfile.utils.ReadWriteIOUtils;
-
 /**
  * Statistics for float type.
  */
@@ -67,6 +67,25 @@ public class FloatStatistics extends Statistics<Float> {
     this.lastValue = last;
   }
 
+  private void updateStats(float minValue, float maxValue, float first, float last, double sumValue, long startTime, long endTime) {
+    if (minValue < this.minValue) {
+      this.minValue = minValue;
+    }
+    if (maxValue > this.maxValue) {
+      this.maxValue = maxValue;
+    }
+    this.sumValue += sumValue;
+    // only if endTime greater or equals to the current endTime need we update the last value
+    // only if startTime less or equals to the current startTime need we update the first value
+    // otherwise, just ignore
+    if (startTime <= this.getStartTime()) {
+      this.firstValue = first;
+    }
+    if (endTime >= this.getEndTime()) {
+      this.lastValue = last;
+    }
+  }
+
   @Override
   public void setMinMaxFromBytes(byte[] minBytes, byte[] maxBytes) {
     minValue = BytesUtils.bytesToFloat(minBytes);
@@ -123,8 +142,8 @@ public class FloatStatistics extends Statistics<Float> {
           floatStats.getLastValue(), floatStats.getSumValue());
       isEmpty = false;
     } else {
-      updateStats(floatStats.getMinValue(), floatStats.getMaxValue(),
-          floatStats.getLastValue(), floatStats.getSumValue());
+      updateStats(floatStats.getMinValue(), floatStats.getMaxValue(), floatStats.getFirstValue(),
+          floatStats.getLastValue(), floatStats.getSumValue(), stats.getStartTime(), stats.getEndTime());
     }
   }
 
diff --git a/tsfile/src/main/java/org/apache/iotdb/tsfile/file/metadata/statistics/IntegerStatistics.java b/tsfile/src/main/java/org/apache/iotdb/tsfile/file/metadata/statistics/IntegerStatistics.java
index c07a7bb..e2c945d 100644
--- a/tsfile/src/main/java/org/apache/iotdb/tsfile/file/metadata/statistics/IntegerStatistics.java
+++ b/tsfile/src/main/java/org/apache/iotdb/tsfile/file/metadata/statistics/IntegerStatistics.java
@@ -18,15 +18,15 @@
  */
 package org.apache.iotdb.tsfile.file.metadata.statistics;
 
+import org.apache.iotdb.tsfile.file.metadata.enums.TSDataType;
+import org.apache.iotdb.tsfile.utils.BytesUtils;
+import org.apache.iotdb.tsfile.utils.ReadWriteIOUtils;
+
 import java.io.IOException;
 import java.io.InputStream;
 import java.io.OutputStream;
 import java.nio.ByteBuffer;
 
-import org.apache.iotdb.tsfile.file.metadata.enums.TSDataType;
-import org.apache.iotdb.tsfile.utils.BytesUtils;
-import org.apache.iotdb.tsfile.utils.ReadWriteIOUtils;
-
 /**
  * Statistics for int type.
  */
@@ -67,6 +67,25 @@ public class IntegerStatistics extends Statistics<Integer> {
     this.lastValue = lastValue;
   }
 
+  private void updateStats(int minValue, int maxValue, int firstValue, int lastValue, double sumValue, long startTime, long endTime) {
+    if (minValue < this.minValue) {
+      this.minValue = minValue;
+    }
+    if (maxValue > this.maxValue) {
+      this.maxValue = maxValue;
+    }
+    this.sumValue += sumValue;
+    // only if endTime greater or equals to the current endTime need we update the last value
+    // only if startTime less or equals to the current startTime need we update the first value
+    // otherwise, just ignore
+    if (startTime <= this.getStartTime()) {
+      this.firstValue = firstValue;
+    }
+    if (endTime >= this.getEndTime()) {
+      this.lastValue = lastValue;
+    }
+  }
+
   @Override
   public void setMinMaxFromBytes(byte[] minBytes, byte[] maxBytes) {
     minValue = BytesUtils.bytesToInt(minBytes);
@@ -124,8 +143,8 @@ public class IntegerStatistics extends Statistics<Integer> {
           intStats.getSumValue());
       isEmpty = false;
     } else {
-      updateStats(intStats.getMinValue(), intStats.getMaxValue(), intStats.getLastValue(),
-          intStats.getSumValue());
+      updateStats(intStats.getMinValue(), intStats.getMaxValue(), intStats.getFirstValue(), intStats.getLastValue(),
+          intStats.getSumValue(), stats.getStartTime(), stats.getEndTime());
     }
 
   }
diff --git a/tsfile/src/main/java/org/apache/iotdb/tsfile/file/metadata/statistics/LongStatistics.java b/tsfile/src/main/java/org/apache/iotdb/tsfile/file/metadata/statistics/LongStatistics.java
index cf1082c..075e582 100644
--- a/tsfile/src/main/java/org/apache/iotdb/tsfile/file/metadata/statistics/LongStatistics.java
+++ b/tsfile/src/main/java/org/apache/iotdb/tsfile/file/metadata/statistics/LongStatistics.java
@@ -18,15 +18,15 @@
  */
 package org.apache.iotdb.tsfile.file.metadata.statistics;
 
+import org.apache.iotdb.tsfile.file.metadata.enums.TSDataType;
+import org.apache.iotdb.tsfile.utils.BytesUtils;
+import org.apache.iotdb.tsfile.utils.ReadWriteIOUtils;
+
 import java.io.IOException;
 import java.io.InputStream;
 import java.io.OutputStream;
 import java.nio.ByteBuffer;
 
-import org.apache.iotdb.tsfile.file.metadata.enums.TSDataType;
-import org.apache.iotdb.tsfile.utils.BytesUtils;
-import org.apache.iotdb.tsfile.utils.ReadWriteIOUtils;
-
 public class LongStatistics extends Statistics<Long> {
 
   private long minValue;
@@ -64,6 +64,25 @@ public class LongStatistics extends Statistics<Long> {
     this.lastValue = lastValue;
   }
 
+  private void updateStats(long minValue, long maxValue, long firstValue, long lastValue, double sumValue, long startTime, long endTime) {
+    if (minValue < this.minValue) {
+      this.minValue = minValue;
+    }
+    if (maxValue > this.maxValue) {
+      this.maxValue = maxValue;
+    }
+    this.sumValue += sumValue;
+    // only if endTime greater or equals to the current endTime need we update the last value
+    // only if startTime less or equals to the current startTime need we update the first value
+    // otherwise, just ignore
+    if (startTime <= this.getStartTime()) {
+      this.firstValue = firstValue;
+    }
+    if (endTime >= this.getEndTime()) {
+      this.lastValue = lastValue;
+    }
+  }
+
   @Override
   public void setMinMaxFromBytes(byte[] minBytes, byte[] maxBytes) {
     minValue = BytesUtils.bytesToLong(minBytes);
@@ -130,8 +149,8 @@ public class LongStatistics extends Statistics<Long> {
           longStats.getLastValue(), longStats.getSumValue());
       isEmpty = false;
     } else {
-      updateStats(longStats.getMinValue(), longStats.getMaxValue(), longStats.getLastValue(),
-          longStats.getSumValue());
+      updateStats(longStats.getMinValue(), longStats.getMaxValue(), longStats.getFirstValue(), longStats.getLastValue(),
+          longStats.getSumValue(), stats.getStartTime(), stats.getEndTime());
     }
 
   }
diff --git a/tsfile/src/main/java/org/apache/iotdb/tsfile/file/metadata/statistics/Statistics.java b/tsfile/src/main/java/org/apache/iotdb/tsfile/file/metadata/statistics/Statistics.java
index 7563b5f..a833086 100644
--- a/tsfile/src/main/java/org/apache/iotdb/tsfile/file/metadata/statistics/Statistics.java
+++ b/tsfile/src/main/java/org/apache/iotdb/tsfile/file/metadata/statistics/Statistics.java
@@ -36,6 +36,7 @@ import java.nio.ByteBuffer;
  * writing processing, the processor records the statistics information. Statistics includes
  * maximum, minimum and null value count up to version 0.0.1.<br> Each data type extends this
  * Statistic as super class.<br>
+ * <br>For the statistics in the Unseq file TimeSeriesMetadata, only firstValue, lastValue, startTime and endTime can be used.</br>
  */
 public abstract class Statistics<T> {
 
diff --git a/tsfile/src/test/java/org/apache/iotdb/tsfile/file/metadata/statistics/BooleanStatisticsTest.java b/tsfile/src/test/java/org/apache/iotdb/tsfile/file/metadata/statistics/BooleanStatisticsTest.java
index 3f75df2..726e10d 100644
--- a/tsfile/src/test/java/org/apache/iotdb/tsfile/file/metadata/statistics/BooleanStatisticsTest.java
+++ b/tsfile/src/test/java/org/apache/iotdb/tsfile/file/metadata/statistics/BooleanStatisticsTest.java
@@ -18,13 +18,10 @@
  */
 package org.apache.iotdb.tsfile.file.metadata.statistics;
 
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertTrue;
-
 import org.junit.Test;
 
-import org.apache.iotdb.tsfile.file.metadata.statistics.BooleanStatistics;
-import org.apache.iotdb.tsfile.file.metadata.statistics.Statistics;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
 
 public class BooleanStatisticsTest {
 
@@ -44,7 +41,11 @@ public class BooleanStatisticsTest {
   @Test
   public void testMerge() {
     Statistics<Boolean> booleanStats1 = new BooleanStatistics();
+    booleanStats1.setStartTime(0);
+    booleanStats1.setEndTime(2);
     Statistics<Boolean> booleanStats2 = new BooleanStatistics();
+    booleanStats2.setStartTime(3);
+    booleanStats2.setEndTime(5);
 
     booleanStats1.updateStats(false);
     booleanStats1.updateStats(false);
@@ -60,5 +61,23 @@ public class BooleanStatisticsTest {
     booleanStats3.mergeStatistics(booleanStats2);
     assertFalse(booleanStats3.getFirstValue());
     assertTrue(booleanStats3.getLastValue());
+
+    // unseq merge
+    Statistics<Boolean> booleanStats4 = new BooleanStatistics();
+    booleanStats4.setStartTime(0);
+    booleanStats4.setEndTime(5);
+    booleanStats4.updateStats(true);
+
+    booleanStats3.mergeStatistics(booleanStats4);
+    assertTrue(booleanStats3.getFirstValue());
+    assertTrue(booleanStats3.getLastValue());
+
+    Statistics<Boolean> booleanStats5 = new BooleanStatistics();
+    booleanStats5.setStartTime(1);
+    booleanStats5.setEndTime(4);
+    booleanStats5.updateStats(false);
+    booleanStats3.mergeStatistics(booleanStats5);
+    assertTrue(booleanStats3.getFirstValue());
+    assertTrue(booleanStats3.getLastValue());
   }
 }
diff --git a/tsfile/src/test/java/org/apache/iotdb/tsfile/file/metadata/statistics/DoubleStatisticsTest.java b/tsfile/src/test/java/org/apache/iotdb/tsfile/file/metadata/statistics/DoubleStatisticsTest.java
index 7ae8b56..0a0131c 100644
--- a/tsfile/src/test/java/org/apache/iotdb/tsfile/file/metadata/statistics/DoubleStatisticsTest.java
+++ b/tsfile/src/test/java/org/apache/iotdb/tsfile/file/metadata/statistics/DoubleStatisticsTest.java
@@ -18,13 +18,10 @@
  */
 package org.apache.iotdb.tsfile.file.metadata.statistics;
 
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-
 import org.junit.Test;
 
-import org.apache.iotdb.tsfile.file.metadata.statistics.DoubleStatistics;
-import org.apache.iotdb.tsfile.file.metadata.statistics.Statistics;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
 
 public class DoubleStatisticsTest {
 
@@ -47,7 +44,11 @@ public class DoubleStatisticsTest {
   @Test
   public void testMerge() {
     Statistics<Double> doubleStats1 = new DoubleStatistics();
+    doubleStats1.setStartTime(0);
+    doubleStats1.setEndTime(2);
     Statistics<Double> doubleStats2 = new DoubleStatistics();
+    doubleStats2.setStartTime(3);
+    doubleStats2.setEndTime(5);
 
     doubleStats1.updateStats(1.34d);
     doubleStats1.updateStats(100.13453d);
@@ -69,6 +70,27 @@ public class DoubleStatisticsTest {
     assertEquals(100.13453d + 1.34d + 200.435d, doubleStats3.getSumValue(), maxError);
     assertEquals(1.34d, doubleStats3.getFirstValue(), maxError);
     assertEquals(200.435d, doubleStats3.getLastValue(), maxError);
+
+    // Unseq merge
+    Statistics<Double> doubleStats4 = new DoubleStatistics();
+    doubleStats4.setStartTime(0);
+    doubleStats4.setEndTime(5);
+    Statistics<Double> doubleStats5 = new DoubleStatistics();
+    doubleStats5.setStartTime(1);
+    doubleStats5.setEndTime(4);
+
+    doubleStats4.updateStats(122.34d);
+    doubleStats4.updateStats(125.34d);
+    doubleStats5.updateStats(111.1d);
+
+    doubleStats3.mergeStatistics(doubleStats4);
+    assertEquals(122.34d, doubleStats3.getFirstValue(), maxError);
+    assertEquals(125.34d, doubleStats3.getLastValue(), maxError);
+
+
+    doubleStats3.mergeStatistics(doubleStats5);
+    assertEquals(122.34d, doubleStats3.getFirstValue(), maxError);
+    assertEquals(125.34d, doubleStats3.getLastValue(), maxError);
   }
 
 }
diff --git a/tsfile/src/test/java/org/apache/iotdb/tsfile/file/metadata/statistics/FloatStatisticsTest.java b/tsfile/src/test/java/org/apache/iotdb/tsfile/file/metadata/statistics/FloatStatisticsTest.java
index 1fc8620..8bd49c3 100644
--- a/tsfile/src/test/java/org/apache/iotdb/tsfile/file/metadata/statistics/FloatStatisticsTest.java
+++ b/tsfile/src/test/java/org/apache/iotdb/tsfile/file/metadata/statistics/FloatStatisticsTest.java
@@ -18,13 +18,10 @@
  */
 package org.apache.iotdb.tsfile.file.metadata.statistics;
 
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-
 import org.junit.Test;
 
-import org.apache.iotdb.tsfile.file.metadata.statistics.FloatStatistics;
-import org.apache.iotdb.tsfile.file.metadata.statistics.Statistics;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
 
 public class FloatStatisticsTest {
 
@@ -47,7 +44,11 @@ public class FloatStatisticsTest {
   @Test
   public void testMerge() {
     Statistics<Float> floatStats1 = new FloatStatistics();
+    floatStats1.setStartTime(0);
+    floatStats1.setEndTime(2);
     Statistics<Float> floatStats2 = new FloatStatistics();
+    floatStats2.setStartTime(3);
+    floatStats2.setEndTime(5);
 
     floatStats1.updateStats(1.34f);
     floatStats1.updateStats(100.13453f);
@@ -64,12 +65,33 @@ public class FloatStatisticsTest {
     assertEquals(100.13453f, floatStats3.getLastValue(), maxError);
 
     floatStats3.mergeStatistics(floatStats2);
-    assertEquals(200.435d, floatStats3.getMaxValue(), maxError);
-    assertEquals(1.34d, floatStats3.getMinValue(), maxError);
-    assertEquals(100.13453f + 1.34f + 200.435d, (float) floatStats3.getSumValue(), maxError);
+    assertEquals(200.435f, floatStats3.getMaxValue(), maxError);
+    assertEquals(1.34f, floatStats3.getMinValue(), maxError);
+    assertEquals(100.13453f + 1.34f + 200.435f, (float) floatStats3.getSumValue(), maxError);
     assertEquals(1.34f, floatStats3.getFirstValue(), maxError);
     assertEquals(200.435f, floatStats3.getLastValue(), maxError);
 
+    // Unseq merge
+    Statistics<Float> floatStats4 = new FloatStatistics();
+    floatStats4.setStartTime(0);
+    floatStats4.setEndTime(5);
+    Statistics<Float> floatStats5 = new FloatStatistics();
+    floatStats5.setStartTime(1);
+    floatStats5.setEndTime(4);
+
+    floatStats4.updateStats(122.34f);
+    floatStats4.updateStats(125.34f);
+    floatStats5.updateStats(111.1f);
+
+    floatStats3.mergeStatistics(floatStats4);
+    assertEquals(122.34f, floatStats3.getFirstValue(), maxError);
+    assertEquals(125.34f, floatStats3.getLastValue(), maxError);
+
+
+    floatStats3.mergeStatistics(floatStats5);
+    assertEquals(122.34f, floatStats3.getFirstValue(), maxError);
+    assertEquals(125.34f, floatStats3.getLastValue(), maxError);
+
   }
 
 }
diff --git a/tsfile/src/test/java/org/apache/iotdb/tsfile/file/metadata/statistics/IntegerStatisticsTest.java b/tsfile/src/test/java/org/apache/iotdb/tsfile/file/metadata/statistics/IntegerStatisticsTest.java
index b440b96..9de231e 100644
--- a/tsfile/src/test/java/org/apache/iotdb/tsfile/file/metadata/statistics/IntegerStatisticsTest.java
+++ b/tsfile/src/test/java/org/apache/iotdb/tsfile/file/metadata/statistics/IntegerStatisticsTest.java
@@ -18,13 +18,10 @@
  */
 package org.apache.iotdb.tsfile.file.metadata.statistics;
 
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-
 import org.junit.Test;
 
-import org.apache.iotdb.tsfile.file.metadata.statistics.IntegerStatistics;
-import org.apache.iotdb.tsfile.file.metadata.statistics.Statistics;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
 
 public class IntegerStatisticsTest {
 
@@ -45,7 +42,11 @@ public class IntegerStatisticsTest {
   @Test
   public void testMerge() {
     Statistics<Integer> intStats1 = new IntegerStatistics();
+    intStats1.setStartTime(0);
+    intStats1.setEndTime(2);
     Statistics<Integer> intStats2 = new IntegerStatistics();
+    intStats2.setStartTime(3);
+    intStats2.setEndTime(5);
 
     intStats1.updateStats(1);
     intStats1.updateStats(100);
@@ -67,5 +68,26 @@ public class IntegerStatisticsTest {
     assertEquals(1, (int) intStats3.getFirstValue());
     assertEquals(101 + 200, (int) intStats3.getSumValue());
     assertEquals(200, (int) intStats3.getLastValue());
+
+    // Unseq merge
+    Statistics<Integer> intStats4 = new IntegerStatistics();
+    intStats4.setStartTime(0);
+    intStats4.setEndTime(5);
+    Statistics<Integer> intStats5 = new IntegerStatistics();
+    intStats5.setStartTime(1);
+    intStats5.setEndTime(4);
+
+    intStats4.updateStats(11);
+    intStats4.updateStats(15);
+
+    intStats5.updateStats(20);
+
+    intStats3.mergeStatistics(intStats4);
+    assertEquals(11, (int) intStats3.getFirstValue());
+    assertEquals(15, (int) intStats3.getLastValue());
+
+    intStats3.mergeStatistics(intStats5);
+    assertEquals(11, (int) intStats3.getFirstValue());
+    assertEquals(15, (int) intStats3.getLastValue());
   }
 }
diff --git a/tsfile/src/test/java/org/apache/iotdb/tsfile/file/metadata/statistics/LongStatisticsTest.java b/tsfile/src/test/java/org/apache/iotdb/tsfile/file/metadata/statistics/LongStatisticsTest.java
index 46f3df1..914d37f 100644
--- a/tsfile/src/test/java/org/apache/iotdb/tsfile/file/metadata/statistics/LongStatisticsTest.java
+++ b/tsfile/src/test/java/org/apache/iotdb/tsfile/file/metadata/statistics/LongStatisticsTest.java
@@ -18,17 +18,10 @@
  */
 package org.apache.iotdb.tsfile.file.metadata.statistics;
 
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertTrue;
-import static org.junit.Assert.fail;
-
+import org.apache.iotdb.tsfile.exception.filter.StatisticsClassException;
 import org.junit.Test;
 
-import org.apache.iotdb.tsfile.exception.filter.StatisticsClassException;
-import org.apache.iotdb.tsfile.file.metadata.statistics.IntegerStatistics;
-import org.apache.iotdb.tsfile.file.metadata.statistics.LongStatistics;
-import org.apache.iotdb.tsfile.file.metadata.statistics.Statistics;
+import static org.junit.Assert.*;
 
 public class LongStatisticsTest {
 
@@ -52,7 +45,11 @@ public class LongStatisticsTest {
   @Test
   public void testMerge() {
     Statistics<Long> longStats1 = new LongStatistics();
+    longStats1.setStartTime(0);
+    longStats1.setEndTime(2);
     Statistics<Long> longStats2 = new LongStatistics();
+    longStats2.setStartTime(3);
+    longStats2.setEndTime(5);
     assertTrue(longStats1.isEmpty());
     assertTrue(longStats2.isEmpty());
     long max1 = 100000000000L;
@@ -95,6 +92,27 @@ public class LongStatisticsTest {
     assertEquals(max2 + max1 + 1, (long) longStats3.getSumValue());
     assertEquals(1, (long) longStats3.getFirstValue());
     assertEquals(max2, (long) longStats3.getLastValue());
+
+    // Unseq Merge
+    LongStatistics longStats4 = new LongStatistics();
+    longStats4.setStartTime(0);
+    longStats4.setEndTime(5);
+    LongStatistics longStats5 = new LongStatistics();
+    longStats5.setStartTime(1);
+    longStats5.setEndTime(4);
+
+    longStats4.updateStats(111L);
+    longStats4.updateStats(114L);
+
+    longStats5.updateStats(116L);
+
+    longStats3.mergeStatistics(longStats4);
+    assertEquals(111L, (long) longStats3.getFirstValue());
+    assertEquals(114L, (long) longStats3.getLastValue());
+
+    longStats3.mergeStatistics(longStats5);
+    assertEquals(111L, (long) longStats3.getFirstValue());
+    assertEquals(114L, (long) longStats3.getLastValue());
   }
 
 }
diff --git a/tsfile/src/test/java/org/apache/iotdb/tsfile/file/metadata/statistics/StringStatisticsTest.java b/tsfile/src/test/java/org/apache/iotdb/tsfile/file/metadata/statistics/StringStatisticsTest.java
index 7f55f2b..07f432c 100644
--- a/tsfile/src/test/java/org/apache/iotdb/tsfile/file/metadata/statistics/StringStatisticsTest.java
+++ b/tsfile/src/test/java/org/apache/iotdb/tsfile/file/metadata/statistics/StringStatisticsTest.java
@@ -18,14 +18,11 @@
  */
 package org.apache.iotdb.tsfile.file.metadata.statistics;
 
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-
+import org.apache.iotdb.tsfile.utils.Binary;
 import org.junit.Test;
 
-import org.apache.iotdb.tsfile.file.metadata.statistics.BinaryStatistics;
-import org.apache.iotdb.tsfile.file.metadata.statistics.Statistics;
-import org.apache.iotdb.tsfile.utils.Binary;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
 
 public class StringStatisticsTest {
 
@@ -43,7 +40,11 @@ public class StringStatisticsTest {
   @Test
   public void testMerge() {
     Statistics<Binary> stringStats1 = new BinaryStatistics();
+    stringStats1.setStartTime(0);
+    stringStats1.setEndTime(2);
     Statistics<Binary> stringStats2 = new BinaryStatistics();
+    stringStats2.setStartTime(3);
+    stringStats2.setEndTime(5);
 
     stringStats1.updateStats(new Binary("aaa"));
     stringStats1.updateStats(new Binary("ccc"));
@@ -57,7 +58,28 @@ public class StringStatisticsTest {
     assertEquals("ccc", stringStats3.getLastValue().getStringValue());
 
     stringStats3.mergeStatistics(stringStats2);
-    assertEquals("aaa", (String) stringStats3.getFirstValue().getStringValue());
+    assertEquals("aaa", stringStats3.getFirstValue().getStringValue());
     assertEquals("ddd", stringStats3.getLastValue().getStringValue());
+
+    Statistics<Binary> stringStats4 = new BinaryStatistics();
+    stringStats4.setStartTime(0);
+    stringStats4.setEndTime(5);
+    Statistics<Binary> stringStats5 = new BinaryStatistics();
+    stringStats5.setStartTime(1);
+    stringStats5.setEndTime(4);
+
+    stringStats4.updateStats(new Binary("eee"));
+    stringStats4.updateStats(new Binary("fff"));
+
+    stringStats5.updateStats(new Binary("ggg"));
+
+    stringStats3.mergeStatistics(stringStats4);
+    assertEquals("eee", stringStats3.getFirstValue().getStringValue());
+    assertEquals("fff", stringStats3.getLastValue().getStringValue());
+
+    stringStats3.mergeStatistics(stringStats5);
+    assertEquals("eee", stringStats3.getFirstValue().getStringValue());
+    assertEquals("fff", stringStats3.getLastValue().getStringValue());
+
   }
 }