package voldemort.utils;


import voldemort.annotations.concurrency.Threadsafe;

import java.util.concurrent.Callable;
import java.util.concurrent.atomic.AtomicReference;

@Threadsafe
public class CachedCallable<T> implements Callable<T> {

    private final Callable<T> inner;
    private final long ttlMs;
    private final AtomicReference<T> valueRef;

    private volatile long lastCalledMs;

    public CachedCallable(Callable<T> inner,
                          long ttlMs) {
        this.inner = inner;
        this.ttlMs = ttlMs;
        valueRef = new AtomicReference<T>();
    }


    public T call() throws Exception {
        T value = valueRef.get();
        long now = System.currentTimeMillis();
        if(value == null || now - lastCalledMs > ttlMs) {
            T newValue = inner.call();
            if(valueRef.compareAndSet(value, newValue)) {
                lastCalledMs = now;
                return newValue;
            }
        }
        return valueRef.get();
    }
}

Create a cached callable for caching expensive stats
Create a cached callable for caching expensive stats
