diff --git a/fluss-client/src/main/java/org/apache/fluss/client/write/WriterClient.java b/fluss-client/src/main/java/org/apache/fluss/client/write/WriterClient.java index b4c96b0ac4..19df2ff6fa 100644 --- a/fluss-client/src/main/java/org/apache/fluss/client/write/WriterClient.java +++ b/fluss-client/src/main/java/org/apache/fluss/client/write/WriterClient.java @@ -176,10 +176,15 @@ private void doSend(WriteRecord record, WriteCallback callback) { TableInfo tableInfo = record.getTableInfo(); PhysicalTablePath physicalTablePath = record.getPhysicalTablePath(); - dynamicPartitionCreator.checkAndCreatePartitionAsync( - physicalTablePath, - tableInfo.getPartitionKeys(), - tableInfo.getTableConfig().getAutoPartitionStrategy()); + // Skip on non-partitioned tables: the callee returns immediately when + // partitionName is null, but the expensive AutoPartitionStrategy argument + // would still be evaluated per record without this guard. + if (tableInfo.isPartitioned()) { + dynamicPartitionCreator.checkAndCreatePartitionAsync( + physicalTablePath, + tableInfo.getPartitionKeys(), + tableInfo.getTableConfig().getAutoPartitionStrategy()); + } // maybe create bucket assigner. Cluster cluster = metadataUpdater.getCluster(); diff --git a/fluss-common/src/main/java/org/apache/fluss/config/TableConfig.java b/fluss-common/src/main/java/org/apache/fluss/config/TableConfig.java index fbf8c77264..4c2e39f779 100644 --- a/fluss-common/src/main/java/org/apache/fluss/config/TableConfig.java +++ b/fluss-common/src/main/java/org/apache/fluss/config/TableConfig.java @@ -44,6 +44,11 @@ public class TableConfig { // the table properties configuration private final Configuration config; + // Cached, lazily-built strategy. Safe because TableConfig is immutable after construction + // and AutoPartitionStrategy itself is fully immutable. A benign race on first call + // produces the same value, so a plain volatile is sufficient. + private volatile AutoPartitionStrategy autoPartitionStrategy; + /** * Creates a new table config. * @@ -156,9 +161,19 @@ public ArrowCompressionInfo getArrowCompressionInfo() { return ArrowCompressionInfo.fromConf(config); } - /** Gets the auto partition strategy of the table. */ + /** + * Gets the auto partition strategy of the table. + * + *

The result is cached on first access; this assumes the underlying config is not mutated + * after this {@code TableConfig} is constructed. + */ public AutoPartitionStrategy getAutoPartitionStrategy() { - return AutoPartitionStrategy.from(config); + AutoPartitionStrategy s = autoPartitionStrategy; + if (s == null) { + s = AutoPartitionStrategy.from(config); + autoPartitionStrategy = s; + } + return s; } /** Gets the number of auto-increment IDs cached per segment. */ diff --git a/fluss-common/src/test/java/org/apache/fluss/config/TableConfigTest.java b/fluss-common/src/test/java/org/apache/fluss/config/TableConfigTest.java index 5d18fcd1c9..c77c9a3913 100644 --- a/fluss-common/src/test/java/org/apache/fluss/config/TableConfigTest.java +++ b/fluss-common/src/test/java/org/apache/fluss/config/TableConfigTest.java @@ -44,4 +44,13 @@ void testDeleteBehavior() { TableConfig tableConfig3 = new TableConfig(conf); assertThat(tableConfig3.getDeleteBehavior()).hasValue(DeleteBehavior.IGNORE); } + + @Test + void testAutoPartitionStrategyIsCached() { + TableConfig tableConfig = new TableConfig(new Configuration()); + + // the strategy is memoized, so repeated calls return the same instance + assertThat(tableConfig.getAutoPartitionStrategy()) + .isSameAs(tableConfig.getAutoPartitionStrategy()); + } }