This is an automated email from the ASF dual-hosted git repository. shuwenwei pushed a commit to branch table_disk_usage_statistics in repository https://gitbox.apache.org/repos/asf/iotdb.git
commit 9e8b71a4e880992078b4b7f8306f925cc79b97da Author: shuwenwei <[email protected]> AuthorDate: Mon Oct 27 18:26:43 2025 +0800 fix --- .../operator/source/ShowDiskUsageOperator.java | 17 +- .../InformationSchemaContentSupplierFactory.java | 243 ++++----------------- .../InformationSchemaTableScanOperator.java | 13 +- .../utils/StorageEngineTimePartitionIterator.java | 13 +- .../utils/TableDiskUsageStatisticUtil.java | 3 + .../utils/TreeDiskUsageStatisticUtil.java | 24 +- 6 files changed, 104 insertions(+), 209 deletions(-) diff --git a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/execution/operator/source/ShowDiskUsageOperator.java b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/execution/operator/source/ShowDiskUsageOperator.java index c6a39caef0a..07272573207 100644 --- a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/execution/operator/source/ShowDiskUsageOperator.java +++ b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/execution/operator/source/ShowDiskUsageOperator.java @@ -23,14 +23,17 @@ import org.apache.iotdb.commons.path.PartialPath; import org.apache.iotdb.commons.utils.PathUtils; import org.apache.iotdb.db.conf.IoTDBDescriptor; import org.apache.iotdb.db.queryengine.common.header.DatasetHeaderFactory; +import org.apache.iotdb.db.queryengine.execution.MemoryEstimationHelper; import org.apache.iotdb.db.queryengine.execution.operator.OperatorContext; import org.apache.iotdb.db.queryengine.plan.planner.plan.node.PlanNodeId; import org.apache.iotdb.db.storageengine.dataregion.DataRegion; import org.apache.iotdb.db.storageengine.dataregion.utils.StorageEngineTimePartitionIterator; import org.apache.iotdb.db.storageengine.dataregion.utils.TreeDiskUsageStatisticUtil; +import org.apache.tsfile.common.conf.TSFileDescriptor; import org.apache.tsfile.read.common.block.TsBlock; import org.apache.tsfile.read.common.block.TsBlockBuilder; +import org.apache.tsfile.utils.RamUsageEstimator; import java.util.NoSuchElementException; import java.util.Optional; @@ -38,6 +41,9 @@ import java.util.concurrent.TimeUnit; public class ShowDiskUsageOperator implements SourceOperator { + private static final long INSTANCE_SIZE = + RamUsageEstimator.shallowSizeOfInstance(ShowDiskUsageOperator.class); + private final OperatorContext operatorContext; private final PlanNodeId sourceId; private final PartialPath pathPattern; @@ -131,12 +137,12 @@ public class ShowDiskUsageOperator implements SourceOperator { @Override public long calculateMaxPeekMemory() { - return 0; + return TSFileDescriptor.getInstance().getConfig().getMaxTsBlockSizeInBytes(); } @Override public long calculateMaxReturnSize() { - return 0; + return TSFileDescriptor.getInstance().getConfig().getMaxTsBlockSizeInBytes(); } @Override @@ -146,6 +152,11 @@ public class ShowDiskUsageOperator implements SourceOperator { @Override public long ramBytesUsed() { - return 0; + return INSTANCE_SIZE + + TreeDiskUsageStatisticUtil.SHALLOW_SIZE + + RamUsageEstimator.sizeOfObject(timePartitionIterator) + + MemoryEstimationHelper.getEstimatedSizeOfPartialPath(pathPattern) + + MemoryEstimationHelper.getEstimatedSizeOfAccountableObject(operatorContext) + + MemoryEstimationHelper.getEstimatedSizeOfAccountableObject(sourceId); } } diff --git a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/execution/operator/source/relational/InformationSchemaContentSupplierFactory.java b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/execution/operator/source/relational/InformationSchemaContentSupplierFactory.java index 270421900e1..34916639f40 100644 --- a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/execution/operator/source/relational/InformationSchemaContentSupplierFactory.java +++ b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/execution/operator/source/relational/InformationSchemaContentSupplierFactory.java @@ -79,7 +79,6 @@ import org.apache.iotdb.db.queryengine.plan.relational.security.AccessControl; import org.apache.iotdb.db.queryengine.plan.relational.sql.util.ReservedIdentifiers; import org.apache.iotdb.db.relational.grammar.sql.RelationalSqlKeywords; import org.apache.iotdb.db.schemaengine.table.InformationSchemaUtils; -import org.apache.iotdb.db.storageengine.StorageEngine; import org.apache.iotdb.db.storageengine.dataregion.DataRegion; import org.apache.iotdb.db.storageengine.dataregion.utils.StorageEngineTimePartitionIterator; import org.apache.iotdb.db.storageengine.dataregion.utils.TableDiskUsageStatisticUtil; @@ -99,6 +98,7 @@ import org.apache.tsfile.utils.Binary; import org.apache.tsfile.utils.BytesUtils; import org.apache.tsfile.utils.Pair; +import java.io.Closeable; import java.io.IOException; import java.util.ArrayList; import java.util.Arrays; @@ -136,7 +136,7 @@ import static org.apache.iotdb.db.queryengine.plan.execution.config.metadata.Sho public class InformationSchemaContentSupplierFactory { private InformationSchemaContentSupplierFactory() {} - public static Iterator<TsBlock> getSupplier( + public static IInformationSchemaContentSupplier getSupplier( final String tableName, final List<TSDataType> dataTypes, final UserEntity userEntity, @@ -178,7 +178,7 @@ public class InformationSchemaContentSupplierFactory { case InformationSchema.DATA_NODES: return new DataNodesSupplier(dataTypes, userEntity); case InformationSchema.TABLE_DISK_USAGE: - return new TableDiskUsageSupplier2(dataTypes, userEntity, pushDownFilter); + return new TableDiskUsageSupplier(dataTypes, userEntity, pushDownFilter); default: throw new UnsupportedOperationException("Unknown table: " + tableName); } @@ -187,6 +187,8 @@ public class InformationSchemaContentSupplierFactory { } } + public interface IInformationSchemaContentSupplier extends Iterator<TsBlock>, Closeable {} + private static class QueriesSupplier extends TsBlockSupplier { private final long currTime = System.currentTimeMillis(); // We initialize it later for the convenience of data preparation @@ -1236,163 +1238,7 @@ public class InformationSchemaContentSupplierFactory { } } - private static class TableDiskUsageSupplier implements Iterator<TsBlock> { - private final List<TSDataType> dataTypes; - private final Map<String, List<TTableInfo>> databaseTableInfoMap; - private final Filter pushDownFilter; - private final Iterator<DataRegion> dataRegionIterator; - - private DataRegion currentDataRegion; - private Iterator<Long> timePartitionsIterator; - private long currentTimePartition; - private List<String> currentTablesToScan; - private TableDiskUsageStatisticUtil statisticUtil; - - private TableDiskUsageSupplier( - final List<TSDataType> dataTypes, final UserEntity userEntity, Filter pushDownFilter) - throws TException, ClientManagerException { - this.dataTypes = dataTypes; - this.pushDownFilter = pushDownFilter; - AuthorityChecker.getAccessControl().checkUserGlobalSysPrivilege(userEntity); - try (final ConfigNodeClient client = - ConfigNodeClientManager.getInstance().borrowClient(ConfigNodeInfo.CONFIG_REGION_ID)) { - this.databaseTableInfoMap = client.showTables4InformationSchema().getDatabaseTableInfoMap(); - } - this.dataRegionIterator = StorageEngine.getInstance().getAllDataRegions().iterator(); - } - - @Override - public boolean hasNext() { - if (statisticUtil != null) { - return true; - } - try { - while (true) { - if (timePartitionsIterator != null && timePartitionsIterator.hasNext()) { - currentTimePartition = timePartitionsIterator.next(); - currentTablesToScan = getTablesToScan(currentTimePartition); - if (!currentTablesToScan.isEmpty()) { - statisticUtil = - new TableDiskUsageStatisticUtil( - currentDataRegion.getTsFileManager(), - currentTimePartition, - currentTablesToScan); - return true; - } - } else if (!nextDataRegion()) { - return false; - } // should not have else branch - } - } catch (Throwable t) { - closeStatisticUtil(); - throw t; - } - } - - private boolean nextDataRegion() { - while (dataRegionIterator.hasNext()) { - currentDataRegion = dataRegionIterator.next(); - if (currentDataRegion == null) { - continue; - } - - List<TTableInfo> tTableInfos = - databaseTableInfoMap.get(currentDataRegion.getDatabaseName()); - if (tTableInfos == null || tTableInfos.isEmpty()) { - continue; - } - - timePartitionsIterator = currentDataRegion.getTimePartitions().iterator(); - if (timePartitionsIterator.hasNext()) { - return true; - } - } - return false; - } - - private List<String> getTablesToScan(long timePartition) { - String databaseName = currentDataRegion.getDatabaseName(); - List<TTableInfo> tTableInfos = databaseTableInfoMap.get(databaseName); - if (tTableInfos == null || tTableInfos.isEmpty()) { - return Collections.emptyList(); - } - - if (pushDownFilter == null) { - return tTableInfos.stream().map(TTableInfo::getTableName).collect(Collectors.toList()); - } - - List<String> tablesToScan = new ArrayList<>(tTableInfos.size()); - for (TTableInfo tTableInfo : tTableInfos) { - Object[] row = new Object[5]; - row[0] = new Binary(currentDataRegion.getDatabaseName(), TSFileConfig.STRING_CHARSET); - row[1] = new Binary(tTableInfo.getTableName(), TSFileConfig.STRING_CHARSET); - row[2] = IoTDBDescriptor.getInstance().getConfig().getDataNodeId(); - row[3] = Integer.parseInt(currentDataRegion.getDataRegionId()); - row[4] = timePartition; - if (pushDownFilter.satisfyRow(0, row)) { - tablesToScan.add(tTableInfo.getTableName()); - } - } - return tablesToScan; - } - - @Override - public TsBlock next() { - try { - if (!hasNext()) { - throw new NoSuchElementException(); - } - - long maxRuntime = OperatorContext.getMaxRunTime().roundTo(TimeUnit.NANOSECONDS); - long start = System.nanoTime(); - - if (statisticUtil.hasNextFile()) { - do { - statisticUtil.calculateNextFile(); - } while (System.nanoTime() - start < maxRuntime && statisticUtil.hasNextFile()); - if (statisticUtil.hasNextFile()) { - return null; - } - } - - TsBlockBuilder builder = new TsBlockBuilder(dataTypes); - long[] resultArr = statisticUtil.getResult(); - - for (int i = 0; i < currentTablesToScan.size(); i++) { - builder.getTimeColumnBuilder().writeLong(0); - ColumnBuilder[] columns = builder.getValueColumnBuilders(); - - columns[0].writeBinary( - new Binary(currentDataRegion.getDatabaseName(), TSFileConfig.STRING_CHARSET)); - columns[1].writeBinary( - new Binary(currentTablesToScan.get(i), TSFileConfig.STRING_CHARSET)); - columns[2].writeInt(IoTDBDescriptor.getInstance().getConfig().getDataNodeId()); - columns[3].writeInt(Integer.parseInt(currentDataRegion.getDataRegionId())); - columns[4].writeLong(currentTimePartition); - columns[5].writeLong(resultArr[i]); - builder.declarePosition(); - } - closeStatisticUtil(); - return builder.build(); - } catch (Throwable t) { - closeStatisticUtil(); - throw t; - } - } - - private void closeStatisticUtil() { - if (statisticUtil == null) { - return; - } - try { - statisticUtil.close(); - statisticUtil = null; - } catch (IOException ignored) { - } - } - } - - private static class TableDiskUsageSupplier2 implements Iterator<TsBlock> { + private static class TableDiskUsageSupplier implements IInformationSchemaContentSupplier { private final List<TSDataType> dataTypes; private final Map<String, List<TTableInfo>> databaseTableInfoMap; private final Filter pushDownFilter; @@ -1404,7 +1250,7 @@ public class InformationSchemaContentSupplierFactory { private final StorageEngineTimePartitionIterator timePartitionIterator; - private TableDiskUsageSupplier2( + private TableDiskUsageSupplier( final List<TSDataType> dataTypes, final UserEntity userEntity, Filter pushDownFilter) throws TException, ClientManagerException { this.dataTypes = dataTypes; @@ -1437,7 +1283,6 @@ public class InformationSchemaContentSupplierFactory { if (statisticUtil != null) { return true; } - try { if (timePartitionIterator.next()) { currentDataRegion = timePartitionIterator.currentDataRegion(); @@ -1482,46 +1327,45 @@ public class InformationSchemaContentSupplierFactory { @Override public TsBlock next() { - try { - if (!hasNext()) { - throw new NoSuchElementException(); - } + if (!hasNext()) { + throw new NoSuchElementException(); + } - long maxRuntime = OperatorContext.getMaxRunTime().roundTo(TimeUnit.NANOSECONDS); - long start = System.nanoTime(); + long maxRuntime = OperatorContext.getMaxRunTime().roundTo(TimeUnit.NANOSECONDS); + long start = System.nanoTime(); + if (statisticUtil.hasNextFile()) { + do { + statisticUtil.calculateNextFile(); + } while (System.nanoTime() - start < maxRuntime && statisticUtil.hasNextFile()); if (statisticUtil.hasNextFile()) { - do { - statisticUtil.calculateNextFile(); - } while (System.nanoTime() - start < maxRuntime && statisticUtil.hasNextFile()); - if (statisticUtil.hasNextFile()) { - return null; - } + return null; } + } - TsBlockBuilder builder = new TsBlockBuilder(dataTypes); - long[] resultArr = statisticUtil.getResult(); - - for (int i = 0; i < currentTablesToScan.size(); i++) { - builder.getTimeColumnBuilder().writeLong(0); - ColumnBuilder[] columns = builder.getValueColumnBuilders(); - - columns[0].writeBinary( - new Binary(currentDataRegion.getDatabaseName(), TSFileConfig.STRING_CHARSET)); - columns[1].writeBinary( - new Binary(currentTablesToScan.get(i), TSFileConfig.STRING_CHARSET)); - columns[2].writeInt(IoTDBDescriptor.getInstance().getConfig().getDataNodeId()); - columns[3].writeInt(Integer.parseInt(currentDataRegion.getDataRegionId())); - columns[4].writeLong(currentTimePartition); - columns[5].writeLong(resultArr[i]); - builder.declarePosition(); - } - closeStatisticUtil(); - return builder.build(); - } catch (Throwable t) { - closeStatisticUtil(); - throw t; + TsBlockBuilder builder = new TsBlockBuilder(dataTypes); + long[] resultArr = statisticUtil.getResult(); + + for (int i = 0; i < currentTablesToScan.size(); i++) { + builder.getTimeColumnBuilder().writeLong(0); + ColumnBuilder[] columns = builder.getValueColumnBuilders(); + + columns[0].writeBinary( + new Binary(currentDataRegion.getDatabaseName(), TSFileConfig.STRING_CHARSET)); + columns[1].writeBinary(new Binary(currentTablesToScan.get(i), TSFileConfig.STRING_CHARSET)); + columns[2].writeInt(IoTDBDescriptor.getInstance().getConfig().getDataNodeId()); + columns[3].writeInt(Integer.parseInt(currentDataRegion.getDataRegionId())); + columns[4].writeLong(currentTimePartition); + columns[5].writeLong(resultArr[i]); + builder.declarePosition(); } + closeStatisticUtil(); + return builder.build(); + } + + @Override + public void close() throws IOException { + closeStatisticUtil(); } private void closeStatisticUtil() { @@ -1536,7 +1380,7 @@ public class InformationSchemaContentSupplierFactory { } } - private abstract static class TsBlockSupplier implements Iterator<TsBlock> { + private abstract static class TsBlockSupplier implements IInformationSchemaContentSupplier { protected final TsBlockBuilder resultBuilder; protected final ColumnBuilder[] columnBuilders; @@ -1565,5 +1409,10 @@ public class InformationSchemaContentSupplierFactory { } protected abstract void constructLine(); + + @Override + public void close() throws IOException { + // do nothing + } } } diff --git a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/execution/operator/source/relational/InformationSchemaTableScanOperator.java b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/execution/operator/source/relational/InformationSchemaTableScanOperator.java index 0b2c5275a1b..d8a625fb92b 100644 --- a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/execution/operator/source/relational/InformationSchemaTableScanOperator.java +++ b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/execution/operator/source/relational/InformationSchemaTableScanOperator.java @@ -28,15 +28,14 @@ import org.apache.tsfile.common.conf.TSFileDescriptor; import org.apache.tsfile.read.common.block.TsBlock; import org.apache.tsfile.utils.RamUsageEstimator; -import java.util.Iterator; - public class InformationSchemaTableScanOperator implements SourceOperator { private final OperatorContext operatorContext; private final PlanNodeId sourceId; - private final Iterator<TsBlock> contentSupplier; + private final InformationSchemaContentSupplierFactory.IInformationSchemaContentSupplier + contentSupplier; private static final int DEFAULT_MAX_TSBLOCK_SIZE_IN_BYTES = TSFileDescriptor.getInstance().getConfig().getMaxTsBlockSizeInBytes(); @@ -45,7 +44,9 @@ public class InformationSchemaTableScanOperator implements SourceOperator { RamUsageEstimator.shallowSizeOfInstance(InformationSchemaTableScanOperator.class); public InformationSchemaTableScanOperator( - OperatorContext operatorContext, PlanNodeId sourceId, Iterator<TsBlock> contentSupplier) { + OperatorContext operatorContext, + PlanNodeId sourceId, + InformationSchemaContentSupplierFactory.IInformationSchemaContentSupplier contentSupplier) { this.operatorContext = operatorContext; this.sourceId = sourceId; this.contentSupplier = contentSupplier; @@ -73,7 +74,9 @@ public class InformationSchemaTableScanOperator implements SourceOperator { @Override public void close() throws Exception { - // do nothing + if (contentSupplier != null) { + contentSupplier.close(); + } } @Override diff --git a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/storageengine/dataregion/utils/StorageEngineTimePartitionIterator.java b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/storageengine/dataregion/utils/StorageEngineTimePartitionIterator.java index 1546f6f1abe..8cae9ad0e2d 100644 --- a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/storageengine/dataregion/utils/StorageEngineTimePartitionIterator.java +++ b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/storageengine/dataregion/utils/StorageEngineTimePartitionIterator.java @@ -22,10 +22,16 @@ package org.apache.iotdb.db.storageengine.dataregion.utils; import org.apache.iotdb.db.storageengine.StorageEngine; import org.apache.iotdb.db.storageengine.dataregion.DataRegion; +import org.apache.tsfile.utils.Accountable; +import org.apache.tsfile.utils.RamUsageEstimator; + import java.util.Iterator; import java.util.Optional; -public class StorageEngineTimePartitionIterator { +public class StorageEngineTimePartitionIterator implements Accountable { + public static final long SHALLOW_SIZE = + RamUsageEstimator.shallowSizeOfInstance(StorageEngineTimePartitionIterator.class); + private final Iterator<DataRegion> dataRegionIterator; private final Optional<DataRegionFilterFunc> dataRegionFilter; private final Optional<TimePartitionFilterFunc> timePartitionFilter; @@ -81,6 +87,11 @@ public class StorageEngineTimePartitionIterator { return currentTimePartition; } + @Override + public long ramBytesUsed() { + return SHALLOW_SIZE; + } + @FunctionalInterface public interface DataRegionFilterFunc { boolean apply(DataRegion currentDataRegion) throws Exception; diff --git a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/storageengine/dataregion/utils/TableDiskUsageStatisticUtil.java b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/storageengine/dataregion/utils/TableDiskUsageStatisticUtil.java index c50be4caa98..43b93cdfe1d 100644 --- a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/storageengine/dataregion/utils/TableDiskUsageStatisticUtil.java +++ b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/storageengine/dataregion/utils/TableDiskUsageStatisticUtil.java @@ -29,6 +29,7 @@ import org.apache.tsfile.file.metadata.TsFileMetadata; import org.apache.tsfile.read.TsFileDeviceIterator; import org.apache.tsfile.read.TsFileSequenceReader; import org.apache.tsfile.utils.Pair; +import org.apache.tsfile.utils.RamUsageEstimator; import java.io.IOException; import java.util.HashMap; @@ -37,6 +38,8 @@ import java.util.List; import java.util.Map; public class TableDiskUsageStatisticUtil extends DiskUsageStatisticUtil { + public static final long SHALLOW_SIZE = + RamUsageEstimator.shallowSizeOfInstance(TableDiskUsageStatisticUtil.class); private final Map<String, Integer> tableIndexMap; private final long[] resultArr; diff --git a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/storageengine/dataregion/utils/TreeDiskUsageStatisticUtil.java b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/storageengine/dataregion/utils/TreeDiskUsageStatisticUtil.java index 0aa4da37e67..54687edda36 100644 --- a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/storageengine/dataregion/utils/TreeDiskUsageStatisticUtil.java +++ b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/storageengine/dataregion/utils/TreeDiskUsageStatisticUtil.java @@ -19,6 +19,7 @@ package org.apache.iotdb.db.storageengine.dataregion.utils; +import org.apache.iotdb.commons.conf.IoTDBConstant; import org.apache.iotdb.commons.exception.IllegalPathException; import org.apache.iotdb.commons.path.PartialPath; import org.apache.iotdb.db.storageengine.dataregion.compaction.execute.utils.CompactionPathUtils; @@ -30,21 +31,38 @@ import org.apache.tsfile.file.metadata.MetadataIndexNode; import org.apache.tsfile.read.TsFileDeviceIterator; import org.apache.tsfile.read.TsFileSequenceReader; import org.apache.tsfile.utils.Pair; +import org.apache.tsfile.utils.RamUsageEstimator; import java.io.IOException; public class TreeDiskUsageStatisticUtil extends DiskUsageStatisticUtil { + public static final long SHALLOW_SIZE = + RamUsageEstimator.shallowSizeOfInstance(TreeDiskUsageStatisticUtil.class); + private final PartialPath pathPattern; - private final boolean isPrefixPathPattern; + private final boolean isMatchedDeviceSequential; private long result; public TreeDiskUsageStatisticUtil( TsFileManager tsFileManager, long timePartition, PartialPath pathPattern) { super(tsFileManager, timePartition); this.pathPattern = pathPattern; - this.isPrefixPathPattern = pathPattern.isPrefixPath(); this.result = 0; + String[] nodes = pathPattern.getNodes(); + boolean hasWildcardInPath = false; + for (int i = 0; i < nodes.length; i++) { + if (nodes[i].equals(IoTDBConstant.ONE_LEVEL_PATH_WILDCARD) + || nodes[i].equals(IoTDBConstant.MULTI_LEVEL_PATH_WILDCARD)) { + hasWildcardInPath = true; + continue; + } + if (hasWildcardInPath) { + this.isMatchedDeviceSequential = false; + return; + } + } + this.isMatchedDeviceSequential = true; } @Override @@ -85,7 +103,7 @@ public class TreeDiskUsageStatisticUtil extends DiskUsageStatisticUtil { nodeOfFirstMatchedDevice, nextNotMatchedDevice, nodeOfNextNotMatchedDevice); - if (isPrefixPathPattern) { + if (isMatchedDeviceSequential) { break; } }
