diff --git a/.mvn/modernizer/violations.xml b/.mvn/modernizer/violations.xml
index 444193e5a1d1..2b3bf519ec6f 100644
--- a/.mvn/modernizer/violations.xml
+++ b/.mvn/modernizer/violations.xml
@@ -43,6 +43,22 @@
Prefer Math.toIntExact(long)
+
+ com/google/common/cache/CacheBuilder.build:()Lcom/google/common/cache/Cache;
+ 1.8
+ Guava Cache has concurrency issues around invalidation and ongoing loads. Use EvictableCache, EvictableLoadingCache, or SafeCaches to build caches.
+ See https://github.com/trinodb/trino/issues/10512 for more information and see https://github.com/trinodb/trino/issues/10512#issuecomment-1016221168
+ for why Caffeine does not solve the problem.
+
+
+
+ com/google/common/cache/CacheBuilder.build:(Lcom/google/common/cache/CacheLoader;)Lcom/google/common/cache/LoadingCache;
+ 1.8
+ Guava LoadingCache has concurrency issues around invalidation and ongoing loads. Use EvictableCache, EvictableLoadingCache, or SafeCaches to build caches.
+ See https://github.com/trinodb/trino/issues/10512 for more information and see https://github.com/trinodb/trino/issues/10512#issuecomment-1016221168
+ for why Caffeine does not solve the problem.
+
+
org/testng/Assert.assertEquals:(Ljava/lang/Iterable;Ljava/lang/Iterable;)V
1.8
diff --git a/client/trino-cli/pom.xml b/client/trino-cli/pom.xml
index 3b1d1fa730ec..50739e7502d7 100644
--- a/client/trino-cli/pom.xml
+++ b/client/trino-cli/pom.xml
@@ -76,6 +76,11 @@
antlr4-runtime
+
+ org.gaul
+ modernizer-maven-annotations
+
+
org.jline
jline-reader
diff --git a/client/trino-cli/src/main/java/io/trino/cli/TableNameCompleter.java b/client/trino-cli/src/main/java/io/trino/cli/TableNameCompleter.java
index 003fd1b09c91..0029f0f07566 100644
--- a/client/trino-cli/src/main/java/io/trino/cli/TableNameCompleter.java
+++ b/client/trino-cli/src/main/java/io/trino/cli/TableNameCompleter.java
@@ -20,6 +20,7 @@
import com.google.common.util.concurrent.ThreadFactoryBuilder;
import io.trino.client.QueryData;
import io.trino.client.StatementClient;
+import org.gaul.modernizer_maven_annotations.SuppressModernizer;
import org.jline.reader.Candidate;
import org.jline.reader.Completer;
import org.jline.reader.LineReader;
@@ -51,12 +52,21 @@ public TableNameCompleter(QueryRunner queryRunner)
{
this.queryRunner = requireNonNull(queryRunner, "queryRunner session was null!");
- tableCache = CacheBuilder.newBuilder()
- .refreshAfterWrite(RELOAD_TIME_MINUTES, TimeUnit.MINUTES)
- .build(asyncReloading(CacheLoader.from(this::listTables), executor));
+ tableCache = buildUnsafeCache(
+ CacheBuilder.newBuilder()
+ .refreshAfterWrite(RELOAD_TIME_MINUTES, TimeUnit.MINUTES),
+ asyncReloading(CacheLoader.from(this::listTables), executor));
- functionCache = CacheBuilder.newBuilder()
- .build(CacheLoader.from(this::listFunctions));
+ functionCache = buildUnsafeCache(
+ CacheBuilder.newBuilder(),
+ CacheLoader.from(this::listFunctions));
+ }
+
+ // TODO extract safe caches implementations to a new module and use SafeCaches.buildNonEvictableCache hereAsyncCache
+ @SuppressModernizer
+ private static LoadingCache buildUnsafeCache(CacheBuilder super K, ? super V> cacheBuilder, CacheLoader super K, V> cacheLoader)
+ {
+ return cacheBuilder.build(cacheLoader);
}
private List listTables(String schemaName)
diff --git a/core/trino-main/pom.xml b/core/trino-main/pom.xml
index 09dd8fc2ee7c..9ac55e29fc4e 100644
--- a/core/trino-main/pom.xml
+++ b/core/trino-main/pom.xml
@@ -299,6 +299,11 @@
8.4.1
+
+ org.gaul
+ modernizer-maven-annotations
+
+
org.jgrapht
jgrapht-core
diff --git a/core/trino-main/src/main/java/io/trino/execution/FailureInjector.java b/core/trino-main/src/main/java/io/trino/execution/FailureInjector.java
index 43b74ce2cbd2..a6af6aac92fb 100644
--- a/core/trino-main/src/main/java/io/trino/execution/FailureInjector.java
+++ b/core/trino-main/src/main/java/io/trino/execution/FailureInjector.java
@@ -13,9 +13,9 @@
*/
package io.trino.execution;
-import com.google.common.cache.Cache;
import com.google.common.cache.CacheBuilder;
import io.airlift.units.Duration;
+import io.trino.plugin.base.cache.NonEvictableCache;
import io.trino.spi.ErrorCode;
import io.trino.spi.ErrorCodeSupplier;
import io.trino.spi.ErrorType;
@@ -29,6 +29,7 @@
import static com.google.common.base.MoreObjects.toStringHelper;
import static com.google.common.base.Preconditions.checkArgument;
import static io.trino.execution.FailureInjector.InjectedFailureType.TASK_FAILURE;
+import static io.trino.plugin.base.cache.SafeCaches.buildNonEvictableCache;
import static io.trino.spi.ErrorType.EXTERNAL;
import static io.trino.spi.ErrorType.INSUFFICIENT_RESOURCES;
import static io.trino.spi.ErrorType.INTERNAL_ERROR;
@@ -40,7 +41,7 @@ public class FailureInjector
{
public static final String FAILURE_INJECTION_MESSAGE = "This error is injected by the failure injection service";
- private final Cache failures;
+ private final NonEvictableCache failures;
private final Duration requestTimeout;
@Inject
@@ -53,9 +54,8 @@ public FailureInjector(FailureInjectionConfig config)
public FailureInjector(Duration expirationPeriod, Duration requestTimeout)
{
- failures = CacheBuilder.newBuilder()
- .expireAfterWrite(expirationPeriod.toMillis(), MILLISECONDS)
- .build();
+ failures = buildNonEvictableCache(CacheBuilder.newBuilder()
+ .expireAfterWrite(expirationPeriod.toMillis(), MILLISECONDS));
this.requestTimeout = requireNonNull(requestTimeout, "requestTimeout is null");
}
diff --git a/core/trino-main/src/main/java/io/trino/execution/SqlTaskManager.java b/core/trino-main/src/main/java/io/trino/execution/SqlTaskManager.java
index 143841d5071c..564db52e75b4 100644
--- a/core/trino-main/src/main/java/io/trino/execution/SqlTaskManager.java
+++ b/core/trino-main/src/main/java/io/trino/execution/SqlTaskManager.java
@@ -16,7 +16,6 @@
import com.google.common.annotations.VisibleForTesting;
import com.google.common.cache.CacheBuilder;
import com.google.common.cache.CacheLoader;
-import com.google.common.cache.LoadingCache;
import com.google.common.collect.ImmutableList;
import com.google.common.util.concurrent.ListenableFuture;
import io.airlift.concurrent.ThreadPoolExecutorMBean;
@@ -41,6 +40,7 @@
import io.trino.memory.MemoryPoolAssignmentsRequest;
import io.trino.memory.NodeMemoryConfig;
import io.trino.memory.QueryContext;
+import io.trino.plugin.base.cache.NonEvictableLoadingCache;
import io.trino.spi.QueryId;
import io.trino.spi.TrinoException;
import io.trino.spi.VersionEmbedder;
@@ -81,6 +81,7 @@
import static io.trino.execution.SqlTask.createSqlTask;
import static io.trino.memory.LocalMemoryManager.GENERAL_POOL;
import static io.trino.memory.LocalMemoryManager.RESERVED_POOL;
+import static io.trino.plugin.base.cache.SafeCaches.buildNonEvictableCache;
import static io.trino.spi.StandardErrorCode.ABANDONED_TASK;
import static io.trino.spi.StandardErrorCode.SERVER_SHUTTING_DOWN;
import static java.lang.Math.min;
@@ -105,8 +106,8 @@ public class SqlTaskManager
private final Duration clientTimeout;
private final LocalMemoryManager localMemoryManager;
- private final LoadingCache queryContexts;
- private final LoadingCache tasks;
+ private final NonEvictableLoadingCache queryContexts;
+ private final NonEvictableLoadingCache tasks;
private final SqlTaskIoStats cachedStats = new SqlTaskIoStats();
private final SqlTaskIoStats finishedTaskStats = new SqlTaskIoStats();
@@ -165,10 +166,10 @@ public SqlTaskManager(
queryMaxMemoryPerNode = maxQueryMemoryPerNode.toBytes();
queryMaxTotalMemoryPerNode = maxQueryTotalMemoryPerNode.toBytes();
- queryContexts = CacheBuilder.newBuilder().weakValues().build(CacheLoader.from(
+ queryContexts = buildNonEvictableCache(CacheBuilder.newBuilder().weakValues(), CacheLoader.from(
queryId -> createQueryContext(queryId, localMemoryManager, localSpillManager, gcMonitor, maxQueryMemoryPerNode, maxQueryTotalMemoryPerNode, queryMaxMemoryPerTask, maxQuerySpillPerNode)));
- tasks = CacheBuilder.newBuilder().build(CacheLoader.from(
+ tasks = buildNonEvictableCache(CacheBuilder.newBuilder(), CacheLoader.from(
taskId -> createSqlTask(
taskId,
locationFactory.createLocalTaskLocation(taskId),
diff --git a/core/trino-main/src/main/java/io/trino/execution/scheduler/TopologyAwareNodeSelectorFactory.java b/core/trino-main/src/main/java/io/trino/execution/scheduler/TopologyAwareNodeSelectorFactory.java
index 1824a85b935e..e8efe86db40f 100644
--- a/core/trino-main/src/main/java/io/trino/execution/scheduler/TopologyAwareNodeSelectorFactory.java
+++ b/core/trino-main/src/main/java/io/trino/execution/scheduler/TopologyAwareNodeSelectorFactory.java
@@ -14,7 +14,6 @@
package io.trino.execution.scheduler;
import com.google.common.base.Suppliers;
-import com.google.common.cache.Cache;
import com.google.common.cache.CacheBuilder;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableList.Builder;
@@ -27,6 +26,7 @@
import io.trino.execution.NodeTaskMap;
import io.trino.metadata.InternalNode;
import io.trino.metadata.InternalNodeManager;
+import io.trino.plugin.base.cache.NonEvictableCache;
import io.trino.spi.HostAddress;
import io.trino.spi.SplitWeight;
@@ -46,6 +46,7 @@
import static com.google.common.collect.ImmutableSet.toImmutableSet;
import static io.trino.SystemSessionProperties.getMaxUnacknowledgedSplitsPerTask;
import static io.trino.metadata.NodeState.ACTIVE;
+import static io.trino.plugin.base.cache.SafeCaches.buildNonEvictableCache;
import static java.util.Objects.requireNonNull;
public class TopologyAwareNodeSelectorFactory
@@ -53,9 +54,9 @@ public class TopologyAwareNodeSelectorFactory
{
private static final Logger LOG = Logger.get(TopologyAwareNodeSelectorFactory.class);
- private final Cache inaccessibleNodeLogCache = CacheBuilder.newBuilder()
- .expireAfterWrite(30, TimeUnit.SECONDS)
- .build();
+ private final NonEvictableCache inaccessibleNodeLogCache = buildNonEvictableCache(
+ CacheBuilder.newBuilder()
+ .expireAfterWrite(30, TimeUnit.SECONDS));
private final NetworkTopology networkTopology;
private final InternalNodeManager nodeManager;
diff --git a/core/trino-main/src/main/java/io/trino/execution/scheduler/UniformNodeSelectorFactory.java b/core/trino-main/src/main/java/io/trino/execution/scheduler/UniformNodeSelectorFactory.java
index 53725a5abc18..b7eec9f8ed78 100644
--- a/core/trino-main/src/main/java/io/trino/execution/scheduler/UniformNodeSelectorFactory.java
+++ b/core/trino-main/src/main/java/io/trino/execution/scheduler/UniformNodeSelectorFactory.java
@@ -15,7 +15,6 @@
import com.google.common.annotations.VisibleForTesting;
import com.google.common.base.Suppliers;
-import com.google.common.cache.Cache;
import com.google.common.cache.CacheBuilder;
import com.google.common.collect.ImmutableSetMultimap;
import io.airlift.log.Logger;
@@ -25,6 +24,7 @@
import io.trino.execution.NodeTaskMap;
import io.trino.metadata.InternalNode;
import io.trino.metadata.InternalNodeManager;
+import io.trino.plugin.base.cache.NonEvictableCache;
import io.trino.spi.HostAddress;
import io.trino.spi.SplitWeight;
@@ -42,6 +42,7 @@
import static com.google.common.collect.ImmutableSet.toImmutableSet;
import static io.trino.SystemSessionProperties.getMaxUnacknowledgedSplitsPerTask;
import static io.trino.metadata.NodeState.ACTIVE;
+import static io.trino.plugin.base.cache.SafeCaches.buildNonEvictableCache;
import static java.util.Objects.requireNonNull;
import static java.util.concurrent.TimeUnit.MILLISECONDS;
import static java.util.concurrent.TimeUnit.SECONDS;
@@ -51,9 +52,9 @@ public class UniformNodeSelectorFactory
{
private static final Logger LOG = Logger.get(UniformNodeSelectorFactory.class);
- private final Cache inaccessibleNodeLogCache = CacheBuilder.newBuilder()
- .expireAfterWrite(30, TimeUnit.SECONDS)
- .build();
+ private final NonEvictableCache inaccessibleNodeLogCache = buildNonEvictableCache(
+ CacheBuilder.newBuilder()
+ .expireAfterWrite(30, TimeUnit.SECONDS));
private final InternalNodeManager nodeManager;
private final int minCandidates;
diff --git a/core/trino-main/src/main/java/io/trino/metadata/AbstractTypedJacksonModule.java b/core/trino-main/src/main/java/io/trino/metadata/AbstractTypedJacksonModule.java
index d6a946f183f0..b99f6d2a9602 100644
--- a/core/trino-main/src/main/java/io/trino/metadata/AbstractTypedJacksonModule.java
+++ b/core/trino-main/src/main/java/io/trino/metadata/AbstractTypedJacksonModule.java
@@ -34,8 +34,9 @@
import com.fasterxml.jackson.databind.ser.BeanSerializerFactory;
import com.fasterxml.jackson.databind.ser.std.StdSerializer;
import com.fasterxml.jackson.databind.type.TypeFactory;
-import com.google.common.cache.Cache;
import com.google.common.cache.CacheBuilder;
+import io.trino.plugin.base.cache.NonEvictableCache;
+import io.trino.plugin.base.cache.SafeCaches;
import java.io.IOException;
import java.util.concurrent.ExecutionException;
@@ -92,7 +93,7 @@ private static class InternalTypeSerializer
extends StdSerializer
{
private final TypeSerializer typeSerializer;
- private final Cache, JsonSerializer> serializerCache = CacheBuilder.newBuilder().build();
+ private final NonEvictableCache, JsonSerializer> serializerCache = SafeCaches.buildNonEvictableCache(CacheBuilder.newBuilder());
public InternalTypeSerializer(Class baseClass, TypeIdResolver typeIdResolver)
{
diff --git a/core/trino-main/src/main/java/io/trino/metadata/FunctionRegistry.java b/core/trino-main/src/main/java/io/trino/metadata/FunctionRegistry.java
index dc8218116b17..67aaf31168ac 100644
--- a/core/trino-main/src/main/java/io/trino/metadata/FunctionRegistry.java
+++ b/core/trino-main/src/main/java/io/trino/metadata/FunctionRegistry.java
@@ -13,7 +13,6 @@
*/
package io.trino.metadata;
-import com.google.common.cache.Cache;
import com.google.common.cache.CacheBuilder;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableListMultimap;
@@ -237,6 +236,7 @@
import io.trino.operator.window.RowNumberFunction;
import io.trino.operator.window.SqlWindowFunction;
import io.trino.operator.window.WindowFunctionSupplier;
+import io.trino.plugin.base.cache.NonEvictableCache;
import io.trino.spi.TrinoException;
import io.trino.spi.block.BlockEncodingSerde;
import io.trino.spi.function.InvocationConvention;
@@ -341,6 +341,7 @@
import static io.trino.operator.scalar.TryCastFunction.TRY_CAST;
import static io.trino.operator.scalar.ZipFunction.ZIP_FUNCTIONS;
import static io.trino.operator.scalar.ZipWithFunction.ZIP_WITH_FUNCTION;
+import static io.trino.plugin.base.cache.SafeCaches.buildNonEvictableCache;
import static io.trino.type.DecimalCasts.BIGINT_TO_DECIMAL_CAST;
import static io.trino.type.DecimalCasts.BOOLEAN_TO_DECIMAL_CAST;
import static io.trino.type.DecimalCasts.DECIMAL_TO_BIGINT_CAST;
@@ -380,9 +381,9 @@
@ThreadSafe
public class FunctionRegistry
{
- private final Cache specializedScalarCache;
- private final Cache specializedAggregationCache;
- private final Cache specializedWindowCache;
+ private final NonEvictableCache specializedScalarCache;
+ private final NonEvictableCache specializedAggregationCache;
+ private final NonEvictableCache specializedWindowCache;
private volatile FunctionMap functions = new FunctionMap();
public FunctionRegistry(
@@ -398,20 +399,17 @@ public FunctionRegistry(
// with generated classes and/or dynamically-created MethodHandles.
// This might also mitigate problems like deoptimization storm or unintended interpreted execution.
- specializedScalarCache = CacheBuilder.newBuilder()
+ specializedScalarCache = buildNonEvictableCache(CacheBuilder.newBuilder()
.maximumSize(1000)
- .expireAfterWrite(1, HOURS)
- .build();
+ .expireAfterWrite(1, HOURS));
- specializedAggregationCache = CacheBuilder.newBuilder()
+ specializedAggregationCache = buildNonEvictableCache(CacheBuilder.newBuilder()
.maximumSize(1000)
- .expireAfterWrite(1, HOURS)
- .build();
+ .expireAfterWrite(1, HOURS));
- specializedWindowCache = CacheBuilder.newBuilder()
+ specializedWindowCache = buildNonEvictableCache(CacheBuilder.newBuilder()
.maximumSize(1000)
- .expireAfterWrite(1, HOURS)
- .build();
+ .expireAfterWrite(1, HOURS));
FunctionListBuilder builder = new FunctionListBuilder()
.window(RowNumberFunction.class)
diff --git a/core/trino-main/src/main/java/io/trino/metadata/MetadataManager.java b/core/trino-main/src/main/java/io/trino/metadata/MetadataManager.java
index 1162bfd1705b..89abd8c9dc40 100644
--- a/core/trino-main/src/main/java/io/trino/metadata/MetadataManager.java
+++ b/core/trino-main/src/main/java/io/trino/metadata/MetadataManager.java
@@ -14,7 +14,6 @@
package io.trino.metadata;
import com.google.common.annotations.VisibleForTesting;
-import com.google.common.cache.Cache;
import com.google.common.cache.CacheBuilder;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
@@ -32,6 +31,7 @@
import io.trino.metadata.ResolvedFunction.ResolvedFunctionDecoder;
import io.trino.operator.aggregation.AggregationMetadata;
import io.trino.operator.window.WindowFunctionSupplier;
+import io.trino.plugin.base.cache.NonEvictableCache;
import io.trino.spi.QueryId;
import io.trino.spi.TrinoException;
import io.trino.spi.block.Block;
@@ -147,6 +147,7 @@
import static io.trino.metadata.RedirectionAwareTableHandle.withRedirectionTo;
import static io.trino.metadata.Signature.mangleOperatorName;
import static io.trino.metadata.SignatureBinder.applyBoundVariables;
+import static io.trino.plugin.base.cache.SafeCaches.buildNonEvictableCache;
import static io.trino.spi.StandardErrorCode.FUNCTION_IMPLEMENTATION_ERROR;
import static io.trino.spi.StandardErrorCode.FUNCTION_IMPLEMENTATION_MISSING;
import static io.trino.spi.StandardErrorCode.FUNCTION_NOT_FOUND;
@@ -180,8 +181,8 @@ public final class MetadataManager
private final ResolvedFunctionDecoder functionDecoder;
- private final Cache operatorCache;
- private final Cache coercionCache;
+ private final NonEvictableCache operatorCache;
+ private final NonEvictableCache coercionCache;
@Inject
public MetadataManager(
@@ -204,13 +205,8 @@ public MetadataManager(
functionDecoder = new ResolvedFunctionDecoder(typeManager::getType);
- operatorCache = CacheBuilder.newBuilder()
- .maximumSize(1000)
- .build();
-
- coercionCache = CacheBuilder.newBuilder()
- .maximumSize(1000)
- .build();
+ operatorCache = buildNonEvictableCache(CacheBuilder.newBuilder().maximumSize(1000));
+ coercionCache = buildNonEvictableCache(CacheBuilder.newBuilder().maximumSize(1000));
}
public static MetadataManager createTestMetadataManager()
diff --git a/core/trino-main/src/main/java/io/trino/metadata/TypeRegistry.java b/core/trino-main/src/main/java/io/trino/metadata/TypeRegistry.java
index 3898bf0b3c5e..4aa5df08681c 100644
--- a/core/trino-main/src/main/java/io/trino/metadata/TypeRegistry.java
+++ b/core/trino-main/src/main/java/io/trino/metadata/TypeRegistry.java
@@ -14,13 +14,13 @@
package io.trino.metadata;
import com.google.common.base.Joiner;
-import com.google.common.cache.Cache;
import com.google.common.cache.CacheBuilder;
import com.google.common.collect.HashMultimap;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.Multimap;
import com.google.common.util.concurrent.UncheckedExecutionException;
import io.trino.FeaturesConfig;
+import io.trino.plugin.base.cache.NonEvictableCache;
import io.trino.spi.function.OperatorType;
import io.trino.spi.type.ParametricType;
import io.trino.spi.type.Type;
@@ -53,6 +53,7 @@
import static com.google.common.base.Preconditions.checkArgument;
import static com.google.common.base.Preconditions.checkState;
import static com.google.common.base.Throwables.throwIfUnchecked;
+import static io.trino.plugin.base.cache.SafeCaches.buildNonEvictableCache;
import static io.trino.spi.function.InvocationConvention.InvocationArgumentConvention.BOXED_NULLABLE;
import static io.trino.spi.function.InvocationConvention.InvocationArgumentConvention.NEVER_NULL;
import static io.trino.spi.function.InvocationConvention.InvocationReturnConvention.FAIL_ON_NULL;
@@ -112,7 +113,7 @@ public final class TypeRegistry
private final ConcurrentMap types = new ConcurrentHashMap<>();
private final ConcurrentMap parametricTypes = new ConcurrentHashMap<>();
- private final Cache parametricTypeCache;
+ private final NonEvictableCache parametricTypeCache;
private final TypeManager typeManager;
private final TypeOperators typeOperators;
@@ -164,9 +165,7 @@ public TypeRegistry(TypeOperators typeOperators, FeaturesConfig featuresConfig)
addParametricType(TIME);
addParametricType(TIME_WITH_TIME_ZONE);
- parametricTypeCache = CacheBuilder.newBuilder()
- .maximumSize(1000)
- .build();
+ parametricTypeCache = buildNonEvictableCache(CacheBuilder.newBuilder().maximumSize(1000));
typeManager = new InternalTypeManager(this, typeOperators);
diff --git a/core/trino-main/src/main/java/io/trino/server/security/oauth2/OAuth2TokenExchange.java b/core/trino-main/src/main/java/io/trino/server/security/oauth2/OAuth2TokenExchange.java
index 335f7d6b8ea4..9ec3a952be50 100644
--- a/core/trino-main/src/main/java/io/trino/server/security/oauth2/OAuth2TokenExchange.java
+++ b/core/trino-main/src/main/java/io/trino/server/security/oauth2/OAuth2TokenExchange.java
@@ -20,6 +20,7 @@
import com.google.common.util.concurrent.ListenableFuture;
import com.google.common.util.concurrent.SettableFuture;
import io.airlift.units.Duration;
+import org.gaul.modernizer_maven_annotations.SuppressModernizer;
import javax.annotation.PreDestroy;
import javax.inject.Inject;
@@ -50,10 +51,11 @@ public class OAuth2TokenExchange
public OAuth2TokenExchange(OAuth2Config config)
{
long challengeTimeoutMillis = config.getChallengeTimeout().toMillis();
- this.cache = CacheBuilder.newBuilder()
- .expireAfterWrite(challengeTimeoutMillis + (MAX_POLL_TIME.toMillis() * 10), MILLISECONDS)
- .>removalListener(notification -> notification.getValue().set(TOKEN_POLL_TIMED_OUT))
- .build(new CacheLoader<>()
+ this.cache = buildUnsafeCache(
+ CacheBuilder.newBuilder()
+ .expireAfterWrite(challengeTimeoutMillis + (MAX_POLL_TIME.toMillis() * 10), MILLISECONDS)
+ .removalListener(notification -> notification.getValue().set(TOKEN_POLL_TIMED_OUT)),
+ new CacheLoader<>()
{
@Override
public SettableFuture load(String authIdHash)
@@ -66,6 +68,13 @@ public SettableFuture load(String authIdHash)
});
}
+ // TODO (https://github.com/trinodb/trino/issues/10685) Investigate cache correctness with respect to invalidation
+ @SuppressModernizer
+ private static LoadingCache buildUnsafeCache(CacheBuilder super K, ? super V> cacheBuilder, CacheLoader super K, V> cacheLoader)
+ {
+ return cacheBuilder.build(cacheLoader);
+ }
+
@PreDestroy
public void stop()
{
diff --git a/core/trino-main/src/main/java/io/trino/spiller/FileSingleStreamSpillerFactory.java b/core/trino-main/src/main/java/io/trino/spiller/FileSingleStreamSpillerFactory.java
index 409ab63c6253..43a5fd86129d 100644
--- a/core/trino-main/src/main/java/io/trino/spiller/FileSingleStreamSpillerFactory.java
+++ b/core/trino-main/src/main/java/io/trino/spiller/FileSingleStreamSpillerFactory.java
@@ -16,7 +16,6 @@
import com.google.common.annotations.VisibleForTesting;
import com.google.common.cache.CacheBuilder;
import com.google.common.cache.CacheLoader;
-import com.google.common.cache.LoadingCache;
import com.google.common.collect.ImmutableList;
import com.google.common.util.concurrent.ListeningExecutorService;
import com.google.inject.Inject;
@@ -26,6 +25,7 @@
import io.trino.execution.buffer.PagesSerdeFactory;
import io.trino.memory.context.LocalMemoryContext;
import io.trino.operator.SpillContext;
+import io.trino.plugin.base.cache.NonKeyEvictableLoadingCache;
import io.trino.spi.TrinoException;
import io.trino.spi.block.BlockEncodingSerde;
import io.trino.spi.type.Type;
@@ -44,6 +44,7 @@
import static com.google.common.util.concurrent.MoreExecutors.listeningDecorator;
import static io.airlift.concurrent.Threads.daemonThreadsNamed;
import static io.trino.FeaturesConfig.SPILLER_SPILL_PATH;
+import static io.trino.plugin.base.cache.SafeCaches.buildNonEvictableCacheWithWeakInvalidateAll;
import static io.trino.spi.StandardErrorCode.OUT_OF_SPILL_SPACE;
import static java.lang.String.format;
import static java.nio.file.Files.createDirectories;
@@ -77,7 +78,7 @@ public class FileSingleStreamSpillerFactory
private final double maxUsedSpaceThreshold;
private final boolean spillEncryptionEnabled;
private int roundRobinIndex;
- private final LoadingCache spillPathHealthCache;
+ private final NonKeyEvictableLoadingCache spillPathHealthCache;
@Inject
public FileSingleStreamSpillerFactory(BlockEncodingSerde blockEncodingSerde, SpillerStats spillerStats, FeaturesConfig featuresConfig, NodeSpillConfig nodeSpillConfig)
@@ -124,9 +125,10 @@ public FileSingleStreamSpillerFactory(
this.spillEncryptionEnabled = spillEncryptionEnabled;
this.roundRobinIndex = 0;
- this.spillPathHealthCache = CacheBuilder.newBuilder()
- .expireAfterWrite(SPILL_PATH_HEALTH_EXPIRY_INTERVAL)
- .build(CacheLoader.from(path -> isAccessible(path) && isSeeminglyHealthy(path)));
+ this.spillPathHealthCache = buildNonEvictableCacheWithWeakInvalidateAll(
+ CacheBuilder.newBuilder()
+ .expireAfterWrite(SPILL_PATH_HEALTH_EXPIRY_INTERVAL),
+ CacheLoader.from(path -> isAccessible(path) && isSeeminglyHealthy(path)));
}
@PostConstruct
diff --git a/core/trino-main/src/main/java/io/trino/sql/gen/ExpressionCompiler.java b/core/trino-main/src/main/java/io/trino/sql/gen/ExpressionCompiler.java
index af95dac084d4..73b9b3b74233 100644
--- a/core/trino-main/src/main/java/io/trino/sql/gen/ExpressionCompiler.java
+++ b/core/trino-main/src/main/java/io/trino/sql/gen/ExpressionCompiler.java
@@ -16,7 +16,6 @@
import com.google.common.annotations.VisibleForTesting;
import com.google.common.cache.CacheBuilder;
import com.google.common.cache.CacheLoader;
-import com.google.common.cache.LoadingCache;
import com.google.common.collect.ImmutableList;
import io.airlift.bytecode.ClassDefinition;
import io.airlift.bytecode.CompilationException;
@@ -26,6 +25,7 @@
import io.trino.operator.project.PageFilter;
import io.trino.operator.project.PageProcessor;
import io.trino.operator.project.PageProjection;
+import io.trino.plugin.base.cache.NonEvictableLoadingCache;
import io.trino.spi.TrinoException;
import io.trino.sql.relational.RowExpression;
import org.weakref.jmx.Managed;
@@ -45,6 +45,7 @@
import static io.airlift.bytecode.Access.PUBLIC;
import static io.airlift.bytecode.Access.a;
import static io.airlift.bytecode.ParameterizedType.type;
+import static io.trino.plugin.base.cache.SafeCaches.buildNonEvictableCache;
import static io.trino.spi.StandardErrorCode.COMPILER_ERROR;
import static io.trino.spi.type.BooleanType.BOOLEAN;
import static io.trino.sql.gen.BytecodeUtils.invoke;
@@ -56,7 +57,7 @@
public class ExpressionCompiler
{
private final PageFunctionCompiler pageFunctionCompiler;
- private final LoadingCache> cursorProcessors;
+ private final NonEvictableLoadingCache> cursorProcessors;
private final CacheStatsMBean cacheStatsMBean;
@Inject
@@ -64,10 +65,10 @@ public ExpressionCompiler(Metadata metadata, PageFunctionCompiler pageFunctionCo
{
requireNonNull(metadata, "metadata is null");
this.pageFunctionCompiler = requireNonNull(pageFunctionCompiler, "pageFunctionCompiler is null");
- this.cursorProcessors = CacheBuilder.newBuilder()
- .recordStats()
- .maximumSize(1000)
- .build(CacheLoader.from(key -> compile(key.getFilter(), key.getProjections(), new CursorProcessorCompiler(metadata), CursorProcessor.class)));
+ this.cursorProcessors = buildNonEvictableCache(CacheBuilder.newBuilder()
+ .recordStats()
+ .maximumSize(1000),
+ CacheLoader.from(key -> compile(key.getFilter(), key.getProjections(), new CursorProcessorCompiler(metadata), CursorProcessor.class)));
this.cacheStatsMBean = new CacheStatsMBean(cursorProcessors);
}
diff --git a/core/trino-main/src/main/java/io/trino/sql/gen/JoinCompiler.java b/core/trino-main/src/main/java/io/trino/sql/gen/JoinCompiler.java
index e3f525831bfa..589f8ec6797b 100644
--- a/core/trino-main/src/main/java/io/trino/sql/gen/JoinCompiler.java
+++ b/core/trino-main/src/main/java/io/trino/sql/gen/JoinCompiler.java
@@ -15,7 +15,6 @@
import com.google.common.cache.CacheBuilder;
import com.google.common.cache.CacheLoader;
-import com.google.common.cache.LoadingCache;
import com.google.common.collect.ImmutableList;
import io.airlift.bytecode.BytecodeBlock;
import io.airlift.bytecode.BytecodeNode;
@@ -40,6 +39,7 @@
import io.trino.operator.join.JoinHashSupplier;
import io.trino.operator.join.LookupSourceSupplier;
import io.trino.operator.join.PagesHash;
+import io.trino.plugin.base.cache.NonEvictableLoadingCache;
import io.trino.spi.Page;
import io.trino.spi.PageBuilder;
import io.trino.spi.block.Block;
@@ -81,6 +81,7 @@
import static io.airlift.bytecode.expression.BytecodeExpressions.invokeDynamic;
import static io.airlift.bytecode.expression.BytecodeExpressions.newInstance;
import static io.airlift.bytecode.expression.BytecodeExpressions.notEqual;
+import static io.trino.plugin.base.cache.SafeCaches.buildNonEvictableCache;
import static io.trino.spi.function.InvocationConvention.InvocationArgumentConvention.BLOCK_POSITION;
import static io.trino.spi.function.InvocationConvention.InvocationReturnConvention.FAIL_ON_NULL;
import static io.trino.spi.function.InvocationConvention.InvocationReturnConvention.NULLABLE_RETURN;
@@ -95,16 +96,18 @@ public class JoinCompiler
{
private final TypeOperators typeOperators;
- private final LoadingCache lookupSourceFactories = CacheBuilder.newBuilder()
- .recordStats()
- .maximumSize(1000)
- .build(CacheLoader.from(key ->
+ private final NonEvictableLoadingCache lookupSourceFactories = buildNonEvictableCache(
+ CacheBuilder.newBuilder()
+ .recordStats()
+ .maximumSize(1000),
+ CacheLoader.from(key ->
internalCompileLookupSourceFactory(key.getTypes(), key.getOutputChannels(), key.getJoinChannels(), key.getSortChannel())));
- private final LoadingCache> hashStrategies = CacheBuilder.newBuilder()
- .recordStats()
- .maximumSize(1000)
- .build(CacheLoader.from(key ->
+ private final NonEvictableLoadingCache> hashStrategies = buildNonEvictableCache(
+ CacheBuilder.newBuilder()
+ .recordStats()
+ .maximumSize(1000),
+ CacheLoader.from(key ->
internalCompileHashStrategy(key.getTypes(), key.getOutputChannels(), key.getJoinChannels(), key.getSortChannel())));
@Inject
diff --git a/core/trino-main/src/main/java/io/trino/sql/gen/JoinFilterFunctionCompiler.java b/core/trino-main/src/main/java/io/trino/sql/gen/JoinFilterFunctionCompiler.java
index 30d0f545bf08..5639ba605a98 100644
--- a/core/trino-main/src/main/java/io/trino/sql/gen/JoinFilterFunctionCompiler.java
+++ b/core/trino-main/src/main/java/io/trino/sql/gen/JoinFilterFunctionCompiler.java
@@ -15,7 +15,6 @@
import com.google.common.cache.CacheBuilder;
import com.google.common.cache.CacheLoader;
-import com.google.common.cache.LoadingCache;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableSet;
@@ -34,6 +33,7 @@
import io.trino.operator.join.InternalJoinFilterFunction;
import io.trino.operator.join.JoinFilterFunction;
import io.trino.operator.join.StandardJoinFilterFunction;
+import io.trino.plugin.base.cache.NonEvictableLoadingCache;
import io.trino.spi.Page;
import io.trino.spi.block.Block;
import io.trino.spi.connector.ConnectorSession;
@@ -62,6 +62,7 @@
import static io.airlift.bytecode.ParameterizedType.type;
import static io.airlift.bytecode.expression.BytecodeExpressions.constantFalse;
import static io.airlift.bytecode.expression.BytecodeExpressions.constantInt;
+import static io.trino.plugin.base.cache.SafeCaches.buildNonEvictableCache;
import static io.trino.sql.gen.BytecodeUtils.invoke;
import static io.trino.sql.gen.LambdaExpressionExtractor.extractLambdaExpressions;
import static io.trino.util.CompilerUtils.defineClass;
@@ -78,10 +79,11 @@ public JoinFilterFunctionCompiler(Metadata metadata)
this.metadata = metadata;
}
- private final LoadingCache joinFilterFunctionFactories = CacheBuilder.newBuilder()
- .recordStats()
- .maximumSize(1000)
- .build(CacheLoader.from(key -> internalCompileFilterFunctionFactory(key.getFilter(), key.getLeftBlocksSize())));
+ private final NonEvictableLoadingCache joinFilterFunctionFactories = buildNonEvictableCache(
+ CacheBuilder.newBuilder()
+ .recordStats()
+ .maximumSize(1000),
+ CacheLoader.from(key -> internalCompileFilterFunctionFactory(key.getFilter(), key.getLeftBlocksSize())));
@Managed
@Nested
diff --git a/core/trino-main/src/main/java/io/trino/sql/gen/OrderingCompiler.java b/core/trino-main/src/main/java/io/trino/sql/gen/OrderingCompiler.java
index 728984138673..f2aa2d090c81 100644
--- a/core/trino-main/src/main/java/io/trino/sql/gen/OrderingCompiler.java
+++ b/core/trino-main/src/main/java/io/trino/sql/gen/OrderingCompiler.java
@@ -16,7 +16,6 @@
import com.google.common.annotations.VisibleForTesting;
import com.google.common.cache.CacheBuilder;
import com.google.common.cache.CacheLoader;
-import com.google.common.cache.LoadingCache;
import com.google.common.collect.ImmutableList;
import io.airlift.bytecode.BytecodeBlock;
import io.airlift.bytecode.ClassDefinition;
@@ -35,6 +34,7 @@
import io.trino.operator.SimplePageWithPositionComparator;
import io.trino.operator.SimplePagesIndexComparator;
import io.trino.operator.SyntheticAddress;
+import io.trino.plugin.base.cache.NonEvictableLoadingCache;
import io.trino.spi.Page;
import io.trino.spi.block.Block;
import io.trino.spi.connector.SortOrder;
@@ -59,6 +59,7 @@
import static io.airlift.bytecode.expression.BytecodeExpressions.constantInt;
import static io.airlift.bytecode.expression.BytecodeExpressions.invokeDynamic;
import static io.airlift.bytecode.expression.BytecodeExpressions.invokeStatic;
+import static io.trino.plugin.base.cache.SafeCaches.buildNonEvictableCache;
import static io.trino.spi.function.InvocationConvention.InvocationArgumentConvention.BLOCK_POSITION;
import static io.trino.spi.function.InvocationConvention.InvocationReturnConvention.FAIL_ON_NULL;
import static io.trino.spi.function.InvocationConvention.simpleConvention;
@@ -71,15 +72,17 @@ public class OrderingCompiler
{
private static final Logger log = Logger.get(OrderingCompiler.class);
- private final LoadingCache pagesIndexOrderings = CacheBuilder.newBuilder()
- .recordStats()
- .maximumSize(1000)
- .build(CacheLoader.from(key -> internalCompilePagesIndexOrdering(key.getSortTypes(), key.getSortChannels(), key.getSortOrders())));
-
- private final LoadingCache pageWithPositionComparators = CacheBuilder.newBuilder()
- .recordStats()
- .maximumSize(1000)
- .build(CacheLoader.from(key -> internalCompilePageWithPositionComparator(key.getSortTypes(), key.getSortChannels(), key.getSortOrders())));
+ private final NonEvictableLoadingCache pagesIndexOrderings = buildNonEvictableCache(
+ CacheBuilder.newBuilder()
+ .recordStats()
+ .maximumSize(1000),
+ CacheLoader.from(key -> internalCompilePagesIndexOrdering(key.getSortTypes(), key.getSortChannels(), key.getSortOrders())));
+
+ private final NonEvictableLoadingCache pageWithPositionComparators = buildNonEvictableCache(
+ CacheBuilder.newBuilder()
+ .recordStats()
+ .maximumSize(1000),
+ CacheLoader.from(key -> internalCompilePageWithPositionComparator(key.getSortTypes(), key.getSortChannels(), key.getSortOrders())));
private final TypeOperators typeOperators;
diff --git a/core/trino-main/src/main/java/io/trino/sql/gen/PageFunctionCompiler.java b/core/trino-main/src/main/java/io/trino/sql/gen/PageFunctionCompiler.java
index 586dfa1c05d3..52dd8f4e776f 100644
--- a/core/trino-main/src/main/java/io/trino/sql/gen/PageFunctionCompiler.java
+++ b/core/trino-main/src/main/java/io/trino/sql/gen/PageFunctionCompiler.java
@@ -16,7 +16,6 @@
import com.google.common.base.Throwables;
import com.google.common.cache.CacheBuilder;
import com.google.common.cache.CacheLoader;
-import com.google.common.cache.LoadingCache;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableSet;
@@ -42,6 +41,7 @@
import io.trino.operator.project.PageFilter;
import io.trino.operator.project.PageProjection;
import io.trino.operator.project.SelectedPositions;
+import io.trino.plugin.base.cache.NonEvictableLoadingCache;
import io.trino.spi.Page;
import io.trino.spi.TrinoException;
import io.trino.spi.block.Block;
@@ -88,6 +88,7 @@
import static io.airlift.bytecode.expression.BytecodeExpressions.newArray;
import static io.airlift.bytecode.expression.BytecodeExpressions.not;
import static io.trino.operator.project.PageFieldsToInputParametersRewriter.rewritePageFieldsToInputParameters;
+import static io.trino.plugin.base.cache.SafeCaches.buildNonEvictableCache;
import static io.trino.spi.StandardErrorCode.COMPILER_ERROR;
import static io.trino.sql.gen.BytecodeUtils.generateWrite;
import static io.trino.sql.gen.BytecodeUtils.invoke;
@@ -102,8 +103,8 @@ public class PageFunctionCompiler
{
private final Metadata metadata;
- private final LoadingCache> projectionCache;
- private final LoadingCache> filterCache;
+ private final NonEvictableLoadingCache> projectionCache;
+ private final NonEvictableLoadingCache> filterCache;
private final CacheStatsMBean projectionCacheStats;
private final CacheStatsMBean filterCacheStats;
@@ -119,10 +120,11 @@ public PageFunctionCompiler(Metadata metadata, int expressionCacheSize)
this.metadata = requireNonNull(metadata, "metadata is null");
if (expressionCacheSize > 0) {
- projectionCache = CacheBuilder.newBuilder()
- .recordStats()
- .maximumSize(expressionCacheSize)
- .build(CacheLoader.from(projection -> compileProjectionInternal(projection, Optional.empty())));
+ projectionCache = buildNonEvictableCache(
+ CacheBuilder.newBuilder()
+ .recordStats()
+ .maximumSize(expressionCacheSize),
+ CacheLoader.from(projection -> compileProjectionInternal(projection, Optional.empty())));
projectionCacheStats = new CacheStatsMBean(projectionCache);
}
else {
@@ -131,10 +133,11 @@ public PageFunctionCompiler(Metadata metadata, int expressionCacheSize)
}
if (expressionCacheSize > 0) {
- filterCache = CacheBuilder.newBuilder()
- .recordStats()
- .maximumSize(expressionCacheSize)
- .build(CacheLoader.from(filter -> compileFilterInternal(filter, Optional.empty())));
+ filterCache = buildNonEvictableCache(
+ CacheBuilder.newBuilder()
+ .recordStats()
+ .maximumSize(expressionCacheSize),
+ CacheLoader.from(filter -> compileFilterInternal(filter, Optional.empty())));
filterCacheStats = new CacheStatsMBean(filterCache);
}
else {
diff --git a/core/trino-main/src/main/java/io/trino/type/BlockTypeOperators.java b/core/trino-main/src/main/java/io/trino/type/BlockTypeOperators.java
index dad7c299d231..9926d9993625 100644
--- a/core/trino-main/src/main/java/io/trino/type/BlockTypeOperators.java
+++ b/core/trino-main/src/main/java/io/trino/type/BlockTypeOperators.java
@@ -13,9 +13,9 @@
*/
package io.trino.type;
-import com.google.common.cache.Cache;
import com.google.common.cache.CacheBuilder;
import com.google.common.util.concurrent.UncheckedExecutionException;
+import io.trino.plugin.base.cache.NonKeyEvictableCache;
import io.trino.spi.block.Block;
import io.trino.spi.connector.SortOrder;
import io.trino.spi.function.InvocationConvention;
@@ -34,6 +34,7 @@
import java.util.function.Supplier;
import static com.google.common.base.Throwables.throwIfUnchecked;
+import static io.trino.plugin.base.cache.SafeCaches.buildNonEvictableCacheWithWeakInvalidateAll;
import static io.trino.spi.function.InvocationConvention.InvocationArgumentConvention.BLOCK_POSITION;
import static io.trino.spi.function.InvocationConvention.InvocationReturnConvention.FAIL_ON_NULL;
import static io.trino.spi.function.InvocationConvention.InvocationReturnConvention.NULLABLE_RETURN;
@@ -54,7 +55,7 @@ public final class BlockTypeOperators
private static final InvocationConvention ORDERING_CONVENTION = simpleConvention(FAIL_ON_NULL, BLOCK_POSITION, BLOCK_POSITION);
private static final InvocationConvention LESS_THAN_CONVENTION = simpleConvention(FAIL_ON_NULL, BLOCK_POSITION, BLOCK_POSITION);
- private final Cache, GeneratedBlockOperator>> generatedBlockOperatorCache;
+ private final NonKeyEvictableCache, GeneratedBlockOperator>> generatedBlockOperatorCache;
private final TypeOperators typeOperators;
public BlockTypeOperators()
@@ -66,10 +67,10 @@ public BlockTypeOperators()
public BlockTypeOperators(TypeOperators typeOperators)
{
this.typeOperators = requireNonNull(typeOperators, "typeOperators is null");
- this.generatedBlockOperatorCache = CacheBuilder.newBuilder()
- .maximumSize(10_000)
- .expireAfterWrite(2, TimeUnit.HOURS)
- .build();
+ this.generatedBlockOperatorCache = buildNonEvictableCacheWithWeakInvalidateAll(
+ CacheBuilder.newBuilder()
+ .maximumSize(10_000)
+ .expireAfterWrite(2, TimeUnit.HOURS));
}
public BlockPositionEqual getEqualOperator(Type type)
diff --git a/core/trino-main/src/main/java/io/trino/type/TypeOperatorsCache.java b/core/trino-main/src/main/java/io/trino/type/TypeOperatorsCache.java
index 027f3adda002..0a2f43258b6e 100644
--- a/core/trino-main/src/main/java/io/trino/type/TypeOperatorsCache.java
+++ b/core/trino-main/src/main/java/io/trino/type/TypeOperatorsCache.java
@@ -13,9 +13,9 @@
*/
package io.trino.type;
-import com.google.common.cache.Cache;
import com.google.common.cache.CacheBuilder;
import com.google.common.util.concurrent.UncheckedExecutionException;
+import io.trino.plugin.base.cache.NonKeyEvictableCache;
import org.weakref.jmx.Managed;
import java.util.concurrent.ExecutionException;
@@ -23,13 +23,14 @@
import java.util.function.Supplier;
import static com.google.common.base.Throwables.throwIfUnchecked;
+import static io.trino.plugin.base.cache.SafeCaches.buildNonEvictableCacheWithWeakInvalidateAll;
public class TypeOperatorsCache
implements BiFunction
+
+ org.gaul
+ modernizer-maven-annotations
+
+
org.weakref
jmxutils
@@ -146,13 +151,6 @@
test
-
- org.gaul
- modernizer-maven-annotations
- 2.1.0
- test
-
-
org.testng
testng
diff --git a/lib/trino-plugin-toolkit/src/main/java/io/trino/plugin/base/cache/EvictableCache.java b/lib/trino-plugin-toolkit/src/main/java/io/trino/plugin/base/cache/EvictableCache.java
index 43e03d6e05b2..b1eb6f7320f3 100644
--- a/lib/trino-plugin-toolkit/src/main/java/io/trino/plugin/base/cache/EvictableCache.java
+++ b/lib/trino-plugin-toolkit/src/main/java/io/trino/plugin/base/cache/EvictableCache.java
@@ -18,6 +18,7 @@
import com.google.common.cache.CacheBuilder;
import com.google.common.cache.CacheStats;
import com.google.common.util.concurrent.SettableFuture;
+import org.gaul.modernizer_maven_annotations.SuppressModernizer;
import javax.annotation.CheckForNull;
@@ -61,7 +62,13 @@ public static EvictableCache buildWith(CacheBuilder super K, Obje
private EvictableCache(CacheBuilder super K, Object> cacheBuilder)
{
requireNonNull(cacheBuilder, "cacheBuilder is null");
- this.delegate = cacheBuilder.build();
+ this.delegate = buildUnsafeCache(cacheBuilder);
+ }
+
+ @SuppressModernizer // CacheBuilder.build() is forbidden, advising to use this class as a safety-adding wrapper.
+ private static Cache buildUnsafeCache(CacheBuilder super K, ? super V> cacheBuilder)
+ {
+ return cacheBuilder.build();
}
@CheckForNull
diff --git a/lib/trino-plugin-toolkit/src/main/java/io/trino/plugin/base/cache/EvictableLoadingCache.java b/lib/trino-plugin-toolkit/src/main/java/io/trino/plugin/base/cache/EvictableLoadingCache.java
index a9b532638b14..a225ecec766e 100644
--- a/lib/trino-plugin-toolkit/src/main/java/io/trino/plugin/base/cache/EvictableLoadingCache.java
+++ b/lib/trino-plugin-toolkit/src/main/java/io/trino/plugin/base/cache/EvictableLoadingCache.java
@@ -23,6 +23,7 @@
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import com.google.common.util.concurrent.ListenableFuture;
+import org.gaul.modernizer_maven_annotations.SuppressModernizer;
import java.util.ArrayList;
import java.util.Collection;
@@ -77,7 +78,13 @@ public static LoadingCache build(
return new EvictableLoadingCache<>(
EvictableCache.buildWith(tokenCache),
- dataCache.build(new TokenCacheLoader<>(cacheLoader)));
+ buildUnsafeCache(dataCache, new TokenCacheLoader<>(cacheLoader)));
+ }
+
+ @SuppressModernizer // CacheBuilder.build(CacheLoader) is forbidden, advising to use this class as a safety-adding wrapper.
+ private static LoadingCache buildUnsafeCache(CacheBuilder super K, ? super V> cacheBuilder, CacheLoader super K, V> cacheLoader)
+ {
+ return cacheBuilder.build(cacheLoader);
}
// Token is a freshness marker. tokenCache keeps the fresh token for given key.
diff --git a/lib/trino-plugin-toolkit/src/main/java/io/trino/plugin/base/cache/NonEvictableCache.java b/lib/trino-plugin-toolkit/src/main/java/io/trino/plugin/base/cache/NonEvictableCache.java
new file mode 100644
index 000000000000..beefc7981c18
--- /dev/null
+++ b/lib/trino-plugin-toolkit/src/main/java/io/trino/plugin/base/cache/NonEvictableCache.java
@@ -0,0 +1,44 @@
+/*
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package io.trino.plugin.base.cache;
+
+import com.google.common.cache.Cache;
+
+/**
+ * A {@link com.google.common.cache.Cache} that does not support eviction.
+ */
+public interface NonEvictableCache
+ extends Cache
+{
+ /**
+ * @deprecated Not supported. Use {@link EvictableCache} cache implementation instead.
+ */
+ @Deprecated
+ @Override
+ void invalidate(Object key);
+
+ /**
+ * @deprecated Not supported. Use {@link EvictableCache} cache implementation instead.
+ */
+ @Deprecated
+ @Override
+ void invalidateAll(Iterable> keys);
+
+ /**
+ * @deprecated Not supported. Use {@link EvictableCache} cache implementation instead.
+ */
+ @Deprecated
+ @Override
+ void invalidateAll();
+}
diff --git a/lib/trino-plugin-toolkit/src/main/java/io/trino/plugin/base/cache/NonEvictableCacheImpl.java b/lib/trino-plugin-toolkit/src/main/java/io/trino/plugin/base/cache/NonEvictableCacheImpl.java
new file mode 100644
index 000000000000..47c7779e744d
--- /dev/null
+++ b/lib/trino-plugin-toolkit/src/main/java/io/trino/plugin/base/cache/NonEvictableCacheImpl.java
@@ -0,0 +1,35 @@
+/*
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package io.trino.plugin.base.cache;
+
+import com.google.common.cache.Cache;
+
+// package-private. The interface provides deprecation and javadoc to help at call sites
+final class NonEvictableCacheImpl
+ extends NonKeyEvictableCacheImpl
+ implements NonEvictableCache
+{
+ NonEvictableCacheImpl(Cache delegate)
+ {
+ super(delegate);
+ }
+
+ @Override
+ public void invalidateAll()
+ {
+ throw new UnsupportedOperationException("invalidateAll does not invalidate ongoing loads, so a stale value may remain in the cache for ever. " +
+ "Use EvictableCache if you need invalidation, or use SafeCaches.buildNonEvictableCacheWithWeakInvalidateAll() " +
+ "if invalidateAll is not required for correctness");
+ }
+}
diff --git a/lib/trino-plugin-toolkit/src/main/java/io/trino/plugin/base/cache/NonEvictableLoadingCache.java b/lib/trino-plugin-toolkit/src/main/java/io/trino/plugin/base/cache/NonEvictableLoadingCache.java
new file mode 100644
index 000000000000..f7aa40e96e82
--- /dev/null
+++ b/lib/trino-plugin-toolkit/src/main/java/io/trino/plugin/base/cache/NonEvictableLoadingCache.java
@@ -0,0 +1,28 @@
+/*
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package io.trino.plugin.base.cache;
+
+/**
+ * A {@link com.google.common.cache.LoadingCache} that does not support eviction.
+ */
+public interface NonEvictableLoadingCache
+ extends NonKeyEvictableLoadingCache
+{
+ /**
+ * @deprecated Not supported. Use {@link EvictableLoadingCache} cache implementation instead.
+ */
+ @Deprecated
+ @Override
+ void invalidateAll();
+}
diff --git a/lib/trino-plugin-toolkit/src/main/java/io/trino/plugin/base/cache/NonEvictableLoadingCacheImpl.java b/lib/trino-plugin-toolkit/src/main/java/io/trino/plugin/base/cache/NonEvictableLoadingCacheImpl.java
new file mode 100644
index 000000000000..69ade57346b8
--- /dev/null
+++ b/lib/trino-plugin-toolkit/src/main/java/io/trino/plugin/base/cache/NonEvictableLoadingCacheImpl.java
@@ -0,0 +1,35 @@
+/*
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package io.trino.plugin.base.cache;
+
+import com.google.common.cache.LoadingCache;
+
+// package-private. The interface provides deprecation and javadoc to help at call sites
+final class NonEvictableLoadingCacheImpl
+ extends NonKeyEvictableLoadingCacheImpl
+ implements NonEvictableLoadingCache
+{
+ NonEvictableLoadingCacheImpl(LoadingCache delegate)
+ {
+ super(delegate);
+ }
+
+ @Override
+ public void invalidateAll()
+ {
+ throw new UnsupportedOperationException("invalidateAll does not invalidate ongoing loads, so a stale value may remain in the cache for ever. " +
+ "Use EvictableLoadingCache if you need invalidation, or use SafeCaches.buildNonEvictableCacheWithWeakInvalidateAll() " +
+ "if invalidateAll is not required for correctness");
+ }
+}
diff --git a/lib/trino-plugin-toolkit/src/main/java/io/trino/plugin/base/cache/NonKeyEvictableCache.java b/lib/trino-plugin-toolkit/src/main/java/io/trino/plugin/base/cache/NonKeyEvictableCache.java
new file mode 100644
index 000000000000..7a1ba409aa7e
--- /dev/null
+++ b/lib/trino-plugin-toolkit/src/main/java/io/trino/plugin/base/cache/NonKeyEvictableCache.java
@@ -0,0 +1,45 @@
+/*
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package io.trino.plugin.base.cache;
+
+import com.google.common.cache.Cache;
+
+/**
+ * A {@link com.google.common.cache.Cache} that does not support key-based eviction.
+ */
+public interface NonKeyEvictableCache
+ extends Cache
+{
+ /**
+ * @deprecated Not supported. Use {@link EvictableCache} cache implementation instead.
+ */
+ @Deprecated
+ @Override
+ void invalidate(Object key);
+
+ /**
+ * @deprecated Not supported. Use {@link EvictableCache} cache implementation instead.
+ */
+ @Deprecated
+ @Override
+ void invalidateAll(Iterable> keys);
+
+ /**
+ * Invalidates all live entries in the cache. Ongoing loads may not be invalidated, so subsequent
+ * get from the cache is not guaranteed to return fresh state. Must not be relied on for correctness,
+ * but can be used for manual intervention, e.g. as a method exposed over JMX.
+ */
+ @Override
+ void invalidateAll();
+}
diff --git a/lib/trino-plugin-toolkit/src/main/java/io/trino/plugin/base/cache/NonKeyEvictableCacheImpl.java b/lib/trino-plugin-toolkit/src/main/java/io/trino/plugin/base/cache/NonKeyEvictableCacheImpl.java
new file mode 100644
index 000000000000..9ccf3edcc100
--- /dev/null
+++ b/lib/trino-plugin-toolkit/src/main/java/io/trino/plugin/base/cache/NonKeyEvictableCacheImpl.java
@@ -0,0 +1,52 @@
+/*
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package io.trino.plugin.base.cache;
+
+import com.google.common.cache.Cache;
+import com.google.common.cache.ForwardingCache;
+
+import static java.util.Objects.requireNonNull;
+
+// package-private. The interface provides deprecation and javadoc to help at call sites
+class NonKeyEvictableCacheImpl
+ extends ForwardingCache
+ implements NonKeyEvictableCache
+{
+ private final Cache delegate;
+
+ NonKeyEvictableCacheImpl(Cache delegate)
+ {
+ this.delegate = requireNonNull(delegate, "delegate is null");
+ }
+
+ @Override
+ protected Cache delegate()
+ {
+ return delegate;
+ }
+
+ @Override
+ public void invalidate(Object key)
+ {
+ throw new UnsupportedOperationException("invalidate(key) does not invalidate ongoing loads, so a stale value may remain in the cache for ever. " +
+ "Use EvictableCache if you need invalidation");
+ }
+
+ @Override
+ public void invalidateAll(Iterable> keys)
+ {
+ throw new UnsupportedOperationException("invalidateAll(keys) does not invalidate ongoing loads, so a stale value may remain in the cache for ever. " +
+ "Use EvictableCache if you need invalidation");
+ }
+}
diff --git a/lib/trino-plugin-toolkit/src/main/java/io/trino/plugin/base/cache/NonKeyEvictableLoadingCache.java b/lib/trino-plugin-toolkit/src/main/java/io/trino/plugin/base/cache/NonKeyEvictableLoadingCache.java
new file mode 100644
index 000000000000..0c16b1c05ca8
--- /dev/null
+++ b/lib/trino-plugin-toolkit/src/main/java/io/trino/plugin/base/cache/NonKeyEvictableLoadingCache.java
@@ -0,0 +1,45 @@
+/*
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package io.trino.plugin.base.cache;
+
+import com.google.common.cache.LoadingCache;
+
+/**
+ * A {@link com.google.common.cache.LoadingCache} that does not support key-based eviction.
+ */
+public interface NonKeyEvictableLoadingCache
+ extends LoadingCache
+{
+ /**
+ * @deprecated Not supported. Use {@link EvictableLoadingCache} cache implementation instead.
+ */
+ @Deprecated
+ @Override
+ void invalidate(Object key);
+
+ /**
+ * @deprecated Not supported. Use {@link EvictableLoadingCache} cache implementation instead.
+ */
+ @Deprecated
+ @Override
+ void invalidateAll(Iterable> keys);
+
+ /**
+ * Invalidates all live entries in the cache. Ongoing loads may not be invalidated, so subsequent
+ * get from the cache is not guaranteed to return fresh state. Must not be relied on for correctness,
+ * but can be used for manual intervention, e.g. as a method exposed over JMX.
+ */
+ @Override
+ void invalidateAll();
+}
diff --git a/lib/trino-plugin-toolkit/src/main/java/io/trino/plugin/base/cache/NonKeyEvictableLoadingCacheImpl.java b/lib/trino-plugin-toolkit/src/main/java/io/trino/plugin/base/cache/NonKeyEvictableLoadingCacheImpl.java
new file mode 100644
index 000000000000..b68c1991ce48
--- /dev/null
+++ b/lib/trino-plugin-toolkit/src/main/java/io/trino/plugin/base/cache/NonKeyEvictableLoadingCacheImpl.java
@@ -0,0 +1,52 @@
+/*
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package io.trino.plugin.base.cache;
+
+import com.google.common.cache.ForwardingLoadingCache;
+import com.google.common.cache.LoadingCache;
+
+import static java.util.Objects.requireNonNull;
+
+// package-private. The interface provides deprecation and javadoc to help at call sites
+class NonKeyEvictableLoadingCacheImpl
+ extends ForwardingLoadingCache
+ implements NonKeyEvictableLoadingCache
+{
+ private final LoadingCache delegate;
+
+ NonKeyEvictableLoadingCacheImpl(LoadingCache delegate)
+ {
+ this.delegate = requireNonNull(delegate, "delegate is null");
+ }
+
+ @Override
+ protected LoadingCache delegate()
+ {
+ return delegate;
+ }
+
+ @Override
+ public void invalidate(Object key)
+ {
+ throw new UnsupportedOperationException("invalidate(key) does not invalidate ongoing loads, so a stale value may remain in the cache for ever. " +
+ "Use EvictableLoadingCache if you need invalidation");
+ }
+
+ @Override
+ public void invalidateAll(Iterable> keys)
+ {
+ throw new UnsupportedOperationException("invalidateAll(keys) does not invalidate ongoing loads, so a stale value may remain in the cache for ever. " +
+ "Use EvictableLoadingCache if you need invalidation");
+ }
+}
diff --git a/lib/trino-plugin-toolkit/src/main/java/io/trino/plugin/base/cache/SafeCaches.java b/lib/trino-plugin-toolkit/src/main/java/io/trino/plugin/base/cache/SafeCaches.java
new file mode 100644
index 000000000000..b049d216927b
--- /dev/null
+++ b/lib/trino-plugin-toolkit/src/main/java/io/trino/plugin/base/cache/SafeCaches.java
@@ -0,0 +1,73 @@
+/*
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package io.trino.plugin.base.cache;
+
+import com.google.common.cache.Cache;
+import com.google.common.cache.CacheBuilder;
+import com.google.common.cache.CacheLoader;
+import com.google.common.cache.LoadingCache;
+import org.gaul.modernizer_maven_annotations.SuppressModernizer;
+
+/**
+ * @see EvictableCache
+ * @see EvictableLoadingCache
+ */
+public final class SafeCaches
+{
+ private SafeCaches() {}
+
+ public static NonEvictableCache buildNonEvictableCache(CacheBuilder super K, ? super V> cacheBuilder)
+ {
+ return new NonEvictableCacheImpl<>(buildUnsafeCache(cacheBuilder));
+ }
+
+ /**
+ * Builds a cache that supports {@link Cache#invalidateAll()} with best-effort semantics:
+ * there is no guarantee that cache is empty after {@code invalidateAll()} returns, or that
+ * subsequent read will not see stale state.
+ */
+ public static NonKeyEvictableCache buildNonEvictableCacheWithWeakInvalidateAll(CacheBuilder super K, ? super V> cacheBuilder)
+ {
+ return new NonKeyEvictableCacheImpl<>(buildUnsafeCache(cacheBuilder));
+ }
+
+ public static NonEvictableLoadingCache buildNonEvictableCache(CacheBuilder super K, ? super V> cacheBuilder, CacheLoader super K, V> cacheLoader)
+ {
+ return new NonEvictableLoadingCacheImpl<>(buildUnsafeCache(cacheBuilder, cacheLoader));
+ }
+
+ /**
+ * Builds a cache that supports {@link Cache#invalidateAll()} with best-effort semantics:
+ * there is no guarantee that cache is empty after {@code invalidateAll()} returns, or that
+ * subsequent read will not see stale state.
+ */
+ public static NonKeyEvictableLoadingCache buildNonEvictableCacheWithWeakInvalidateAll(
+ CacheBuilder super K, ? super V> cacheBuilder,
+ CacheLoader super K, V> cacheLoader)
+ {
+ return new NonKeyEvictableLoadingCacheImpl<>(buildUnsafeCache(cacheBuilder, cacheLoader));
+ }
+
+ @SuppressModernizer // CacheBuilder.build() is forbidden, advising to use this class as a safety-adding wrapper.
+ private static Cache buildUnsafeCache(CacheBuilder super K, ? super V> cacheBuilder)
+ {
+ return cacheBuilder.build();
+ }
+
+ @SuppressModernizer // CacheBuilder.build(CacheLoader) is forbidden, advising to use this class as a safety-adding wrapper.
+ private static LoadingCache buildUnsafeCache(CacheBuilder super K, ? super V> cacheBuilder, CacheLoader super K, V> cacheLoader)
+ {
+ return cacheBuilder.build(cacheLoader);
+ }
+}
diff --git a/plugin/trino-accumulo/src/main/java/io/trino/plugin/accumulo/index/ColumnCardinalityCache.java b/plugin/trino-accumulo/src/main/java/io/trino/plugin/accumulo/index/ColumnCardinalityCache.java
index 595f3faf0c5a..e5fcadd3d07c 100644
--- a/plugin/trino-accumulo/src/main/java/io/trino/plugin/accumulo/index/ColumnCardinalityCache.java
+++ b/plugin/trino-accumulo/src/main/java/io/trino/plugin/accumulo/index/ColumnCardinalityCache.java
@@ -15,7 +15,6 @@
import com.google.common.cache.CacheBuilder;
import com.google.common.cache.CacheLoader;
-import com.google.common.cache.LoadingCache;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableMultimap;
import com.google.common.collect.Iterables;
@@ -27,6 +26,7 @@
import io.airlift.units.Duration;
import io.trino.plugin.accumulo.conf.AccumuloConfig;
import io.trino.plugin.accumulo.model.AccumuloColumnConstraint;
+import io.trino.plugin.base.cache.NonEvictableLoadingCache;
import io.trino.spi.TrinoException;
import org.apache.accumulo.core.client.BatchScanner;
import org.apache.accumulo.core.client.Connector;
@@ -63,6 +63,7 @@
import static io.trino.plugin.accumulo.index.Indexer.CARDINALITY_CQ_AS_TEXT;
import static io.trino.plugin.accumulo.index.Indexer.getIndexColumnFamily;
import static io.trino.plugin.accumulo.index.Indexer.getMetricsTableName;
+import static io.trino.plugin.base.cache.SafeCaches.buildNonEvictableCache;
import static io.trino.spi.StandardErrorCode.FUNCTION_IMPLEMENTATION_ERROR;
import static java.lang.Long.parseLong;
import static java.nio.charset.StandardCharsets.UTF_8;
@@ -83,7 +84,7 @@ public class ColumnCardinalityCache
private final Connector connector;
private final ExecutorService coreExecutor;
private final BoundedExecutor executorService;
- private final LoadingCache cache;
+ private final NonEvictableLoadingCache cache;
@Inject
public ColumnCardinalityCache(Connector connector, AccumuloConfig config)
@@ -97,10 +98,11 @@ public ColumnCardinalityCache(Connector connector, AccumuloConfig config)
this.executorService = new BoundedExecutor(coreExecutor, 4 * Runtime.getRuntime().availableProcessors());
LOG.debug("Created new cache size %d expiry %s", size, expireDuration);
- cache = CacheBuilder.newBuilder()
- .maximumSize(size)
- .expireAfterWrite(expireDuration.toMillis(), MILLISECONDS)
- .build(new CardinalityCacheLoader());
+ cache = buildNonEvictableCache(
+ CacheBuilder.newBuilder()
+ .maximumSize(size)
+ .expireAfterWrite(expireDuration.toMillis(), MILLISECONDS),
+ new CardinalityCacheLoader());
}
@PreDestroy
diff --git a/plugin/trino-base-jdbc/src/main/java/io/trino/plugin/jdbc/mapping/CachingIdentifierMapping.java b/plugin/trino-base-jdbc/src/main/java/io/trino/plugin/jdbc/mapping/CachingIdentifierMapping.java
index da6caaa579b0..544fa5b569e7 100644
--- a/plugin/trino-base-jdbc/src/main/java/io/trino/plugin/jdbc/mapping/CachingIdentifierMapping.java
+++ b/plugin/trino-base-jdbc/src/main/java/io/trino/plugin/jdbc/mapping/CachingIdentifierMapping.java
@@ -14,11 +14,11 @@
package io.trino.plugin.jdbc.mapping;
import com.google.common.base.CharMatcher;
-import com.google.common.cache.Cache;
import com.google.common.cache.CacheBuilder;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableSet;
+import io.trino.plugin.base.cache.NonKeyEvictableCache;
import io.trino.plugin.jdbc.BaseJdbcClient;
import io.trino.plugin.jdbc.mapping.IdentifierMappingModule.ForCachingIdentifierMapping;
import io.trino.spi.TrinoException;
@@ -43,6 +43,7 @@
import static com.google.common.base.MoreObjects.firstNonNull;
import static com.google.common.base.Preconditions.checkArgument;
import static com.google.common.base.Verify.verify;
+import static io.trino.plugin.base.cache.SafeCaches.buildNonEvictableCacheWithWeakInvalidateAll;
import static io.trino.plugin.jdbc.JdbcErrorCode.JDBC_ERROR;
import static java.util.Objects.requireNonNull;
import static java.util.concurrent.TimeUnit.MILLISECONDS;
@@ -50,8 +51,8 @@
public final class CachingIdentifierMapping
implements IdentifierMapping
{
- private final Cache remoteSchemaNames;
- private final Cache remoteTableNames;
+ private final NonKeyEvictableCache remoteSchemaNames;
+ private final NonKeyEvictableCache remoteTableNames;
private final IdentifierMapping identifierMapping;
private final Provider baseJdbcClient;
@@ -64,8 +65,8 @@ public CachingIdentifierMapping(
requireNonNull(mappingConfig, "mappingConfig is null");
CacheBuilder remoteNamesCacheBuilder = CacheBuilder.newBuilder()
.expireAfterWrite(mappingConfig.getCaseInsensitiveNameMatchingCacheTtl().toMillis(), MILLISECONDS);
- this.remoteSchemaNames = remoteNamesCacheBuilder.build();
- this.remoteTableNames = remoteNamesCacheBuilder.build();
+ this.remoteSchemaNames = buildNonEvictableCacheWithWeakInvalidateAll(remoteNamesCacheBuilder);
+ this.remoteTableNames = buildNonEvictableCacheWithWeakInvalidateAll(remoteNamesCacheBuilder);
this.identifierMapping = requireNonNull(identifierMapping, "identifierMapping is null");
this.baseJdbcClient = requireNonNull(baseJdbcClient, "baseJdbcClient is null");
diff --git a/plugin/trino-bigquery/pom.xml b/plugin/trino-bigquery/pom.xml
index 9e87257c4424..08ec9c0fd97b 100644
--- a/plugin/trino-bigquery/pom.xml
+++ b/plugin/trino-bigquery/pom.xml
@@ -54,6 +54,11 @@
+
+ io.trino
+ trino-plugin-toolkit
+
+
io.airlift
bootstrap
diff --git a/plugin/trino-bigquery/src/main/java/io/trino/plugin/bigquery/BigQueryClientFactory.java b/plugin/trino-bigquery/src/main/java/io/trino/plugin/bigquery/BigQueryClientFactory.java
index f45bbac4e556..316d8778534e 100644
--- a/plugin/trino-bigquery/src/main/java/io/trino/plugin/bigquery/BigQueryClientFactory.java
+++ b/plugin/trino-bigquery/src/main/java/io/trino/plugin/bigquery/BigQueryClientFactory.java
@@ -18,8 +18,8 @@
import com.google.auth.oauth2.ServiceAccountCredentials;
import com.google.cloud.bigquery.BigQuery;
import com.google.cloud.bigquery.BigQueryOptions;
-import com.google.common.cache.Cache;
import com.google.common.cache.CacheBuilder;
+import io.trino.plugin.base.cache.NonEvictableCache;
import io.trino.spi.connector.ConnectorSession;
import javax.inject.Inject;
@@ -27,6 +27,7 @@
import java.util.Optional;
import java.util.concurrent.ExecutionException;
+import static io.trino.plugin.base.cache.SafeCaches.buildNonEvictableCache;
import static java.util.Objects.requireNonNull;
import static java.util.concurrent.TimeUnit.MILLISECONDS;
@@ -37,7 +38,7 @@ public class BigQueryClientFactory
private final BigQueryConfig bigQueryConfig;
private final ViewMaterializationCache materializationCache;
private final HeaderProvider headerProvider;
- private final Cache clientCache;
+ private final NonEvictableCache clientCache;
@Inject
public BigQueryClientFactory(
@@ -56,7 +57,7 @@ public BigQueryClientFactory(
CacheBuilder cacheBuilder = CacheBuilder.newBuilder()
.expireAfterWrite(bigQueryConfig.getServiceCacheTtl().toMillis(), MILLISECONDS);
- clientCache = cacheBuilder.build();
+ clientCache = buildNonEvictableCache(cacheBuilder);
}
public BigQueryClient create(ConnectorSession session)
diff --git a/plugin/trino-bigquery/src/main/java/io/trino/plugin/bigquery/ViewMaterializationCache.java b/plugin/trino-bigquery/src/main/java/io/trino/plugin/bigquery/ViewMaterializationCache.java
index 0c047633f8d0..d339929be26f 100644
--- a/plugin/trino-bigquery/src/main/java/io/trino/plugin/bigquery/ViewMaterializationCache.java
+++ b/plugin/trino-bigquery/src/main/java/io/trino/plugin/bigquery/ViewMaterializationCache.java
@@ -21,10 +21,10 @@
import com.google.cloud.bigquery.Table;
import com.google.cloud.bigquery.TableId;
import com.google.cloud.bigquery.TableInfo;
-import com.google.common.cache.Cache;
import com.google.common.cache.CacheBuilder;
import io.airlift.log.Logger;
import io.airlift.units.Duration;
+import io.trino.plugin.base.cache.NonEvictableCache;
import io.trino.spi.TrinoException;
import io.trino.spi.connector.SchemaTableName;
import io.trino.spi.connector.TableNotFoundException;
@@ -35,6 +35,7 @@
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
+import static io.trino.plugin.base.cache.SafeCaches.buildNonEvictableCache;
import static io.trino.plugin.bigquery.BigQueryErrorCode.BIGQUERY_VIEW_DESTINATION_TABLE_CREATION_FAILED;
import static io.trino.plugin.bigquery.BigQueryUtil.convertToBigQueryException;
import static java.lang.String.format;
@@ -47,7 +48,7 @@ public class ViewMaterializationCache
{
private static final Logger log = Logger.get(ViewMaterializationCache.class);
- private final Cache destinationTableCache;
+ private final NonEvictableCache destinationTableCache;
private final Optional viewMaterializationProject;
private final Optional viewMaterializationDataset;
@@ -55,10 +56,10 @@ public class ViewMaterializationCache
public ViewMaterializationCache(BigQueryConfig config)
{
requireNonNull(config, "config is null");
- this.destinationTableCache = CacheBuilder.newBuilder()
- .expireAfterWrite(config.getViewsCacheTtl().toMillis(), MILLISECONDS)
- .maximumSize(1000)
- .build();
+ this.destinationTableCache = buildNonEvictableCache(
+ CacheBuilder.newBuilder()
+ .expireAfterWrite(config.getViewsCacheTtl().toMillis(), MILLISECONDS)
+ .maximumSize(1000));
this.viewMaterializationProject = config.getViewMaterializationProject();
this.viewMaterializationDataset = config.getViewMaterializationDataset();
}
diff --git a/plugin/trino-google-sheets/src/main/java/io/trino/plugin/google/sheets/SheetsClient.java b/plugin/trino-google-sheets/src/main/java/io/trino/plugin/google/sheets/SheetsClient.java
index f61c7ea79ae1..65c332cf1b1f 100644
--- a/plugin/trino-google-sheets/src/main/java/io/trino/plugin/google/sheets/SheetsClient.java
+++ b/plugin/trino-google-sheets/src/main/java/io/trino/plugin/google/sheets/SheetsClient.java
@@ -21,13 +21,13 @@
import com.google.api.services.sheets.v4.SheetsScopes;
import com.google.common.cache.CacheBuilder;
import com.google.common.cache.CacheLoader;
-import com.google.common.cache.LoadingCache;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableSet;
import com.google.common.util.concurrent.UncheckedExecutionException;
import io.airlift.json.JsonCodec;
import io.airlift.log.Logger;
+import io.trino.plugin.base.cache.NonEvictableLoadingCache;
import io.trino.spi.TrinoException;
import io.trino.spi.type.VarcharType;
@@ -46,8 +46,8 @@
import static com.google.api.client.googleapis.javanet.GoogleNetHttpTransport.newTrustedTransport;
import static com.google.common.base.Throwables.throwIfInstanceOf;
-import static com.google.common.cache.CacheLoader.from;
import static com.google.common.collect.ImmutableList.toImmutableList;
+import static io.trino.plugin.base.cache.SafeCaches.buildNonEvictableCache;
import static io.trino.plugin.google.sheets.SheetsErrorCode.SHEETS_BAD_CREDENTIALS_ERROR;
import static io.trino.plugin.google.sheets.SheetsErrorCode.SHEETS_METASTORE_ERROR;
import static io.trino.plugin.google.sheets.SheetsErrorCode.SHEETS_TABLE_LOAD_ERROR;
@@ -65,8 +65,8 @@ public class SheetsClient
private static final List SCOPES = ImmutableList.of(SheetsScopes.SPREADSHEETS_READONLY);
- private final LoadingCache> tableSheetMappingCache;
- private final LoadingCache>> sheetDataCache;
+ private final NonEvictableLoadingCache> tableSheetMappingCache;
+ private final NonEvictableLoadingCache>> sheetDataCache;
private final String metadataSheetId;
private final String credentialsFilePath;
@@ -91,8 +91,9 @@ public SheetsClient(SheetsConfig config, JsonCodec