On Saturday, August 25, 2012 12:09:11 AM UTC+2, Louis Wasserman wrote:
> Putting it another way: "A single method like `CacheLoader.load` surely can't suffice." What would you prefer?
The problem with `load` is that it must not call `cache.get` if we want to prevent stack overflow.
> I'm just not seeing what other methods would possibly be of use in this scenario.
You need something to break the recursion. I see two possibilities, both of them quite simple.
1. GET-OR-REQUEST
This was one of my first ideas:
public Integer load(Integer key) throws Exception {
if (key<=1) return 1;
Integer x1 = cache.getOrRequest(key-1, key);
Integer x2 = cache.getOrRequest(key-2, key);
return x1==null || x2==null ? null : x1+x2;
}
where `getOrRequest(x, master)` is similar to `getIfPresent(x)`. In case it returns `null`, it records that the value for `x` was requested when computing the value for `master`. If `load` returns null, the cache processes the requests iteratively, and finally calls `load(key)` again.
There would be something like `public final class ComputingCache extends AbstractLoadingCache` with this single additional method and the `CacheLoader` would be allowed to return `null` if used for the `ComputingCache`.
2. TWO-PHASE-LOADER
A more structured approach was given in
Basically, the `TwoPhaseLoader` has two methods, one for determining its dependencies, the other for computing the value when they're satisfied. Concerning the cache, nothing but a new private implementation is needed. His idea is nice, but it has some weaknesses, e.g. it's can't handle complicated recursion like
REMARKS
That all can be done on top of Guava, no changes are required. If it were part of Guava, then there could be some support in `CacheBuilder`, possibly also allowing to throw in some `ExecutorService`, that's all.