Improved cache performance by removing locks.

These sync locks can be removed because of fixing the multithread cases in the previous commit.
This commit is contained in:
Harrison Deng 2020-04-30 00:20:32 -05:00
parent f7eb94ae39
commit 83297a1d10

View File

@ -1,17 +1,13 @@
package ca.recrown.islandsurvivalcraft.caching; package ca.recrown.islandsurvivalcraft.caching;
import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.locks.ReentrantReadWriteLock; import java.util.concurrent.locks.ReentrantLock;
import java.util.concurrent.locks.ReentrantReadWriteLock.ReadLock;
import java.util.concurrent.locks.ReentrantReadWriteLock.WriteLock;
public class Cache<K, V> { public class Cache<K, V> {
private final int maxSize; private final int maxSize;
private final ConcurrentHashMap<K, CacheValue<K, V>> data; private final ConcurrentHashMap<K, CacheValue<K, V>> data;
private final CacheUsageStack<K, V> usage = new CacheUsageStack<>(); private final CacheUsageStack<K, V> usage = new CacheUsageStack<>();
private final ReentrantReadWriteLock lock = new ReentrantReadWriteLock(); private final ReentrantLock lock = new ReentrantLock();
private final WriteLock writeLock = lock.writeLock();
private final ReadLock readLock = lock.readLock();
public Cache(int maxSize) { public Cache(int maxSize) {
data = new ConcurrentHashMap<>(maxSize + 1, 0.75f, 16); data = new ConcurrentHashMap<>(maxSize + 1, 0.75f, 16);
@ -33,7 +29,7 @@ public class Cache<K, V> {
if (data.containsKey(key)) { if (data.containsKey(key)) {
data.get(key).value = value; data.get(key).value = value;
} else { } else {
writeLock.lock(); lock.lock();
try { try {
CacheValue<K, V> val = new CacheValue<>(); CacheValue<K, V> val = new CacheValue<>();
val.key = key; val.key = key;
@ -44,7 +40,7 @@ public class Cache<K, V> {
data.remove(usage.pop().key); data.remove(usage.pop().key);
} }
} finally { } finally {
writeLock.unlock(); lock.unlock();
} }
} }
} }
@ -57,29 +53,22 @@ public class Cache<K, V> {
* @return the value associated to the key. * @return the value associated to the key.
*/ */
public V get(K key) { public V get(K key) {
CacheValue<K, V> value = null; CacheValue<K, V> cacheValue = data.get(key);
value = data.get(key); if (cacheValue == null) return null;
if (value == null) return null; usage.tryMoveToTop(cacheValue);
if (readLock.tryLock()) { return cacheValue.value;
try {
usage.tryMoveToTop(value);
} finally {
readLock.unlock();
}
}
return value.value;
} }
/** /**
* Clears the cache of all values. * Clears the cache of all values.
*/ */
public void clearCache() { public void clearCache() {
writeLock.lock(); lock.lock();
try { try {
data.clear(); data.clear();
usage.clear(); usage.clear();
} finally { } finally {
writeLock.unlock(); lock.unlock();
} }
} }
} }