// (c) Tuomas J. Lukka package org.fenfire.functional; import java.util.*; import org.nongnu.libvob.util.CachingMap; import org.nongnu.libvob.util.Background; import org.fenfire.*; import org.fenfire.util.*; import org.fenfire.swamp.*; /** A super-lazy node function: caches values from another function, * and for uncached values returns a placeholder value and initializes * a background computation. *

* This function only caches pure node functions but is not a pure * node function itself as it returns the placeholder value. */ public class SuperLazyPureNodeFunction extends SuperLazyBase implements NodeFunction { ConstGraph ourGraph; PureNodeFunction f; /** Create a new SuperLazyPureNodeFunction. * @param n The number of cache entries to use * @param g The constgraph to cache using * @param f The pure node function whose values we are caching * @param placeHolder The value to return when no function value * has been precalculated. * @param background The object to use for the background calculations. * @param recalcObs The observer to call whenever a new value * has been calculated */ public SuperLazyPureNodeFunction(int n, ConstGraph g, PureNodeFunction f, Object placeHolder, Background background, ObjObs recalcObs ) { super(n, placeHolder, background, recalcObs); this.ourGraph = g; this.f = f; } private class SuperLazyNodeFunctionCacheEntry extends CacheEntry { public SuperLazyNodeFunctionCacheEntry(Object input) { super(input); } public void run() { if(this.value != DIRTY) return; synchronized(this) { ConstGraph og = (ourGraph == null ? null : ourGraph.getObservedConstGraph(this)); this.value = f.f(og, this.input); if(og != null) og.close(); } if(recalcObs != null) recalcObs.chg(this.input); } } public Object f(ConstGraph g, Object node) { Obs o = null; if(g != ourGraph) { o = g.getObserver(); g = g.getOriginalConstGraph(); if(g != ourGraph) throw new IllegalArgumentException("Called with wrong graph"); } SuperLazyNodeFunctionCacheEntry cac = (SuperLazyNodeFunctionCacheEntry)cache.get(node); if(cac == null) { cac = new SuperLazyNodeFunctionCacheEntry(node); cache.put(node, cac); } synchronized(cac) { if(o != null) cac.addObs(o); return cac.getValueAndSchedule(); } } }