package cm.android.sdk.v4;
import android.os.SystemClock;
import android.support.v4.util.ArrayMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;
public class ExpirableLruCache<K, V> {
public static final class Builder<K, V> {
private long expire;
private int maxSize;
public Builder() {
expire = TimeUnit.HOURS.toMillis(6);
maxSize = 100;
}
public Builder<K, V> expire(long duration, TimeUnit unit) {
if (duration < 0) {
throw new IllegalArgumentException("duration < 0");
}
if (unit == null) {
throw new NullPointerException("unit == null");
}
this.expire = unit.toMillis(duration);
return this;
}
public Builder<K, V> maxSize(int maxSize) {
if (maxSize < 0) {
throw new IllegalArgumentException("maxSize < 0");
}
this.maxSize = maxSize;
return this;
}
public ExpirableLruCache<K, V> build() {
return new ExpirableLruCache<>(this);
}
}
private static final class Expire<K> {
private final Map<K, Long> timestamp = new ArrayMap<>();
private long expire;
void put(K key) {
timestamp.put(key, elapsedRealtime() + expire);
}
void setExpire(long expire) {
this.expire = expire;
}
private long elapsedRealtime() {
return SystemClock.elapsedRealtime();
}
boolean isExpired(K key) {
Long t = timestamp.get(key);
if (t != null && elapsedRealtime() >= t) {
return true;
}
return false;
}
void remove(K key) {
timestamp.remove(key);
}
}
private android.support.v4.util.LruCache<K, V> cache;
private Expire<K> expire = new Expire<>();
public ExpirableLruCache(Builder builder) {
cache = new android.support.v4.util.LruCache<K, V>(builder.maxSize) {
@Override
public int sizeOf(K key, V value) {
return super.sizeOf(key, value);
}
@Override
protected void entryRemoved(boolean evicted, K key, V oldValue, V newValue) {
super.entryRemoved(evicted, key, oldValue, newValue);
expire.remove(key);
}
};
expire.setExpire(builder.expire);
}
public void put(K key, V value) {
expire.put(key);
cache.put(key, value);
}
public V get(K key) {
if (isExpired(key)) {
remove(key);
return null;
}
return cache.get(key);
}
public void remove(K key) {
cache.remove(key);
}
public void evictAll() {
cache.evictAll();
}
public boolean isExpired(K key) {
return expire.isExpired(key);
}
public long size() {
return cache.size();
}
public long maxSize() {
return cache.maxSize();
}
}