如何解决当您必须从数据中提供多个结果时,如何最佳地使用 Guava Cache?
我有一个缓存加载器,它缓存来自 API 的响应(以列表的形式)。现在我的函数不需要直接响应数据,所以我创建了一个提供程序,它可以处理这些原始响应并充当预言机,允许我发送所需的数据而不是整个列表。
我当前方法的问题是,对于每个这样的响应,即使列表与以前相同,提供者也必须遍历整个列表;这使得每次调用的复杂度为 O(n) 而不是我想要的 O(1)。
我能想到的潜在解决方案
- 改为缓存已处理的数据。现在的问题是,在这种情况下我需要两个不同的缓存,并且每次刷新都会从 API 中不必要地从两个缓存中获取相同的结果。
- 仅在缓存值已更改时才在提供程序中迭代 我想这样做,但我找不到一种方法来知道缓存是否更改了值,我所有的方法都需要传递再次花费 O(n) 时间的数据。
规则信息缓存加载器类
import com.google.common.cache.CacheLoader;
import java.util.List;
import java.util.concurrent.TimeUnit;
import javax.annotation.ParametersAreNonnullByDefault;
final class RuleInfoLoader extends CacheLoader<RuleType,List<RuleInfo>> {
private final ConfigServiceGrpc.ConfigServiceBlockingStub configServiceBlockingStub;
private final long callTimeout;
RuleInfoLoader(ConfigServiceClientConfig clientConfig) {
callTimeout = clientConfig.getCallTimeout();
configServiceBlockingStub = ConfigServiceGrpc.newBlockingStub();
}
@Override
@ParametersAreNonnullByDefault
public List<RuleInfo> load(RuleType ruleType) {
return fetchRuleInfo(ruleType);
}
private List<RuleInfo> fetchRuleInfo(RuleType ruleType) {
return configServiceBlockingStub
.withDeadlineAfter(callTimeout,TimeUnit.MILLISECONDS)
.getAnomalyRuleInfos(
GetRuleInfosRequest.newBuilder().setRuleType(ruleType).build())
.getRuleInfosList();
}
}
规则信息提供者
import com.google.common.cache.CacheLoader;
import com.google.common.collect.ImmutableMap;
import com.typesafe.config.Config;
import java.util.Collections;
import java.util.List;
import java.util.concurrent.Executors;
import java.util.stream.Collectors;
public class RuleInfoProvider {
private LoadingCache<RuleType,List<RuleInfo>> ruleInfoCache;
public RuleInfoProvider(Config config) {
initCache(config);
}
public Map<String,RuleInfo> getRuleMapping() {
ImmutableMap.Builder<String,RuleInfo> mapBuilder = new ImmutableMap.Builder<>();
getRuleInfo(RuleType.a)
.forEach(rule -> mapBuilder.put(rule.getRuleId(),rule));
getRuleInfo(RuleType.b)
.forEach(rule -> mapBuilder.put(rule.getRuleId(),rule));
getRuleInfo(RuleType.c)
.forEach(rule -> mapBuilder.put(rule.getRuleId(),rule));
return mapBuilder.build();
}
public Map<Class<? extends RuleInfo>,List<String>> getPathsMapping() {
return new ImmutableMap.Builder<Class<? extends RuleInfo>,List<String>>()
.put(
Class_A.class,getRuleInfo(RuleType.a).stream()
.map(RuleInfo::getPath)
.collect(Collectors.toList()))
.put(
Class_B.class,getRuleInfo(RuleType.b).stream()
.map(RuleInfo::getPath)
.collect(Collectors.toList()))
.put(
Class_c.class,getRuleInfo(RuleType.c).stream()
.map(RuleInfo::getPath)
.collect(Collectors.toList()))
.build();
}
private List<RuleInfo> getRuleInfo(RuleType ruleType) {
try {
return ruleInfoCache.get(ruleType);
} catch (Exception e) {
return Collections.emptyList();
}
}
private void initCache(Config config) {
ruleInfoCache =
CacheBuilder.newBuilder()
.refreshAfterWrite(config.getCacheConfig().getRefreshMs())
.maximumSize(config.getCacheConfig().getMaxSize())
.build(
CacheLoader.asyncReloading(
new RuleInfoLoader(config.getConfigServiceClientConfig()),Executors.newSingleThreadScheduledExecutor()));
}
}
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。