static class TimedCache { long timeout; A value; long set; // stats int stores, fails, hits; // 0 = no timeout *(double timeoutSeconds) { timeout = toMS(timeoutSeconds); } synchronized A set(A a) { ++stores; value = a; set = now(); ret a; } synchronized bool has() { clean(); if (set != 0) { ++hits; true; } ++fails; false; } synchronized A get() { clean(); if (set != 0) ++hits; else ++fails; ret value; } synchronized A get(O makerFunction) { if (has()) ret getNoClean(); A a = cast callF(makerFunction); ret set(a); } synchronized A getNoClean() { ret value; } // clear if timed out synchronized void clean() { if (timeout > 0 && now() > set+timeout) clear(); } // clear now synchronized void clear() { set = 0; value = null; } synchronized S stats() { ret "Stores: " + stores + ", hits: " + hits + ", fails: " + fails; } }