diff --git a/core/src/main/java/org/apache/iceberg/CachingCatalog.java b/core/src/main/java/org/apache/iceberg/CachingCatalog.java index 5c92fe7db602..20c26eb5c5da 100644 --- a/core/src/main/java/org/apache/iceberg/CachingCatalog.java +++ b/core/src/main/java/org/apache/iceberg/CachingCatalog.java @@ -95,7 +95,7 @@ class MetadataTableInvalidatingRemovalListener @Override public void onRemoval(TableIdentifier tableIdentifier, Table table, RemovalCause cause) { LOG.debug("Evicted {} from the table cache ({})", tableIdentifier, cause); - if (RemovalCause.EXPIRED.equals(cause)) { + if (cause.wasEvicted()) { if (!MetadataTableUtils.hasMetadataTableName(tableIdentifier)) { tableCache.invalidateAll(metadataTableIdentifiers(tableIdentifier)); } diff --git a/core/src/test/java/org/apache/iceberg/hadoop/TestCachingCatalog.java b/core/src/test/java/org/apache/iceberg/hadoop/TestCachingCatalog.java index 1c36c1acea2e..d094121dd5cc 100644 --- a/core/src/test/java/org/apache/iceberg/hadoop/TestCachingCatalog.java +++ b/core/src/test/java/org/apache/iceberg/hadoop/TestCachingCatalog.java @@ -20,6 +20,9 @@ import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatThrownBy; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; import com.github.benmanes.caffeine.cache.Cache; import java.io.IOException; @@ -43,6 +46,7 @@ import org.apache.iceberg.catalog.Namespace; import org.apache.iceberg.catalog.TableIdentifier; import org.apache.iceberg.exceptions.NoSuchTableException; +import org.apache.iceberg.io.FileIO; import org.apache.iceberg.relocated.com.google.common.collect.ImmutableMap; import org.apache.iceberg.relocated.com.google.common.collect.Lists; import org.apache.iceberg.util.FakeTicker; @@ -436,6 +440,29 @@ public void testRegisterTableWithOverwriteInvalidatesCache() throws Exception { assertThat(catalog.cache().asMap()).doesNotContainKey(targetIdent); } + @Test + public void testFileIOClosedOnCacheEviction() throws IOException { + FileIO mockIO = mock(FileIO.class); + Table mockTable = mock(Table.class); + TableIdentifier tableIdent = TableIdentifier.of("db", "tbl"); + + Catalog mockCatalog = mock(Catalog.class); + when(mockCatalog.loadTable(tableIdent)).thenReturn(mockTable); + when(mockTable.io()).thenReturn(mockIO); + + TestableCachingCatalog catalog = + TestableCachingCatalog.wrap(mockCatalog, EXPIRATION_TTL, ticker); + + catalog.loadTable(tableIdent); + assertThat(catalog.cache().asMap()).containsKey(tableIdent); + + ticker.advance(EXPIRATION_TTL.plus(Duration.ofSeconds(1))); + catalog.cache().cleanUp(); + + assertThat(catalog.cache().asMap()).doesNotContainKey(tableIdent); + verify(mockIO).close(); + } + public static TableIdentifier[] metadataTables(TableIdentifier tableIdent) { return Arrays.stream(MetadataTableType.values()) .map(type -> TableIdentifier.parse(tableIdent + "." + type.name().toLowerCase(Locale.ROOT)))