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 2021/03/15 01:19:18 UTC

[iotdb] 01/05: add VectorSeriesReader

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

jackietien pushed a commit to branch TYQuery
in repository https://gitbox.apache.org/repos/asf/iotdb.git

commit 6cd892d4722d18ea36a9880877cb92b2a0fe1071
Author: JackieTien97 <Ja...@foxmail.com>
AuthorDate: Fri Mar 12 21:18:40 2021 +0800

    add VectorSeriesReader
---
 .../cluster/query/reader/ClusterReaderFactory.java |  26 ++--
 .../query/reader/series/SeriesAggregateReader.java |  14 +--
 .../reader/series/SeriesRawDataBatchReader.java    |  28 +----
 .../iotdb/db/query/reader/series/SeriesReader.java | 136 ++++++++++-----------
 .../reader/series/SeriesReaderByTimestamp.java     |  19 +--
 .../query/reader/series/SeriesReaderFactory.java   |  53 ++++++++
 .../db/query/reader/series/VectorSeriesReader.java | 115 +++++++++++++++++
 7 files changed, 255 insertions(+), 136 deletions(-)

diff --git a/cluster/src/main/java/org/apache/iotdb/cluster/query/reader/ClusterReaderFactory.java b/cluster/src/main/java/org/apache/iotdb/cluster/query/reader/ClusterReaderFactory.java
index 91819b1..2d29033 100644
--- a/cluster/src/main/java/org/apache/iotdb/cluster/query/reader/ClusterReaderFactory.java
+++ b/cluster/src/main/java/org/apache/iotdb/cluster/query/reader/ClusterReaderFactory.java
@@ -55,6 +55,7 @@ import org.apache.iotdb.db.query.reader.series.SeriesRawDataBatchReader;
 import org.apache.iotdb.db.query.reader.series.SeriesRawDataPointReader;
 import org.apache.iotdb.db.query.reader.series.SeriesReader;
 import org.apache.iotdb.db.query.reader.series.SeriesReaderByTimestamp;
+import org.apache.iotdb.db.query.reader.series.SeriesReaderFactory;
 import org.apache.iotdb.db.utils.SerializeUtils;
 import org.apache.iotdb.rpc.TSStatusCode;
 import org.apache.iotdb.tsfile.file.metadata.enums.TSDataType;
