This is an automated email from the ASF dual-hosted git repository. haonan pushed a commit to branch delete_object_file in repository https://gitbox.apache.org/repos/asf/iotdb.git
commit 5fa057d4b4b1814a9bedaa6744c0c891f72371d3 Author: HTHou <[email protected]> AuthorDate: Thu Dec 18 12:19:32 2025 +0800 optimize drop table --- .../db/storageengine/dataregion/DataRegion.java | 109 +++++++++++---------- .../dataregion/modification/DeletionPredicate.java | 4 + .../modification/TableDeletionEntry.java | 9 ++ .../db/storageengine/rescon/disk/TierManager.java | 11 +++ 4 files changed, 82 insertions(+), 51 deletions(-) diff --git a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/storageengine/dataregion/DataRegion.java b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/storageengine/dataregion/DataRegion.java index 27a290b60fd..8de74e066ab 100644 --- a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/storageengine/dataregion/DataRegion.java +++ b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/storageengine/dataregion/DataRegion.java @@ -2766,10 +2766,21 @@ public class DataRegion implements IDataRegionForQuery { } } - List<File> matchedObjectDirs = + List<File> objectTableDirs = TierManager.getInstance().getAllMatchedObjectDirs(dataRegionIdString, tableName); - if (!matchedObjectDirs.isEmpty()) { - deleteObjectFiles(matchedObjectDirs, modEntries); + if (!objectTableDirs.isEmpty()) { + boolean droppingTable = false; + for (TableDeletionEntry entry : modEntries) { + if (entry.isDroppingTable()) { + for (File objectTableDir : objectTableDirs) { + droppingTable = true; + FileUtils.deleteQuietly(objectTableDir); + } + } + } + if (!droppingTable) { + deleteObjectFiles(objectTableDirs, modEntries); + } } List<List<TsFileResource>> sealedTsFileResourceLists = new ArrayList<>(modEntries.size()); @@ -2943,54 +2954,50 @@ public class DataRegion implements IDataRegionForQuery { private void deleteObjectFiles(List<File> matchedObjectDirs, List<TableDeletionEntry> modEntries) throws IOException { for (File matchedObjectDir : matchedObjectDirs) { - try (Stream<Path> paths = Files.walk(matchedObjectDir.toPath())) { - paths - .filter(Files::isRegularFile) - .filter( - path -> { - String name = path.getFileName().toString(); - return name.endsWith(".bin"); - }) - .forEach( - path -> { - Path relativePath = matchedObjectDir.getParentFile().toPath().relativize(path); - String[] ideviceIdSegments = new String[relativePath.getNameCount() - 2]; - for (int i = 0; i < ideviceIdSegments.length; i++) { - ideviceIdSegments[i] = - config.getRestrictObjectLimit() - ? relativePath.getName(i).toString() - : new String( - BaseEncoding.base32() - .omitPadding() - .decode(relativePath.getName(i).toString()), - StandardCharsets.UTF_8); - } - IDeviceID iDeviceID = Factory.DEFAULT_FACTORY.create(ideviceIdSegments); - String measurementId = - config.getRestrictObjectLimit() - ? relativePath.getName(relativePath.getNameCount() - 2).toString() - : new String( - BaseEncoding.base32() - .omitPadding() - .decode( - relativePath - .getName(relativePath.getNameCount() - 2) - .toString()), - StandardCharsets.UTF_8); - String fileName = path.getFileName().toString(); - long timestamp = Long.parseLong(fileName.substring(0, fileName.lastIndexOf('.'))); - logger.info( - "timestamp {}, measurementId {}, ideviceId {}", - timestamp, - measurementId, - iDeviceID); - for (TableDeletionEntry modEntry : modEntries) { - if (modEntry.affects(iDeviceID, timestamp, timestamp) - && modEntry.affects(measurementId)) { - ObjectTypeUtils.deleteObjectPath(path.toFile()); - } - } - }); + try (Stream<Path> paths = + Files.find( + matchedObjectDir.toPath(), + Integer.MAX_VALUE, + (path, attrs) -> + attrs.isRegularFile() && path.getFileName().toString().endsWith(".bin"))) { + paths.forEach( + path -> { + Path relativePath = matchedObjectDir.getParentFile().toPath().relativize(path); + String[] ideviceIdSegments = new String[relativePath.getNameCount() - 2]; + for (int i = 0; i < ideviceIdSegments.length; i++) { + ideviceIdSegments[i] = + config.getRestrictObjectLimit() + ? relativePath.getName(i).toString() + : new String( + BaseEncoding.base32() + .omitPadding() + .decode(relativePath.getName(i).toString()), + StandardCharsets.UTF_8); + } + IDeviceID iDeviceID = Factory.DEFAULT_FACTORY.create(ideviceIdSegments); + String measurementId = + config.getRestrictObjectLimit() + ? relativePath.getName(relativePath.getNameCount() - 2).toString() + : new String( + BaseEncoding.base32() + .omitPadding() + .decode( + relativePath.getName(relativePath.getNameCount() - 2).toString()), + StandardCharsets.UTF_8); + String fileName = path.getFileName().toString(); + long timestamp = Long.parseLong(fileName.substring(0, fileName.lastIndexOf('.'))); + logger.info( + "timestamp {}, measurementId {}, ideviceId {}", + timestamp, + measurementId, + iDeviceID); + for (TableDeletionEntry modEntry : modEntries) { + if (modEntry.affects(iDeviceID, timestamp, timestamp) + && modEntry.affects(measurementId)) { + ObjectTypeUtils.deleteObjectPath(path.toFile()); + } + } + }); } } } diff --git a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/storageengine/dataregion/modification/DeletionPredicate.java b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/storageengine/dataregion/modification/DeletionPredicate.java index 7e79e8f580d..0a22da2a90a 100644 --- a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/storageengine/dataregion/modification/DeletionPredicate.java +++ b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/storageengine/dataregion/modification/DeletionPredicate.java @@ -72,6 +72,10 @@ public class DeletionPredicate implements StreamSerializable, BufferSerializable this.idPredicate = idPredicate; } + public IDPredicate getIdPredicate() { + return idPredicate; + } + public String getTableName() { return tableName; } diff --git a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/storageengine/dataregion/modification/TableDeletionEntry.java b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/storageengine/dataregion/modification/TableDeletionEntry.java index 858b6645b2f..61ec2e0d678 100644 --- a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/storageengine/dataregion/modification/TableDeletionEntry.java +++ b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/storageengine/dataregion/modification/TableDeletionEntry.java @@ -21,6 +21,7 @@ package org.apache.iotdb.db.storageengine.dataregion.modification; import org.apache.iotdb.commons.conf.IoTDBConstant; import org.apache.iotdb.commons.path.PartialPath; import org.apache.iotdb.db.queryengine.execution.MemoryEstimationHelper; +import org.apache.iotdb.db.storageengine.dataregion.modification.IDPredicate.IDPredicateType; import org.apache.iotdb.db.utils.ModificationUtils; import org.apache.tsfile.file.metadata.IDeviceID; @@ -136,6 +137,14 @@ public class TableDeletionEntry extends ModEntry { return predicate.getTableName(); } + public boolean isDroppingTable() { + IDPredicate idPredicate = predicate.getIdPredicate(); + return idPredicate.type == IDPredicateType.NOP + && predicate.getMeasurementNames().isEmpty() + && timeRange.getMin() == Long.MIN_VALUE + && timeRange.getMax() == Long.MAX_VALUE; + } + @Override public boolean equals(Object o) { if (this == o) { diff --git a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/storageengine/rescon/disk/TierManager.java b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/storageengine/rescon/disk/TierManager.java index 3aff31a9631..f83bdc36b4b 100644 --- a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/storageengine/rescon/disk/TierManager.java +++ b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/storageengine/rescon/disk/TierManager.java @@ -287,6 +287,17 @@ public class TierManager { public List<File> getAllMatchedObjectDirs(String regionIdStr, String... path) { List<File> matchedDirs = new ArrayList<>(); + boolean hasObjectDir = false; + for (String objectDir : objectDirs) { + File objectDirPath = FSFactoryProducer.getFSFactory().getFile(objectDir); + if (objectDirPath.exists()) { + hasObjectDir = true; + break; + } + } + if (!hasObjectDir) { + return matchedDirs; + } StringBuilder objectPath = new StringBuilder(); objectPath.append(regionIdStr); for (String str : path) {
