java如何在番石榴缓存中存储地图
我有一个Map<Range<Double>, String>
检查特定Double
值(分数)映射到String
(级别)的位置。最终用户希望能够动态更改此映射,从长远来看,我们希望有一个基于web的GUI
,他们可以控制此映射,但从短期来看,他们很高兴文件位于S3
中,并在需要更改时对其进行编辑。我不想为每个请求点击S3
,而是想缓存它,因为它不会太频繁地更改(大约一周一次)。我也不想改变代码,取消我的服务
以下是我的想法-
public class Mapper() {
private LoadingCache<Score, String> scoreToLevelCache;
public Mapper() {
scoreToLevelCache = CacheBuilder.newBuilder()
.expireAfterWrite(10, TimeUnit.MINUTES)
.build(new CacheLoader<Score, String>() {
public String load(Score score) {
Map<Range<Double>, String> scoreToLevelMap = readMappingFromS3(); //readMappingFromS3 omitted for brevity
for(Range<Double> key : scoreToLevelMap.keySet()) {
if(key.contains(score.getCount())) { return scoreToLevelMap.get(key); }
}
throw new IllegalArgumentException("The score couldn't be mapped to a level. Either the score passed in was incorrect or the mapping is incorrect");
}
});
}
public String getContentLevelForScore(Score Score) {
try {
return scoreToLevelCache.get(Score);
} catch (ExecutionException e) { throw new InternalServerException(e); }
}
}
这种方法的明显问题在于load
方法
Map<Range<Double>, String> scoreToLevelMap = readMappingFromS3();
对于每个键,我都会一遍又一遍地加载整个地图。这不是一个性能问题,但当规模增加时,它可能会成为一个问题,无论如何,这不是一个有效的方法
我认为把整个地图保存在缓存中会更好,但我不知道该怎么做。有人能帮上忙吗,或者提出一种更优雅的方法来实现这一点
# 1 楼答案
番石榴对“只包含一个值的缓存”有不同的机制;它叫^{}
# 2 楼答案
这里有一个解决方案,可以一次读取整个地图,并通过asyncReloading保持refreshing it asynchronouzly as needed
它将在refresh期间返回旧值,而不会阻塞多个读卡器线程,比如
Suppliers.memoizeWithExpiration
does还考虑用RangeMap^ {CD3>}替换^ {< CD2>}以执行有效的远程查找。