@@ -207,7 +208,7 @@ public class ClusterReaderFactory {
    * each group a series reader will be created, and finally all such readers will be merged into
    * one.
    *
-   * @param timeFilter nullable, when null, all data groups will be queried
+   * @param timeFilter  nullable, when null, all data groups will be queried
    * @param valueFilter nullable
    */
   public ManagedSeriesReader getSeriesReader(
@@ -253,7 +254,7 @@ public class ClusterReaderFactory {
    * "partitionGroup" contains the local node, a local reader will be returned. Otherwise a remote
    * reader will be returned.
    *
-   * @param timeFilter nullable
+   * @param timeFilter  nullable
    * @param valueFilter nullable
    */
   private IPointReader getSeriesReader(
@@ -313,7 +314,7 @@ public class ClusterReaderFactory {
    *
    * @param path
    * @param dataType
-   * @param timeFilter nullable
+   * @param timeFilter  nullable
    * @param valueFilter nullable
    * @param context
    * @return
@@ -353,7 +354,7 @@ public class ClusterReaderFactory {
    *
    * @param path
    * @param dataType
-   * @param timeFilter nullable
+   * @param timeFilter  nullable
    * @param valueFilter nullable
    * @param context
    * @return
@@ -374,16 +375,9 @@ public class ClusterReaderFactory {
         ((SlotPartitionTable) metaGroupMember.getPartitionTable()).getNodeSlots(header);
     QueryDataSource queryDataSource =
         QueryResourceManager.getInstance().getQueryDataSource(path, context, timeFilter);
-    return new SeriesReader(
-        path,
-        allSensors,
-        dataType,
-        context,
-        queryDataSource,
-        timeFilter,
-        valueFilter,
-        new SlotTsFileFilter(nodeSlots),
-        ascending);
+    return SeriesReaderFactory
+        .createSeriesReader(path, allSensors, dataType, context, queryDataSource, timeFilter,
+            valueFilter, new SlotTsFileFilter(nodeSlots), ascending);
   }
 
   /**
@@ -392,7 +386,7 @@ public class ClusterReaderFactory {
    * the id of the reader will be returned so that we can fetch data from that node using the reader
    * id.
    *
-   * @param timeFilter nullable
+   * @param timeFilter  nullable
    * @param valueFilter nullable
    */
   private IPointReader getRemoteSeriesPointReader(
@@ -671,7 +665,7 @@ public class ClusterReaderFactory {
    *
    * @param path
    * @param dataType
-   * @param timeFilter nullable
+   * @param timeFilter  nullable
    * @param valueFilter nullable
    * @param context
    * @return an IBatchReader or null if there is no satisfying data
diff --git a/server/src/main/java/org/apache/iotdb/db/query/reader/series/SeriesAggregateReader.java b/server/src/main/java/org/apache/iotdb/db/query/reader/series/SeriesAggregateReader.java
index 04cb907..d87aa26 100644
--- a/server/src/main/java/org/apache/iotdb/db/query/reader/series/SeriesAggregateReader.java
+++ b/server/src/main/java/org/apache/iotdb/db/query/reader/series/SeriesAggregateReader.java
@@ -44,17 +44,9 @@ public class SeriesAggregateReader implements IAggregateReader {
       Filter valueFilter,
       TsFileFilter fileFilter,
       boolean ascending) {
-    this.seriesReader =
-        new SeriesReader(
-            seriesPath,
-            allSensors,
-            dataType,
-            context,
-            dataSource,
-            timeFilter,
-            valueFilter,
-            fileFilter,
-            ascending);
+    this.seriesReader = SeriesReaderFactory
+        .createSeriesReader(seriesPath, allSensors, dataType, context, dataSource, timeFilter,
+            valueFilter, fileFilter, ascending);
   }
 
   @Override
diff --git a/server/src/main/java/org/apache/iotdb/db/query/reader/series/SeriesRawDataBatchReader.java b/server/src/main/java/org/apache/iotdb/db/query/reader/series/SeriesRawDataBatchReader.java
index 8698955..7be1fb2 100644
--- a/server/src/main/java/org/apache/iotdb/db/query/reader/series/SeriesRawDataBatchReader.java
+++ b/server/src/main/java/org/apache/iotdb/db/query/reader/series/SeriesRawDataBatchReader.java
@@ -57,17 +57,9 @@ public class SeriesRawDataBatchReader implements ManagedSeriesReader {
       Filter valueFilter,
       TsFileFilter fileFilter,
       boolean ascending) {
-    this.seriesReader =
-        new SeriesReader(
-            seriesPath,
-            allSensors,
-            dataType,
-            context,
-            dataSource,
-            timeFilter,
-            valueFilter,
-            fileFilter,
-            ascending);
+    this.seriesReader = SeriesReaderFactory
+        .createSeriesReader(seriesPath, allSensors, dataType, context, dataSource, timeFilter,
+            valueFilter, fileFilter, ascending);
   }
 
   @TestOnly
@@ -83,17 +75,9 @@ public class SeriesRawDataBatchReader implements ManagedSeriesReader {
       boolean ascending) {
     Set<String> allSensors = new HashSet<>();
     allSensors.add(seriesPath.getMeasurement());
-    this.seriesReader =
-        new SeriesReader(
-            seriesPath,
-            allSensors,
-            dataType,
-            context,
-            seqFileResource,
-            unseqFileResource,
-            timeFilter,
-            valueFilter,
-            ascending);
+    this.seriesReader = SeriesReaderFactory
+        .createSeriesReader(seriesPath, allSensors, dataType, context, seqFileResource,
+            unseqFileResource, timeFilter, valueFilter, ascending);
   }
 
   /**
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 5350993..1051a24 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
@@ -18,6 +18,16 @@
  */
 package org.apache.iotdb.db.query.reader.series;
 
+import java.io.IOException;
+import java.io.Serializable;
+import java.util.Comparator;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Objects;
+import java.util.PriorityQueue;
+import java.util.Set;
+import java.util.function.ToLongFunction;
+import java.util.stream.Collectors;
 import org.apache.iotdb.db.conf.IoTDBDescriptor;
 import org.apache.iotdb.db.engine.querycontext.QueryDataSource;
 import org.apache.iotdb.db.engine.storagegroup.TsFileResource;
@@ -44,28 +54,17 @@ import org.apache.iotdb.tsfile.read.filter.basic.Filter;
 import org.apache.iotdb.tsfile.read.filter.basic.UnaryFilter;
 import org.apache.iotdb.tsfile.read.reader.IPageReader;
 
-import java.io.IOException;
-import java.io.Serializable;
-import java.util.Comparator;
-import java.util.LinkedList;
-import java.util.List;
-import java.util.Objects;
-import java.util.PriorityQueue;
-import java.util.Set;
-import java.util.function.ToLongFunction;
-import java.util.stream.Collectors;
-
 public class SeriesReader {
 
   // inner class of SeriesReader for order purpose
-  private TimeOrderUtils orderUtils;
+  protected TimeOrderUtils orderUtils;
 
-  private final PartialPath seriesPath;
+  protected final PartialPath seriesPath;
 
   // all the sensors in this device;
-  private final Set<String> allSensors;
-  private final TSDataType dataType;
-  private final QueryContext context;
+  protected final Set<String> allSensors;
+  protected final TSDataType dataType;
+  protected final QueryContext context;
 
   /*
    * There is at most one is not null between timeFilter and valueFilter
@@ -74,44 +73,44 @@ public class SeriesReader {
    *
    * valueFilter is pushed down to non-overlapped page only
    */
-  private final Filter timeFilter;
-  private final Filter valueFilter;
+  protected final Filter timeFilter;
+  protected final Filter valueFilter;
   /*
    * file cache
    */
-  private final List<TsFileResource> seqFileResource;
-  private final List<TsFileResource> unseqFileResource;
+  protected final List<TsFileResource> seqFileResource;
+  protected final List<TsFileResource> unseqFileResource;
 
   /*
    * TimeSeriesMetadata cache
    */
-  private ITimeSeriesMetadata firstTimeSeriesMetadata;
-  private final List<ITimeSeriesMetadata> seqTimeSeriesMetadata = new LinkedList<>();
-  private final PriorityQueue<ITimeSeriesMetadata> unSeqTimeSeriesMetadata;
+  protected ITimeSeriesMetadata firstTimeSeriesMetadata;
+  protected final List<ITimeSeriesMetadata> seqTimeSeriesMetadata = new LinkedList<>();
+  protected final PriorityQueue<ITimeSeriesMetadata> unSeqTimeSeriesMetadata;
 
   /*
    * chunk cache
    */
-  private IChunkMetadata firstChunkMetadata;
-  private final PriorityQueue<IChunkMetadata> cachedChunkMetadata;
+  protected IChunkMetadata firstChunkMetadata;
+  protected final PriorityQueue<IChunkMetadata> cachedChunkMetadata;
 
   /*
    * page cache
    */
-  private VersionPageReader firstPageReader;
-  private final List<VersionPageReader> seqPageReaders = new LinkedList<>();
-  private final PriorityQueue<VersionPageReader> unSeqPageReaders;
+  protected VersionPageReader firstPageReader;
+  protected final List<VersionPageReader> seqPageReaders = new LinkedList<>();
+  protected final PriorityQueue<VersionPageReader> unSeqPageReaders;
 
   /*
    * point cache
    */
-  private final PriorityMergeReader mergeReader;
+  protected final PriorityMergeReader mergeReader;
 
   /*
    * result cache
    */
-  private boolean hasCachedNextOverlappedPage;
-  private BatchData cachedBatchData;
+  protected boolean hasCachedNextOverlappedPage;
+  protected BatchData cachedBatchData;
 
   public SeriesReader(
       PartialPath seriesPath,
@@ -329,7 +328,7 @@ public class SeriesReader {
     }
   }
 
-  private void unpackOneTimeSeriesMetadata(ITimeSeriesMetadata timeSeriesMetadata)
+  protected void unpackOneTimeSeriesMetadata(ITimeSeriesMetadata timeSeriesMetadata)
       throws IOException {
     List<IChunkMetadata> chunkMetadataList =
         FileLoaderUtils.loadChunkMetadataList(timeSeriesMetadata);
@@ -857,36 +856,19 @@ public class SeriesReader {
    * approach is likely to be ubiquitous, but it keeps the system running smoothly
    */
   @SuppressWarnings("squid:S3776") // Suppress high Cognitive Complexity warning
-  private void tryToUnpackAllOverlappedFilesToTimeSeriesMetadata() throws IOException {
+  protected void tryToUnpackAllOverlappedFilesToTimeSeriesMetadata() throws IOException {
     /*
      * Fill sequence TimeSeriesMetadata List until it is not empty
      */
     while (seqTimeSeriesMetadata.isEmpty() && !seqFileResource.isEmpty()) {
-      TimeseriesMetadata timeseriesMetadata =
-          FileLoaderUtils.loadTimeSeriesMetadata(
-              orderUtils.getNextSeqFileResource(seqFileResource, true),
-              seriesPath,
-              context,
-              getAnyFilter(),
-              allSensors);
-      if (timeseriesMetadata != null) {
-        timeseriesMetadata.setSeq(true);
-        seqTimeSeriesMetadata.add(timeseriesMetadata);
-      }
+      unpackSeqTsFileResource();
     }
 
     /*
      * Fill unSequence TimeSeriesMetadata Priority Queue until it is not empty
      */
     while (unSeqTimeSeriesMetadata.isEmpty() && !unseqFileResource.isEmpty()) {
-      TimeseriesMetadata timeseriesMetadata =
-          FileLoaderUtils.loadTimeSeriesMetadata(
-              unseqFileResource.remove(0), seriesPath, context, getAnyFilter(), allSensors);
-      if (timeseriesMetadata != null) {
-        timeseriesMetadata.setModified(true);
-        timeseriesMetadata.setSeq(false);
-        unSeqTimeSeriesMetadata.add(timeseriesMetadata);
-      }
+      unpackUnseqTsFileResource();
     }
 
     /*
@@ -935,37 +917,45 @@ public class SeriesReader {
     }
   }
 
-  private void unpackAllOverlappedTsFilesToTimeSeriesMetadata(long endpointTime)
+  protected void unpackAllOverlappedTsFilesToTimeSeriesMetadata(long endpointTime)
       throws IOException {
     while (!unseqFileResource.isEmpty()
         && orderUtils.isOverlapped(endpointTime, unseqFileResource.get(0))) {
-      TimeseriesMetadata timeseriesMetadata =
-          FileLoaderUtils.loadTimeSeriesMetadata(
-              unseqFileResource.remove(0), seriesPath, context, getAnyFilter(), allSensors);
-      if (timeseriesMetadata != null) {
-        timeseriesMetadata.setModified(true);
-        timeseriesMetadata.setSeq(false);
-        unSeqTimeSeriesMetadata.add(timeseriesMetadata);
-      }
+      unpackUnseqTsFileResource();
     }
     while (!seqFileResource.isEmpty()
         && orderUtils.isOverlapped(
             endpointTime, orderUtils.getNextSeqFileResource(seqFileResource, false))) {
-      TimeseriesMetadata timeseriesMetadata =
-          FileLoaderUtils.loadTimeSeriesMetadata(
-              orderUtils.getNextSeqFileResource(seqFileResource, true),
-              seriesPath,
-              context,
-              getAnyFilter(),
-              allSensors);
-      if (timeseriesMetadata != null) {
-        timeseriesMetadata.setSeq(true);
-        seqTimeSeriesMetadata.add(timeseriesMetadata);
-      }
+      unpackSeqTsFileResource();
+    }
+  }
+
+  protected void unpackSeqTsFileResource() throws IOException {
+    TimeseriesMetadata timeseriesMetadata =
+        FileLoaderUtils.loadTimeSeriesMetadata(
+            orderUtils.getNextSeqFileResource(seqFileResource, true),
+            seriesPath,
+            context,
+            getAnyFilter(),
+            allSensors);
+    if (timeseriesMetadata != null) {
+      timeseriesMetadata.setSeq(true);
+      seqTimeSeriesMetadata.add(timeseriesMetadata);
+    }
+  }
+
+  protected void unpackUnseqTsFileResource() throws IOException {
+    TimeseriesMetadata timeseriesMetadata =
+        FileLoaderUtils.loadTimeSeriesMetadata(
+            unseqFileResource.remove(0), seriesPath, context, getAnyFilter(), allSensors);
+    if (timeseriesMetadata != null) {
+      timeseriesMetadata.setModified(true);
+      timeseriesMetadata.setSeq(false);
+      unSeqTimeSeriesMetadata.add(timeseriesMetadata);
     }
   }
 
-  private Filter getAnyFilter() {
+  protected Filter getAnyFilter() {
     return timeFilter != null ? timeFilter : valueFilter;
   }
 
diff --git a/server/src/main/java/org/apache/iotdb/db/query/reader/series/SeriesReaderByTimestamp.java b/server/src/main/java/org/apache/iotdb/db/query/reader/series/SeriesReaderByTimestamp.java
index f09b980..2063e71 100644
--- a/server/src/main/java/org/apache/iotdb/db/query/reader/series/SeriesReaderByTimestamp.java
+++ b/server/src/main/java/org/apache/iotdb/db/query/reader/series/SeriesReaderByTimestamp.java
@@ -18,6 +18,8 @@
  */
 package org.apache.iotdb.db.query.reader.series;
 
+import java.io.IOException;
+import java.util.Set;
 import org.apache.iotdb.db.engine.querycontext.QueryDataSource;
 import org.apache.iotdb.db.metadata.PartialPath;
 import org.apache.iotdb.db.query.context.QueryContext;
@@ -28,9 +30,6 @@ import org.apache.iotdb.tsfile.read.common.BatchData;
 import org.apache.iotdb.tsfile.read.filter.TimeFilter;
 import org.apache.iotdb.tsfile.read.filter.basic.UnaryFilter;
 
-import java.io.IOException;
-import java.util.Set;
-
 public class SeriesReaderByTimestamp implements IReaderByTimestamp {
 
   private SeriesReader seriesReader;
@@ -47,17 +46,9 @@ public class SeriesReaderByTimestamp implements IReaderByTimestamp {
       boolean ascending) {
     UnaryFilter timeFilter =
         ascending ? TimeFilter.gtEq(Long.MIN_VALUE) : TimeFilter.ltEq(Long.MAX_VALUE);
-    seriesReader =
-        new SeriesReader(
-            seriesPath,
-            allSensors,
-            dataType,
-            context,
-            dataSource,
-            timeFilter,
-            null,
-            fileFilter,
-            ascending);
+    this.seriesReader = SeriesReaderFactory
+        .createSeriesReader(seriesPath, allSensors, dataType, context, dataSource, timeFilter, null,
+            fileFilter, ascending);
     this.ascending = ascending;
   }
 
diff --git a/server/src/main/java/org/apache/iotdb/db/query/reader/series/SeriesReaderFactory.java b/server/src/main/java/org/apache/iotdb/db/query/reader/series/SeriesReaderFactory.java
new file mode 100644
index 0000000..562cb2d
--- /dev/null
+++ b/server/src/main/java/org/apache/iotdb/db/query/reader/series/SeriesReaderFactory.java
@@ -0,0 +1,53 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.iotdb.db.query.reader.series;
+
+import java.util.List;
+import java.util.Set;
+import org.apache.iotdb.db.engine.querycontext.QueryDataSource;
+import org.apache.iotdb.db.engine.storagegroup.TsFileResource;
+import org.apache.iotdb.db.metadata.PartialPath;
+import org.apache.iotdb.db.metadata.VectorPartialPath;
+import org.apache.iotdb.db.query.context.QueryContext;
+import org.apache.iotdb.db.query.filter.TsFileFilter;
+import org.apache.iotdb.tsfile.file.metadata.enums.TSDataType;
+import org.apache.iotdb.tsfile.read.filter.basic.Filter;
+
+public class SeriesReaderFactory {
+
+  public static SeriesReader createSeriesReader(PartialPath seriesPath, Set<String> allSensors,
+      TSDataType dataType, QueryContext context, QueryDataSource dataSource, Filter timeFilter,
+      Filter valueFilter, TsFileFilter fileFilter, boolean ascending) {
+    if (seriesPath instanceof VectorPartialPath) {
+      return new VectorSeriesReader(seriesPath, allSensors, dataType, context, dataSource,
+          timeFilter, valueFilter, fileFilter, ascending);
+    } else {
+      return new SeriesReader(seriesPath, allSensors, dataType, context, dataSource, timeFilter,
+          valueFilter, fileFilter, ascending);
+    }
+  }
+
+  public static SeriesReader createSeriesReader(PartialPath seriesPath, Set<String> allSensors,
+      TSDataType dataType, QueryContext context, List<TsFileResource> seqFileResource,
+      List<TsFileResource> unseqFileResource, Filter timeFilter, Filter valueFilter,
+      boolean ascending) {
+    return new SeriesReader(seriesPath, allSensors, dataType, context, seqFileResource,
+        unseqFileResource, timeFilter, valueFilter, ascending);
+  }
+}
diff --git a/server/src/main/java/org/apache/iotdb/db/query/reader/series/VectorSeriesReader.java b/server/src/main/java/org/apache/iotdb/db/query/reader/series/VectorSeriesReader.java
new file mode 100644
index 0000000..29e7d13
--- /dev/null
+++ b/server/src/main/java/org/apache/iotdb/db/query/reader/series/VectorSeriesReader.java
@@ -0,0 +1,115 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.iotdb.db.query.reader.series;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import java.util.Set;
+import org.apache.iotdb.db.engine.querycontext.QueryDataSource;
+import org.apache.iotdb.db.engine.storagegroup.TsFileResource;
+import org.apache.iotdb.db.metadata.PartialPath;
+import org.apache.iotdb.db.metadata.VectorPartialPath;
+import org.apache.iotdb.db.query.context.QueryContext;
+import org.apache.iotdb.db.query.filter.TsFileFilter;
+import org.apache.iotdb.db.utils.FileLoaderUtils;
+import org.apache.iotdb.db.utils.TestOnly;
+import org.apache.iotdb.tsfile.file.metadata.TimeseriesMetadata;
+import org.apache.iotdb.tsfile.file.metadata.VectorTimeSeriesMetadata;
+import org.apache.iotdb.tsfile.file.metadata.enums.TSDataType;
+import org.apache.iotdb.tsfile.read.filter.basic.Filter;
+
+public class VectorSeriesReader extends SeriesReader {
+
+  private final VectorPartialPath vectorPartialPath;
+
+  public VectorSeriesReader(PartialPath seriesPath,
+      Set<String> allSensors,
+      TSDataType dataType,
+      QueryContext context,
+      QueryDataSource dataSource,
+      Filter timeFilter,
+      Filter valueFilter,
+      TsFileFilter fileFilter, boolean ascending) {
+    super(seriesPath, allSensors, dataType, context, dataSource, timeFilter, valueFilter,
+        fileFilter,
+        ascending);
+    this.vectorPartialPath = (VectorPartialPath) seriesPath;
+  }
+
+  @TestOnly
+  VectorSeriesReader(PartialPath seriesPath, Set<String> allSensors,
+      TSDataType dataType, QueryContext context,
+      List<TsFileResource> seqFileResource,
+      List<TsFileResource> unseqFileResource,
+      Filter timeFilter, Filter valueFilter, boolean ascending) {
+    super(seriesPath, allSensors, dataType, context, seqFileResource, unseqFileResource, timeFilter,
+        valueFilter, ascending);
+    this.vectorPartialPath = (VectorPartialPath) seriesPath;
+  }
+
+  protected void unpackSeqTsFileResource() throws IOException {
+    TsFileResource resource = orderUtils.getNextSeqFileResource(seqFileResource, true);
+    TimeseriesMetadata timeseriesMetadata = FileLoaderUtils
+        .loadTimeSeriesMetadata(resource, vectorPartialPath, context, getAnyFilter(), allSensors);
+    if (timeseriesMetadata != null) {
+      timeseriesMetadata.setSeq(true);
+      List<TimeseriesMetadata> valueTimeseriesMetadataList = new ArrayList<>();
+      for (PartialPath subSensor : vectorPartialPath.getSubSensorsPathList()) {
+        TimeseriesMetadata valueTimeSeriesMetadata = FileLoaderUtils
+            .loadTimeSeriesMetadata(resource, subSensor, context, getAnyFilter(),
+                Collections.emptySet());
+        if (valueTimeSeriesMetadata == null) {
+          throw new IOException("File contains value");
+        }
+        valueTimeSeriesMetadata.setSeq(true);
+        valueTimeseriesMetadataList.add(valueTimeSeriesMetadata);
+      }
+      VectorTimeSeriesMetadata vectorTimeSeriesMetadata = new VectorTimeSeriesMetadata(
+          timeseriesMetadata, valueTimeseriesMetadataList);
+      seqTimeSeriesMetadata.add(vectorTimeSeriesMetadata);
+    }
+  }
+
+  protected void unpackUnseqTsFileResource() throws IOException {
+    TsFileResource resource = unseqFileResource.remove(0);
+    TimeseriesMetadata timeseriesMetadata = FileLoaderUtils
+        .loadTimeSeriesMetadata(resource, vectorPartialPath, context, getAnyFilter(), allSensors);
+    if (timeseriesMetadata != null) {
+      timeseriesMetadata.setModified(true);
+      timeseriesMetadata.setSeq(false);
+      List<TimeseriesMetadata> valueTimeseriesMetadataList = new ArrayList<>();
+      for (PartialPath subSensor : vectorPartialPath.getSubSensorsPathList()) {
+        TimeseriesMetadata valueTimeSeriesMetadata = FileLoaderUtils
+            .loadTimeSeriesMetadata(resource, subSensor, context, getAnyFilter(),
+                Collections.emptySet());
+        if (valueTimeSeriesMetadata == null) {
+          throw new IOException("File contains value");
+        }
+        timeseriesMetadata.setModified(true);
+        valueTimeSeriesMetadata.setSeq(false);
+        valueTimeseriesMetadataList.add(valueTimeSeriesMetadata);
+      }
+      VectorTimeSeriesMetadata vectorTimeSeriesMetadata = new VectorTimeSeriesMetadata(
+          timeseriesMetadata, valueTimeseriesMetadataList);
+      unSeqTimeSeriesMetadata.add(vectorTimeSeriesMetadata);
+    }
+  }
+}