Improved locking scheme of cache.

This commit is contained in:
Harrison Deng 2020-04-29 16:23:39 -05:00
parent e40bf74cb8
commit 6f27e52c6b

View File

@ -1,17 +1,15 @@
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.ReentrantLock;
import java.util.concurrent.locks.ReentrantReadWriteLock; import java.util.concurrent.locks.ReentrantReadWriteLock;
import java.util.concurrent.locks.ReentrantReadWriteLock.ReadLock;
import java.util.concurrent.locks.ReentrantReadWriteLock.WriteLock; 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 UsageStack<K, V> usage = new UsageStack<>(); private final UsageStack<K, V> usage = new UsageStack<>();
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, 6); data = new ConcurrentHashMap<>(maxSize + 1, 0.75f, 6);
@ -33,7 +31,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 +42,7 @@ public class Cache<K, V> {
data.remove(usage.pop().key); data.remove(usage.pop().key);
} }
} finally { } finally {
writeLock.unlock(); lock.unlock();
} }
} }
} }
@ -57,15 +55,9 @@ 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) {
readLock.lock(); CacheValue<K, V> value = data.get(key);
CacheValue<K, V> value = null;
try {
if (!data.containsKey(key)) return null;
value = data.get(key);
usage.tryMoveToTop(value); usage.tryMoveToTop(value);
} finally { if (value == null) return null;
readLock.unlock();
}
return value.value; return value.value;
} }
@ -73,12 +65,12 @@ public class Cache<K, V> {
* 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();
} }
} }
} }