Closed sunshio closed 5 months ago
In Jimmer, SubKey must be the JSON-serialized string of java.util.SortedMap<String, Object>. This SortedMap must use the default sorting rule without custom Comparator. ... When invalidating cache, Jimmer will automatically delete invalid cached by key. Cached items of multi-view cache are always deleted as a whole based on Key rather than partially based on Key + SubKey, to maximize the relative simplicity of multi-view cache.
This means it is a Cache<Key, SortedMap<SubKey, Value>>
, so that eviction / invalidation removes the key and sub-map. Likely one would want to bound the maximum size by the number of sub-map entries, so a weigher could be used in these cases. Those APIs don't specify if the sub-map can be modified, but for simpler concurrency I would treat it as a copy-on-write map.
Cache<Key, SortedMap<SubKey, Value>> multiViewCache = Caffeine.newBuilder()
.expireAfterWrite(Duration.ofMinutes(10))
.weigher((key, submap) -> submap.size())
.maximumWeight(10_000)
.build();
// get a subKey entry
var value = multiViewCache.asMap().getOrDefault(key, Collections.emptySortedMap()).get(subKey);
// add an subKey entry
multiViewCache.asMap().compute((key, submap) -> {
var map = (submap == null) ? new TreeMap<> : new TreeMap<>(submap);
map.put(subKey, value);
return Collections.unmodifiableSortedMap(submap);
});
// remove a subKey entry
multiViewCache.asMap().computeIfPresent((key, submap) -> {
if (!submap.containsKey(subKey)) {
return submap;
} else if (submap.size() == 1) {
return null;
}
var map = new TreeMap<>(submap);
map.remove(subKey);
return Collections.unmodifiableSortedMap(map);
});
This would lead to locks with exceedingly coarse granularity, and there is no eviction mechanism for the keys of the submap.
The eviction follows what the Jimmer documentation states for eviction, so that's following their expectations.
For locking, while it would be coarse as by Key, the operations are very fast since they are in-memory operations without I/O. That allows for a very high throughput of writes so I don't think that should cause a problem.
NestedCache<String, String, Object> cache = ...
cache.put("x", "y", 0)