From f95ac5063f18d23e90f411bfc8678253ffe0f3c4 Mon Sep 17 00:00:00 2001 From: shuwenwei Date: Fri, 17 Jul 2026 12:13:42 +0800 Subject: [PATCH] Compatibility changes for internal settle compaction API --- .../selector/impl/SettleSelectorImpl.java | 43 +++++++++++++++---- 1 file changed, 34 insertions(+), 9 deletions(-) diff --git a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/storageengine/dataregion/compaction/selector/impl/SettleSelectorImpl.java b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/storageengine/dataregion/compaction/selector/impl/SettleSelectorImpl.java index cef6084d1aebb..b08c032d483ce 100644 --- a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/storageengine/dataregion/compaction/selector/impl/SettleSelectorImpl.java +++ b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/storageengine/dataregion/compaction/selector/impl/SettleSelectorImpl.java @@ -71,6 +71,7 @@ public class SettleSelectorImpl implements ISettleSelector { private final TsFileManager tsFileManager; private boolean isSeq; private final CompactionScheduleContext context; + private final boolean ttlAuditEnabled; public SettleSelectorImpl( boolean heavySelect, @@ -85,19 +86,28 @@ public SettleSelectorImpl( this.timePartition = timePartition; this.tsFileManager = tsFileManager; this.context = context; + // this will be enabled in other branches + this.ttlAuditEnabled = false; } static class FileDirtyInfo { DirtyStatus status; long dirtyDataSize = 0; + Set ttlTables = Collections.emptySet(); public FileDirtyInfo(DirtyStatus status) { this.status = status; } - public FileDirtyInfo(DirtyStatus status, long dirtyDataSize) { + public FileDirtyInfo(DirtyStatus status, Set ttlTables) { + this.status = status; + this.ttlTables = ttlTables; + } + + public FileDirtyInfo(DirtyStatus status, long dirtyDataSize, Set ttlTables) { this.status = status; this.dirtyDataSize = dirtyDataSize; + this.ttlTables = ttlTables; } } @@ -106,15 +116,19 @@ static class SettleTaskResource { List fullyDirtyResources = new ArrayList<>(); List partiallyDirtyResources = new ArrayList<>(); long totalPartiallyDirtyFileSize = 0; + final Set ttlTables = new HashSet<>(); - public void addFullyDirtyResource(TsFileResource resource) { + public void addFullyDirtyResource(TsFileResource resource, Set fileTTLTables) { fullyDirtyResources.add(resource); + ttlTables.addAll(fileTTLTables); } - public boolean addPartiallyDirtyResource(TsFileResource resource, long dirtyDataSize) { + public boolean addPartiallyDirtyResource( + TsFileResource resource, long dirtyDataSize, Set fileTTLTables) { partiallyDirtyResources.add(resource); totalPartiallyDirtyFileSize += resource.getTsFileSize(); totalPartiallyDirtyFileSize -= dirtyDataSize; + ttlTables.addAll(fileTTLTables); return checkHasReachedThreshold(); } @@ -126,6 +140,10 @@ public List getPartiallyDirtyResources() { return partiallyDirtyResources; } + public Set getTTLTables() { + return ttlTables; + } + public boolean checkHasReachedThreshold() { return partiallyDirtyResources.size() >= config.getInnerCompactionCandidateFileNum() || totalPartiallyDirtyFileSize >= config.getTargetCompactionFileSize(); @@ -165,11 +183,12 @@ private List selectTasks(List resources) { switch (fileDirtyInfo.status) { case FULLY_DIRTY: - settleTaskResource.addFullyDirtyResource(resource); + settleTaskResource.addFullyDirtyResource(resource, fileDirtyInfo.ttlTables); break; case PARTIALLY_DIRTY: shouldStop = - settleTaskResource.addPartiallyDirtyResource(resource, fileDirtyInfo.dirtyDataSize); + settleTaskResource.addPartiallyDirtyResource( + resource, fileDirtyInfo.dirtyDataSize, fileDirtyInfo.ttlTables); break; case NOT_SATISFIED: shouldStop = !settleTaskResource.getPartiallyDirtyResources().isEmpty(); @@ -231,6 +250,7 @@ private FileDirtyInfo selectFileBaseOnDirtyData(TsFileResource resource) timeIndex = CompactionUtils.buildDeviceTimeIndex(resource); } Set deletedDevices = new HashSet<>(); + Set ttlTables = new HashSet<>(); boolean hasExpiredTooLong = false; long currentTime = CommonDateTimeUtils.currentTime(); @@ -240,12 +260,17 @@ private FileDirtyInfo selectFileBaseOnDirtyData(TsFileResource resource) long ttl; String tableName = device.getTableName(); + boolean hasSetTTL; if (tableName.startsWith("root.")) { ttl = DataNodeTTLCache.getInstance().getTTLForTree(device); + hasSetTTL = ttl != Long.MAX_VALUE; } else { ttl = DataNodeTTLCache.getInstance().getTTLForTable(storageGroupName, tableName); + hasSetTTL = ttl != Long.MAX_VALUE; + if (hasSetTTL && ttlAuditEnabled) { + ttlTables.add(tableName); + } } - boolean hasSetTTL = ttl != Long.MAX_VALUE; long endTime = timeIndex.getEndTime(device).get(); boolean isDeleted = @@ -256,7 +281,7 @@ private FileDirtyInfo selectFileBaseOnDirtyData(TsFileResource resource) if (!isDeleted) { // For devices with TTL set, all data must expire in order to meet the conditions for // being selected. - return new FileDirtyInfo(DirtyStatus.NOT_SATISFIED); + return new FileDirtyInfo(DirtyStatus.NOT_SATISFIED, ttlTables); } if (currentTime > endTime) { @@ -281,13 +306,13 @@ private FileDirtyInfo selectFileBaseOnDirtyData(TsFileResource resource) ((double) deletedDevices.size()) / ((ArrayDeviceTimeIndex) timeIndex).getDevices().size(); if (deletedDeviceRatio == 1d) { // the whole file is completely dirty - return new FileDirtyInfo(DirtyStatus.FULLY_DIRTY); + return new FileDirtyInfo(DirtyStatus.FULLY_DIRTY, ttlTables); } hasExpiredTooLong = config.getMaxExpiredTime() != Long.MAX_VALUE && hasExpiredTooLong; if (hasExpiredTooLong || deletedDeviceRatio >= config.getExpiredDataRatio()) { // evaluate dirty data size in the tsfile return new FileDirtyInfo( - PARTIALLY_DIRTY, (long) (deletedDeviceRatio * resource.getTsFileSize())); + PARTIALLY_DIRTY, (long) (deletedDeviceRatio * resource.getTsFileSize()), ttlTables); } return new FileDirtyInfo(DirtyStatus.NOT_SATISFIED); }