如何在Guava缓存中存储Map

nik*_*hil 6 java caching dictionary guava

我有一个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); }
  } 
}
Run Code Online (Sandbox Code Playgroud)

这种方法的明显问题在于load我做的方法 Map<Range<Double>, String> scoreToLevelMap = readMappingFromS3(); 对于每个键,我一遍又一遍地加载整个地图.这不是性能问题,但是当尺寸增加时它可能成为一个,无论如何这不是一种有效的方法.

我认为将整个地图保留在缓存中会更好,但我不知道该怎么做.任何人都可以帮助这个或建议一个更优雅的方式来实现这一目标.

Dav*_*vid 6

Guava对"只包含一个值的缓存"有不同的机制; 它被称为Suppliers.memoizeWithExpiration.

private Supplier<Map<Range<Double>, String> cachedMap = 
    Suppliers.memoizeWithExpiration(
        new Supplier<Map<Range<Double>, String>() {
            public Map<Range<Double>, String> get() {
                return readMappingFromS3();
            }
        }, 10, TimeUnit.MINUTES);

public String getContentLevelForScore(Score score) {
    Map<Range<Double>, String> scoreMap = cachedMap.get();
    // etc.
}
Run Code Online (Sandbox Code Playgroud)