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

jackietien pushed a commit to branch snapshot/2.2.0-251208
in repository https://gitbox.apache.org/repos/asf/tsfile.git


The following commit(s) were added to refs/heads/snapshot/2.2.0-251208 by this 
push:
     new fe0d9326 enhance TsFileDeviceIterator (#657)
fe0d9326 is described below

commit fe0d93261195d09ae693a8da899189b12ef3278d
Author: shuwenwei <[email protected]>
AuthorDate: Mon Dec 8 11:11:01 2025 +0800

    enhance TsFileDeviceIterator (#657)
---
 .../tsfile/read/LazyTsFileDeviceIterator.java      | 234 +++++++++++++++++++++
 .../apache/tsfile/read/TsFileDeviceIterator.java   | 196 +----------------
 .../apache/tsfile/read/TsFileSequenceReader.java   |   7 +-
 .../tsfile/read/TsFileDeviceIteratorTest.java      |  15 +-
 4 files changed, 264 insertions(+), 188 deletions(-)

diff --git 
a/java/tsfile/src/main/java/org/apache/tsfile/read/LazyTsFileDeviceIterator.java
 
b/java/tsfile/src/main/java/org/apache/tsfile/read/LazyTsFileDeviceIterator.java
new file mode 100644
index 00000000..8a88f112
--- /dev/null
+++ 
b/java/tsfile/src/main/java/org/apache/tsfile/read/LazyTsFileDeviceIterator.java
@@ -0,0 +1,234 @@
+/*
+ * 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.tsfile.read;
+
+import org.apache.tsfile.exception.TsFileRuntimeException;
+import org.apache.tsfile.file.IMetadataIndexEntry;
+import org.apache.tsfile.file.metadata.DeviceMetadataIndexEntry;
+import org.apache.tsfile.file.metadata.IDeviceID;
+import org.apache.tsfile.file.metadata.MetadataIndexNode;
+import org.apache.tsfile.file.metadata.enums.MetadataIndexNodeType;
+import org.apache.tsfile.utils.Pair;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.io.IOException;
+import java.util.ArrayDeque;
+import java.util.Collections;
+import java.util.Iterator;
+import java.util.List;
+import java.util.NoSuchElementException;
+import java.util.Queue;
+import java.util.function.LongConsumer;
+
+public class LazyTsFileDeviceIterator {
+  protected final TsFileSequenceReader reader;
+  protected final Iterator<MetadataIndexNode> tableMetadataIndexNodeIterator;
+  protected final ArrayDeque<Pair<IDeviceID, long[]>> queue = new 
ArrayDeque<>();
+  protected final ArrayDeque<Iterator<Pair<DeviceMetadataIndexEntry, Long>>>
+      levelInternalDeviceNodeIterators = new ArrayDeque<>(4);
+  protected final LongConsumer ioSizeRecorder;
+  protected Pair<IDeviceID, long[]> currentDeviceAndMeasurementNodeOffsetPair;
+  protected MetadataIndexNode firstMeasurementNodeOfCurrentDevice;
+
+  protected static final Logger logger = 
LoggerFactory.getLogger(LazyTsFileDeviceIterator.class);
+
+  public LazyTsFileDeviceIterator(TsFileSequenceReader reader) throws 
IOException {
+    this(reader, null);
+  }
+
+  public LazyTsFileDeviceIterator(TsFileSequenceReader reader, LongConsumer 
ioSizeRecorder)
+      throws IOException {
+    this.reader = reader;
+    this.tableMetadataIndexNodeIterator =
+        
reader.readFileMetadata(ioSizeRecorder).getTableMetadataIndexNodeMap().values().iterator();
+    this.ioSizeRecorder = ioSizeRecorder;
+  }
+
+  public LazyTsFileDeviceIterator(
+      TsFileSequenceReader reader, String tableName, LongConsumer 
ioSizeRecorder)
+      throws IOException {
+    this.reader = reader;
+    this.ioSizeRecorder = ioSizeRecorder;
+    MetadataIndexNode tableMetadataIndexNode =
+        
reader.readFileMetadata(ioSizeRecorder).getTableMetadataIndexNode(tableName);
+    this.tableMetadataIndexNodeIterator =
+        tableMetadataIndexNode == null
+            ? Collections.emptyIterator()
+            : Collections.singleton(tableMetadataIndexNode).iterator();
+  }
+
+  public boolean hasNext() {
+    try {
+      while (true) {
+        if (!queue.isEmpty()) {
+          return true;
+        }
+
+        if (!levelInternalDeviceNodeIterators.isEmpty()) {
+          advanceInternalIterators();
+          continue;
+        }
+
+        if (!tableMetadataIndexNodeIterator.hasNext()) {
+          return false;
+        }
+        prepareNextTable();
+      }
+    } catch (IOException e) {
+      throw new TsFileRuntimeException(e);
+    }
+  }
+
+  private void advanceInternalIterators() throws IOException {
+    while (!levelInternalDeviceNodeIterators.isEmpty() && queue.isEmpty()) {
+      Iterator<Pair<DeviceMetadataIndexEntry, Long>> iterator =
+          levelInternalDeviceNodeIterators.peek();
+
+      if (!iterator.hasNext()) {
+        levelInternalDeviceNodeIterators.pop();
+        continue;
+      }
+
+      Pair<DeviceMetadataIndexEntry, Long> childEntryPair = iterator.next();
+      MetadataIndexNode node =
+          reader.readMetadataIndexNode(
+              childEntryPair.getLeft().getOffset(),
+              childEntryPair.getRight(),
+              true,
+              ioSizeRecorder);
+
+      if (node.getNodeType() == MetadataIndexNodeType.LEAF_DEVICE) {
+        getDevicesOfLeafNode(node, queue);
+      } else {
+        
levelInternalDeviceNodeIterators.push(constructDeviceEntryIterator(node));
+      }
+    }
+  }
+
+  public IDeviceID next() {
+    if (!hasNext()) {
+      throw new NoSuchElementException();
+    }
+    this.currentDeviceAndMeasurementNodeOffsetPair = queue.remove();
+    this.firstMeasurementNodeOfCurrentDevice = null;
+    return currentDeviceAndMeasurementNodeOffsetPair.getLeft();
+  }
+
+  public IDeviceID getCurrentDeviceID() {
+    if (currentDeviceAndMeasurementNodeOffsetPair == null) {
+      throw new IllegalStateException("next() must be called before accessing 
current device");
+    }
+    return currentDeviceAndMeasurementNodeOffsetPair.getLeft();
+  }
+
+  public long[] getCurrentDeviceMeasurementNodeOffset() {
+    if (currentDeviceAndMeasurementNodeOffsetPair == null) {
+      throw new IllegalStateException("next() must be called before accessing 
current device");
+    }
+    return this.currentDeviceAndMeasurementNodeOffsetPair.getRight();
+  }
+
+  public boolean isCurrentDeviceAligned() throws IOException {
+    return reader.isAlignedDevice(getFirstMeasurementNodeOfCurrentDevice());
+  }
+
+  public MetadataIndexNode getFirstMeasurementNodeOfCurrentDevice() throws 
IOException {
+    if (currentDeviceAndMeasurementNodeOffsetPair == null) {
+      throw new IllegalStateException("next() must be called before accessing 
current device");
+    }
+    if (this.firstMeasurementNodeOfCurrentDevice != null) {
+      return this.firstMeasurementNodeOfCurrentDevice;
+    }
+    long[] offsetArr = currentDeviceAndMeasurementNodeOffsetPair.getRight();
+    this.firstMeasurementNodeOfCurrentDevice =
+        reader.readMetadataIndexNode(offsetArr[0], offsetArr[1], false, 
ioSizeRecorder);
+    return this.firstMeasurementNodeOfCurrentDevice;
+  }
+
+  private void prepareNextTable() throws IOException {
+    while (queue.isEmpty()
+        && levelInternalDeviceNodeIterators.isEmpty()
+        && tableMetadataIndexNodeIterator.hasNext()) {
+      MetadataIndexNode nextTableMetadataIndexNode = 
tableMetadataIndexNodeIterator.next();
+
+      if 
(nextTableMetadataIndexNode.getNodeType().equals(MetadataIndexNodeType.LEAF_DEVICE))
 {
+        getDevicesOfLeafNode(nextTableMetadataIndexNode, queue);
+      } else {
+        levelInternalDeviceNodeIterators.push(
+            constructDeviceEntryIterator(nextTableMetadataIndexNode));
+      }
+    }
+  }
+
+  protected Iterator<Pair<DeviceMetadataIndexEntry, Long>> 
constructDeviceEntryIterator(
+      MetadataIndexNode node) {
+    return new Iterator<Pair<DeviceMetadataIndexEntry, Long>>() {
+
+      int index = 0;
+
+      @Override
+      public boolean hasNext() {
+        return index < node.getChildren().size();
+      }
+
+      @Override
+      public Pair<DeviceMetadataIndexEntry, Long> next() {
+        if (!hasNext()) {
+          throw new NoSuchElementException();
+        }
+        IMetadataIndexEntry entry = node.getChildren().get(index++);
+        if (index == node.getChildren().size()) {
+          return new Pair<>((DeviceMetadataIndexEntry) entry, 
node.getEndOffset());
+        }
+        return new Pair<>(
+            (DeviceMetadataIndexEntry) entry, 
node.getChildren().get(index).getOffset());
+      }
+    };
+  }
+
+  protected void getDevicesOfLeafNode(
+      MetadataIndexNode deviceLeafNode, Queue<Pair<IDeviceID, long[]>> 
measurementNodeOffsetQueue) {
+    if 
(!deviceLeafNode.getNodeType().equals(MetadataIndexNodeType.LEAF_DEVICE)) {
+      throw new IllegalStateException("the first param should be device leaf 
node.");
+    }
+    List<IMetadataIndexEntry> childrenEntries = deviceLeafNode.getChildren();
+    for (int i = 0; i < childrenEntries.size(); i++) {
+      IMetadataIndexEntry deviceEntry = childrenEntries.get(i);
+      long childStartOffset = deviceEntry.getOffset();
+      long childEndOffset =
+          i == childrenEntries.size() - 1
+              ? deviceLeafNode.getEndOffset()
+              : childrenEntries.get(i + 1).getOffset();
+      long[] offset = {childStartOffset, childEndOffset};
+      measurementNodeOffsetQueue.offer(
+          new Pair<>(((DeviceMetadataIndexEntry) deviceEntry).getDeviceID(), 
offset));
+    }
+  }
+
+  public TsFileSequenceReader getReader() {
+    return reader;
+  }
+
+  public LongConsumer getIoSizeRecorder() {
+    return ioSizeRecorder;
+  }
+}
diff --git 
a/java/tsfile/src/main/java/org/apache/tsfile/read/TsFileDeviceIterator.java 
b/java/tsfile/src/main/java/org/apache/tsfile/read/TsFileDeviceIterator.java
index fc283f26..781d233e 100644
--- a/java/tsfile/src/main/java/org/apache/tsfile/read/TsFileDeviceIterator.java
+++ b/java/tsfile/src/main/java/org/apache/tsfile/read/TsFileDeviceIterator.java
@@ -19,226 +19,50 @@
 
 package org.apache.tsfile.read;
 
-import org.apache.tsfile.compatibility.DeserializeConfig;
-import org.apache.tsfile.exception.StopReadTsFileByInterruptException;
 import org.apache.tsfile.exception.TsFileRuntimeException;
-import org.apache.tsfile.file.IMetadataIndexEntry;
-import org.apache.tsfile.file.metadata.DeviceMetadataIndexEntry;
 import org.apache.tsfile.file.metadata.IDeviceID;
 import org.apache.tsfile.file.metadata.MetadataIndexNode;
-import org.apache.tsfile.file.metadata.enums.MetadataIndexNodeType;
 import org.apache.tsfile.utils.Pair;
-import org.apache.tsfile.utils.ReadWriteIOUtils;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
 
 import java.io.IOException;
-import java.nio.ByteBuffer;
-import java.util.Collections;
 import java.util.Iterator;
-import java.util.LinkedList;
-import java.util.List;
-import java.util.NoSuchElementException;
-import java.util.Queue;
 import java.util.function.LongConsumer;
 
 public class TsFileDeviceIterator implements Iterator<Pair<IDeviceID, 
Boolean>> {
-
-  private final TsFileSequenceReader reader;
-  private final DeserializeConfig deserializeConfig;
-  private final Iterator<MetadataIndexNode> tableMetadataIndexNodeIterator;
-  private final Queue<Pair<IDeviceID, long[]>> queue = new LinkedList<>();
-  private final List<long[]> leafDeviceNodeOffsetList = new LinkedList<>();
-  private final LongConsumer ioSizeRecorder;
-  private Pair<IDeviceID, Boolean> currentDevice = null;
-  private MetadataIndexNode measurementNode;
-
-  private static final Logger logger = 
LoggerFactory.getLogger(TsFileDeviceIterator.class);
+  private final LazyTsFileDeviceIterator lazyTsFileDeviceIterator;
 
   public TsFileDeviceIterator(TsFileSequenceReader reader) throws IOException {
-    this.reader = reader;
-    this.deserializeConfig = reader.getDeserializeContext();
-    this.tableMetadataIndexNodeIterator =
-        
reader.readFileMetadata().getTableMetadataIndexNodeMap().values().iterator();
-    this.ioSizeRecorder = null;
+    this.lazyTsFileDeviceIterator = new LazyTsFileDeviceIterator(reader);
   }
 
   public TsFileDeviceIterator(
       TsFileSequenceReader reader, String tableName, LongConsumer 
ioSizeRecorder)
       throws IOException {
-    this.reader = reader;
-    this.deserializeConfig = reader.getDeserializeContext();
-    this.ioSizeRecorder = ioSizeRecorder;
-    MetadataIndexNode tableMetadataIndexNode =
-        
reader.readFileMetadata(ioSizeRecorder).getTableMetadataIndexNode(tableName);
-    this.tableMetadataIndexNodeIterator =
-        tableMetadataIndexNode == null
-            ? Collections.emptyIterator()
-            : Collections.singleton(tableMetadataIndexNode).iterator();
-  }
-
-  public Pair<IDeviceID, Boolean> current() {
-    return currentDevice;
+    this.lazyTsFileDeviceIterator = new LazyTsFileDeviceIterator(reader, 
tableName, ioSizeRecorder);
   }
 
   @Override
   public boolean hasNext() {
-    try {
-      prepareNextTable();
-      if (!queue.isEmpty()) {
-        return true;
-      } else if (leafDeviceNodeOffsetList.isEmpty()) {
-        // device queue is empty and all device leaf node has been read
-        return false;
-      } else {
-        // queue is empty but there are still some devices on leaf node not 
being read yet
-        long[] nextDeviceLeafNodeOffset = leafDeviceNodeOffsetList.remove(0);
-        getDevicesAndEntriesOfOneLeafNode(
-            nextDeviceLeafNodeOffset[0], nextDeviceLeafNodeOffset[1], queue);
-        return true;
-      }
-    } catch (IOException e) {
-      throw new TsFileRuntimeException(e);
-    }
-  }
-
-  private void prepareNextTable() throws IOException {
-    if (!queue.isEmpty() || !leafDeviceNodeOffsetList.isEmpty()) {
-      return;
-    }
-    if (!tableMetadataIndexNodeIterator.hasNext()) {
-      return;
-    }
-    MetadataIndexNode nextTableMetadataIndexNode = 
tableMetadataIndexNodeIterator.next();
-
-    if 
(nextTableMetadataIndexNode.getNodeType().equals(MetadataIndexNodeType.LEAF_DEVICE))
 {
-      getDevicesOfLeafNode(nextTableMetadataIndexNode, queue);
-    } else {
-      getAllDeviceLeafNodeOffset(nextTableMetadataIndexNode, 
leafDeviceNodeOffsetList);
-    }
+    return lazyTsFileDeviceIterator.hasNext();
   }
 
   @Override
   public Pair<IDeviceID, Boolean> next() {
-    if (!hasNext()) {
-      throw new NoSuchElementException();
-    }
-    Pair<IDeviceID, long[]> startEndPair = queue.remove();
+    IDeviceID deviceId = lazyTsFileDeviceIterator.next();
     try {
       // get the first measurement node of this device, to know if the device 
is aligned
-      this.measurementNode =
-          reader.readMetadataIndexNode(
-              startEndPair.right[0], startEndPair.right[1], false, 
ioSizeRecorder);
-      boolean isAligned = reader.isAlignedDevice(measurementNode);
-      currentDevice = new Pair<>(startEndPair.left, isAligned);
-      return currentDevice;
+      return new Pair<>(deviceId, 
lazyTsFileDeviceIterator.isCurrentDeviceAligned());
     } catch (IOException e) {
       throw new TsFileRuntimeException(
           "Error occurred while reading a time series metadata block.");
     }
   }
 
-  public MetadataIndexNode getFirstMeasurementNodeOfCurrentDevice() {
-    return measurementNode;
+  public MetadataIndexNode getFirstMeasurementNodeOfCurrentDevice() throws 
IOException {
+    return lazyTsFileDeviceIterator.getFirstMeasurementNodeOfCurrentDevice();
   }
 
-  /**
-   * Get devices and first measurement node offset.
-   *
-   * @param startOffset start offset of device leaf node
-   * @param endOffset end offset of device leaf node
-   * @param measurementNodeOffsetQueue device -> first measurement node offset
-   */
-  public void getDevicesAndEntriesOfOneLeafNode(
-      Long startOffset, Long endOffset, Queue<Pair<IDeviceID, long[]>> 
measurementNodeOffsetQueue)
-      throws IOException {
-    try {
-      ByteBuffer nextBuffer = reader.readData(startOffset, endOffset, 
ioSizeRecorder);
-      MetadataIndexNode deviceLeafNode =
-          
deserializeConfig.deviceMetadataIndexNodeBufferDeserializer.deserialize(
-              nextBuffer, deserializeConfig);
-      getDevicesOfLeafNode(deviceLeafNode, measurementNodeOffsetQueue);
-    } catch (StopReadTsFileByInterruptException e) {
-      throw e;
-    } catch (Exception e) {
-      logger.error(
-          "Something error happened while getting all devices of file {}", 
reader.getFileName());
-      throw e;
-    }
-  }
-
-  /**
-   * Get all devices and its corresponding entries on the specific device leaf 
node.
-   *
-   * @param deviceLeafNode this node must be device leaf node
-   */
-  private void getDevicesOfLeafNode(
-      MetadataIndexNode deviceLeafNode, Queue<Pair<IDeviceID, long[]>> 
measurementNodeOffsetQueue) {
-    if 
(!deviceLeafNode.getNodeType().equals(MetadataIndexNodeType.LEAF_DEVICE)) {
-      throw new IllegalStateException("the first param should be device leaf 
node.");
-    }
-    List<IMetadataIndexEntry> childrenEntries = deviceLeafNode.getChildren();
-    for (int i = 0; i < childrenEntries.size(); i++) {
-      IMetadataIndexEntry deviceEntry = childrenEntries.get(i);
-      long childStartOffset = deviceEntry.getOffset();
-      long childEndOffset =
-          i == childrenEntries.size() - 1
-              ? deviceLeafNode.getEndOffset()
-              : childrenEntries.get(i + 1).getOffset();
-      long[] offset = {childStartOffset, childEndOffset};
-      measurementNodeOffsetQueue.add(
-          new Pair<>(((DeviceMetadataIndexEntry) deviceEntry).getDeviceID(), 
offset));
-    }
-  }
-
-  /**
-   * Get the device leaf node offset under the specific device internal node.
-   *
-   * @param deviceInternalNode this node must be device internal node
-   */
-  private void getAllDeviceLeafNodeOffset(
-      MetadataIndexNode deviceInternalNode, List<long[]> 
leafDeviceNodeOffsets) throws IOException {
-    if 
(!deviceInternalNode.getNodeType().equals(MetadataIndexNodeType.INTERNAL_DEVICE))
 {
-      throw new IllegalStateException("the first param should be device 
internal node.");
-    }
-    try {
-      int metadataIndexListSize = deviceInternalNode.getChildren().size();
-      boolean isCurrentLayerLeafNode = false;
-      for (int i = 0; i < metadataIndexListSize; i++) {
-        IMetadataIndexEntry entry = deviceInternalNode.getChildren().get(i);
-        long startOffset = entry.getOffset();
-        long endOffset = deviceInternalNode.getEndOffset();
-        if (i != metadataIndexListSize - 1) {
-          endOffset = deviceInternalNode.getChildren().get(i + 1).getOffset();
-        }
-        if (i == 0) {
-          // check is current layer device leaf node or device internal node. 
Just need to check the
-          // first entry, because the rest are the same
-          MetadataIndexNodeType nodeType =
-              MetadataIndexNodeType.deserialize(
-                  ReadWriteIOUtils.readByte(
-                      reader.readData(endOffset - 1, endOffset, 
ioSizeRecorder)));
-          isCurrentLayerLeafNode = 
nodeType.equals(MetadataIndexNodeType.LEAF_DEVICE);
-        }
-        if (isCurrentLayerLeafNode) {
-          // is device leaf node
-          long[] offset = {startOffset, endOffset};
-          leafDeviceNodeOffsets.add(offset);
-          continue;
-        }
-        ByteBuffer nextBuffer = reader.readData(startOffset, endOffset, 
ioSizeRecorder);
-        getAllDeviceLeafNodeOffset(
-            
deserializeConfig.deviceMetadataIndexNodeBufferDeserializer.deserialize(
-                nextBuffer, deserializeConfig),
-            leafDeviceNodeOffsets);
-      }
-    } catch (StopReadTsFileByInterruptException e) {
-      throw e;
-    } catch (Exception e) {
-      logger.error(
-          "Something error happened while getting all devices of file {}", 
reader.getFileName());
-      throw e;
-    }
+  public long[] getCurrentDeviceMeasurementNodeOffset() {
+    return lazyTsFileDeviceIterator.getCurrentDeviceMeasurementNodeOffset();
   }
 }
diff --git 
a/java/tsfile/src/main/java/org/apache/tsfile/read/TsFileSequenceReader.java 
b/java/tsfile/src/main/java/org/apache/tsfile/read/TsFileSequenceReader.java
index 132c6f34..35a39dc9 100644
--- a/java/tsfile/src/main/java/org/apache/tsfile/read/TsFileSequenceReader.java
+++ b/java/tsfile/src/main/java/org/apache/tsfile/read/TsFileSequenceReader.java
@@ -1118,12 +1118,17 @@ public class TsFileSequenceReader implements 
AutoCloseable {
   /**
    * @return an iterator of "device, isAligned" list, in which names of 
devices are ordered in
    *     dictionary order, and isAligned represents whether the device is 
aligned. Only read devices
-   *     on one device leaf node each time to save memory.
+   *     on one device leaf node each time to save memory. If you only need to 
iterate through the
+   *     device and don't need to know if the device is aligned, use 
LazyTsFileDeviceIterator.
    */
   public TsFileDeviceIterator getAllDevicesIteratorWithIsAligned() throws 
IOException {
     return new TsFileDeviceIterator(this);
   }
 
+  public LazyTsFileDeviceIterator getLazyDeviceIterator() throws IOException {
+    return new LazyTsFileDeviceIterator(this);
+  }
+
   public TsFileDeviceIterator getTableDevicesIteratorWithIsAligned(
       String tableName, LongConsumer ioSizeRecorder) throws IOException {
     return new TsFileDeviceIterator(this, tableName, ioSizeRecorder);
diff --git 
a/java/tsfile/src/test/java/org/apache/tsfile/read/TsFileDeviceIteratorTest.java
 
b/java/tsfile/src/test/java/org/apache/tsfile/read/TsFileDeviceIteratorTest.java
index 5dd1a096..5e73ed82 100644
--- 
a/java/tsfile/src/test/java/org/apache/tsfile/read/TsFileDeviceIteratorTest.java
+++ 
b/java/tsfile/src/test/java/org/apache/tsfile/read/TsFileDeviceIteratorTest.java
@@ -82,8 +82,21 @@ public class TsFileDeviceIteratorTest {
         }
         previous = next.getLeft();
       }
+      Assert.assertEquals(totalDeviceNum, deviceFromIterator);
+
+      deviceFromIterator = 0;
+      deviceIterator = reader.getTableDevicesIteratorWithIsAligned("table2", 
null);
+      previous = null;
+      while (deviceIterator.hasNext()) {
+        Pair<IDeviceID, Boolean> next = deviceIterator.next();
+        deviceFromIterator++;
+        if (previous != null) {
+          Assert.assertTrue(previous.compareTo(next.getLeft()) < 0);
+        }
+        previous = next.getLeft();
+      }
+      Assert.assertEquals(20000, deviceFromIterator);
     }
-    Assert.assertEquals(totalDeviceNum, deviceFromIterator);
   }
 
   private void registerTableSchema(TsFileIOWriter writer, String tableName) {

Reply via email to