LruCache.java
/*
* Decompiled with CFR 0_132.
*/
package org.xutils.cache;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Set;
public class LruCache<K, V> {
private final LinkedHashMap<K, V> map;
private int size;
private int maxSize;
private int putCount;
private int createCount;
private int evictionCount;
private int hitCount;
private int missCount;
public LruCache(int maxSize) {
if (maxSize <= 0) {
throw new IllegalArgumentException("maxSize <= 0");
}
this.maxSize = maxSize;
this.map = new LinkedHashMap(0, 0.75f, true);
}
/*
* WARNING - Removed try catching itself - possible behaviour change.
*/
public void resize(int maxSize) {
if (maxSize <= 0) {
throw new IllegalArgumentException("maxSize <= 0");
}
LruCache lruCache = this;
synchronized (lruCache) {
this.maxSize = maxSize;
}
this.trimToSize(maxSize);
}
/*
* WARNING - Removed try catching itself - possible behaviour change.
*/
public final V get(K key) {
V mapValue;
if (key == null) {
throw new NullPointerException("key == null");
}
LruCache lruCache = this;
synchronized (lruCache) {
mapValue = this.map.get(key);
if (mapValue != null) {
++this.hitCount;
return mapValue;
}
++this.missCount;
}
V createdValue = this.create(key);
if (createdValue == null) {
return null;
}
LruCache lruCache2 = this;
synchronized (lruCache2) {
++this.createCount;
mapValue = this.map.put(key, createdValue);
if (mapValue != null) {
this.map.put(key, mapValue);
} else {
this.size += this.safeSizeOf(key, createdValue);
}
}
if (mapValue != null) {
this.entryRemoved(false, key, createdValue, mapValue);
return mapValue;
}
this.trimToSize(this.maxSize);
return createdValue;
}
/*
* WARNING - Removed try catching itself - possible behaviour change.
*/
public final V put(K key, V value) {
V previous;
if (key == null || value == null) {
throw new NullPointerException("key == null || value == null");
}
LruCache lruCache = this;
synchronized (lruCache) {
++this.putCount;
this.size += this.safeSizeOf(key, value);
previous = this.map.put(key, value);
if (previous != null) {
this.size -= this.safeSizeOf(key, previous);
}
}
if (previous != null) {
this.entryRemoved(false, key, previous, value);
}
this.trimToSize(this.maxSize);
return previous;
}
/*
* WARNING - Removed try catching itself - possible behaviour change.
*/
public void trimToSize(int maxSize) {
do {
V value;
K key;
LruCache lruCache = this;
synchronized (lruCache) {
if (this.size < 0 || this.map.isEmpty() && this.size != 0) {
throw new IllegalStateException(this.getClass().getName() + ".sizeOf() is reporting inconsistent results!");
}
if (this.size <= maxSize || this.map.isEmpty()) {
break;
}
Map.Entry<K, V> toEvict = this.map.entrySet().iterator().next();
key = toEvict.getKey();
value = toEvict.getValue();
this.map.remove(key);
this.size -= this.safeSizeOf(key, value);
++this.evictionCount;
}
this.entryRemoved(true, key, value, null);
} while (true);
}
/*
* WARNING - Removed try catching itself - possible behaviour change.
*/
public final V remove(K key) {
V previous;
if (key == null) {
throw new NullPointerException("key == null");
}
LruCache lruCache = this;
synchronized (lruCache) {
previous = this.map.remove(key);
if (previous != null) {
this.size -= this.safeSizeOf(key, previous);
}
}
if (previous != null) {
this.entryRemoved(false, key, previous, null);
}
return previous;
}
protected void entryRemoved(boolean evicted, K key, V oldValue, V newValue) {
}
protected V create(K key) {
return null;
}
private int safeSizeOf(K key, V value) {
int result = this.sizeOf(key, value);
if (result < 0) {
throw new IllegalStateException("Negative size: " + key + "=" + value);
}
return result;
}
protected int sizeOf(K key, V value) {
return 1;
}
public final void evictAll() {
this.trimToSize(-1);
}
public final synchronized int size() {
return this.size;
}
public final synchronized int maxSize() {
return this.maxSize;
}
public final synchronized int hitCount() {
return this.hitCount;
}
public final synchronized int missCount() {
return this.missCount;
}
public final synchronized int createCount() {
return this.createCount;
}
public final synchronized int putCount() {
return this.putCount;
}
public final synchronized int evictionCount() {
return this.evictionCount;
}
public final synchronized Map<K, V> snapshot() {
return new LinkedHashMap<K, V>(this.map);
}
public final synchronized String toString() {
int accesses = this.hitCount + this.missCount;
int hitPercent = accesses != 0 ? 100 * this.hitCount / accesses : 0;
return String.format("LruCache[maxSize=%d,hits=%d,misses=%d,hitRate=%d%%]", this.maxSize, this.hitCount, this.missCount, hitPercent);
}
}