How do I store a Map in a Guava Cache
Guava has a different mechanism for "a cache that only ever contains one value"; it's called 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.
}
Do not mix caching and business logic. Unless your score mapping is huge AND you can load individual pieces, e.g. using readMappingFromS3(Double d) - simply cache the whole map.
public static final String MAGIC_WORD = "oh please please give me my data!!!";
private final LoadingCache<String, Map<Range<Double>, String>> scoreToLevelCache;
public Mapper() {
scoreToLevelCache = CacheBuilder.newBuilder()
.expireAfterWrite(10, TimeUnit.MINUTES)
.build(new CacheLoader<String, Map<Range<Double>, String>>() {
public Map<Range<Double>, String> load(String score) {
return readMappingFromS3(); //readMappingFromS3 omitted for brevity
}
});
}
public Map<Range<Double>, String> getScoreMap() {
try {
return scoreToLevelCache.get(MAGIC_WORD);
} catch (ExecutionException e) {
throw new InternalServerException(e);
}
}
Fetch level name like this
public String findLevel(final Double score) {
final Map<Range<Double>, String> scoreMap = getScoreMap();
for (final Range<Double> key : scoreMap.keySet()) {
if (key.contains(score)) {
return scoreMap.get(key);
}
}
...
}