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