package com.stardust.util;
import java.util.Iterator;
import java.util.Map;
import java.util.Timer;
import java.util.TimerTask;
/**
* Created by Stardust on 2017/4/5.
*/
public class SimpleCache<T> {
public interface Supplier<T> {
T get(String key);
}
private long mPersistTime;
private LimitedHashMap<String, Item<T>> mCache;
private Timer mCacheCheckTimer;
private Supplier<T> mSupplier;
public SimpleCache(long persistTime, int cacheSize, long checkInterval, Supplier<T> supplier) {
mPersistTime = persistTime;
mCache = new LimitedHashMap<>(cacheSize);
mSupplier = supplier == null ? new NullSupplier<T>() : supplier;
mCacheCheckTimer = new Timer();
startCacheCheck(checkInterval);
}
public SimpleCache(long persistTime, int cacheSize, long checkInterval) {
this(persistTime, cacheSize, checkInterval, null);
}
public synchronized void put(String key, T value) {
mCache.put(key, new Item<>(value));
}
public synchronized T get(String key) {
Item<T> item = mCache.get(key);
if (item == null) {
T value = mSupplier.get(key);
if (value != null) {
put(key, value);
}
return value;
}
return item.value;
}
public T get(String key, T defaultValue) {
T value = get(key);
if (value == null) {
value = defaultValue;
}
return value;
}
public T get(String key, Supplier<T> supplier) {
T value = get(key);
if (value == null) {
value = supplier.get(key);
put(key, value);
}
return value;
}
public synchronized void destroy() {
mCacheCheckTimer.cancel();
mCache.clear();
}
private void startCacheCheck(long checkInterval) {
mCacheCheckTimer.schedule(new TimerTask() {
@Override
public void run() {
checkCache();
}
}, 0, checkInterval);
}
private synchronized void checkCache() {
Iterator<Map.Entry<String, Item<T>>> iterator = mCache.entrySet().iterator();
while (iterator.hasNext()) {
if (!iterator.next().getValue().isValid()) {
iterator.remove();
}
}
}
private class Item<T> {
T value;
private long mSaveMillis;
Item(T value) {
mSaveMillis = System.currentTimeMillis();
this.value = value;
}
boolean isValid() {
return System.currentTimeMillis() - mSaveMillis <= mPersistTime;
}
}
private static class NullSupplier<T> implements Supplier<T> {
@Override
public T get(String key) {
return null;
}
}
}