200 lines
5.4 KiB
Java
200 lines
5.4 KiB
Java
package androidx.collection;
|
|
|
|
import androidx.annotation.NonNull;
|
|
import androidx.annotation.Nullable;
|
|
import java.util.LinkedHashMap;
|
|
import java.util.Locale;
|
|
import java.util.Map;
|
|
import java.util.Objects;
|
|
public class LruCache<K, V> {
|
|
private int createCount;
|
|
private int evictionCount;
|
|
private int hitCount;
|
|
private final LinkedHashMap<K, V> map;
|
|
private int maxSize;
|
|
private int missCount;
|
|
private int putCount;
|
|
private int size;
|
|
|
|
public LruCache(int i) {
|
|
if (i > 0) {
|
|
this.maxSize = i;
|
|
this.map = new LinkedHashMap<>(0, 0.75f, true);
|
|
return;
|
|
}
|
|
throw new IllegalArgumentException("maxSize <= 0");
|
|
}
|
|
|
|
private int safeSizeOf(K k, V v) {
|
|
int sizeOf = sizeOf(k, v);
|
|
if (sizeOf >= 0) {
|
|
return sizeOf;
|
|
}
|
|
throw new IllegalStateException("Negative size: " + ((Object) k) + "=" + ((Object) v));
|
|
}
|
|
|
|
@Nullable
|
|
public V create(@NonNull K k) {
|
|
return null;
|
|
}
|
|
|
|
public final synchronized int createCount() {
|
|
return this.createCount;
|
|
}
|
|
|
|
public void entryRemoved(boolean z2, @NonNull K k, @NonNull V v, @Nullable V v2) {
|
|
}
|
|
|
|
public final void evictAll() {
|
|
trimToSize(-1);
|
|
}
|
|
|
|
public final synchronized int evictionCount() {
|
|
return this.evictionCount;
|
|
}
|
|
|
|
@Nullable
|
|
public final V get(@NonNull K k) {
|
|
V put;
|
|
Objects.requireNonNull(k, "key == null");
|
|
synchronized (this) {
|
|
V v = this.map.get(k);
|
|
if (v != null) {
|
|
this.hitCount++;
|
|
return v;
|
|
}
|
|
this.missCount++;
|
|
}
|
|
V create = create(k);
|
|
if (create == null) {
|
|
return null;
|
|
}
|
|
synchronized (this) {
|
|
this.createCount++;
|
|
put = this.map.put(k, create);
|
|
if (put != null) {
|
|
this.map.put(k, put);
|
|
} else {
|
|
this.size += safeSizeOf(k, create);
|
|
}
|
|
}
|
|
if (put != null) {
|
|
entryRemoved(false, k, create, put);
|
|
return put;
|
|
}
|
|
trimToSize(this.maxSize);
|
|
return create;
|
|
}
|
|
|
|
public final synchronized int hitCount() {
|
|
return this.hitCount;
|
|
}
|
|
|
|
public final synchronized int maxSize() {
|
|
return this.maxSize;
|
|
}
|
|
|
|
public final synchronized int missCount() {
|
|
return this.missCount;
|
|
}
|
|
|
|
@Nullable
|
|
public final V put(@NonNull K k, @NonNull V v) {
|
|
V put;
|
|
if (k == null || v == null) {
|
|
throw new NullPointerException("key == null || value == null");
|
|
}
|
|
synchronized (this) {
|
|
this.putCount++;
|
|
this.size += safeSizeOf(k, v);
|
|
put = this.map.put(k, v);
|
|
if (put != null) {
|
|
this.size -= safeSizeOf(k, put);
|
|
}
|
|
}
|
|
if (put != null) {
|
|
entryRemoved(false, k, put, v);
|
|
}
|
|
trimToSize(this.maxSize);
|
|
return put;
|
|
}
|
|
|
|
public final synchronized int putCount() {
|
|
return this.putCount;
|
|
}
|
|
|
|
@Nullable
|
|
public final V remove(@NonNull K k) {
|
|
V remove;
|
|
Objects.requireNonNull(k, "key == null");
|
|
synchronized (this) {
|
|
remove = this.map.remove(k);
|
|
if (remove != null) {
|
|
this.size -= safeSizeOf(k, remove);
|
|
}
|
|
}
|
|
if (remove != null) {
|
|
entryRemoved(false, k, remove, null);
|
|
}
|
|
return remove;
|
|
}
|
|
|
|
public void resize(int i) {
|
|
if (i > 0) {
|
|
synchronized (this) {
|
|
this.maxSize = i;
|
|
}
|
|
trimToSize(i);
|
|
return;
|
|
}
|
|
throw new IllegalArgumentException("maxSize <= 0");
|
|
}
|
|
|
|
public final synchronized int size() {
|
|
return this.size;
|
|
}
|
|
|
|
public int sizeOf(@NonNull K k, @NonNull V v) {
|
|
return 1;
|
|
}
|
|
|
|
public final synchronized Map<K, V> snapshot() {
|
|
return new LinkedHashMap(this.map);
|
|
}
|
|
|
|
public final synchronized String toString() {
|
|
int i;
|
|
int i2;
|
|
i = this.hitCount;
|
|
i2 = this.missCount + i;
|
|
return String.format(Locale.US, "LruCache[maxSize=%d,hits=%d,misses=%d,hitRate=%d%%]", Integer.valueOf(this.maxSize), Integer.valueOf(this.hitCount), Integer.valueOf(this.missCount), Integer.valueOf(i2 != 0 ? (i * 100) / i2 : 0));
|
|
}
|
|
|
|
/* JADX WARNING: Code restructure failed: missing block: B:19:0x0070, code lost:
|
|
throw new java.lang.IllegalStateException(getClass().getName() + ".sizeOf() is reporting inconsistent results!");
|
|
*/
|
|
public void trimToSize(int i) {
|
|
K key;
|
|
V value;
|
|
while (true) {
|
|
synchronized (this) {
|
|
if (this.size < 0 || (this.map.isEmpty() && this.size != 0)) {
|
|
break;
|
|
} else if (this.size <= i) {
|
|
break;
|
|
} else if (this.map.isEmpty()) {
|
|
break;
|
|
} else {
|
|
Map.Entry<K, V> next = this.map.entrySet().iterator().next();
|
|
key = next.getKey();
|
|
value = next.getValue();
|
|
this.map.remove(key);
|
|
this.size -= safeSizeOf(key, value);
|
|
this.evictionCount++;
|
|
}
|
|
}
|
|
entryRemoved(true, key, value, null);
|
|
}
|
|
}
|
|
}
|