Changed to use of read and write locks in cache.

Also added specifics to constructor for the hash map.
This commit is contained in:
Harrison Deng 2020-04-26 15:41:31 -05:00
parent 8d392cd779
commit 2b05dfe4cc

View File

@ -2,19 +2,22 @@ package ca.recrown.islandsurvivalcraft.caching;
import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentLinkedQueue; import java.util.concurrent.ConcurrentLinkedQueue;
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<Key, Value> { public class Cache<Key, Value> {
private final int maxSize; private final int maxSize;
private final ConcurrentHashMap<Key, CacheValue<Value>> data; private final ConcurrentHashMap<Key, CacheValue<Value>> data;
private final ConcurrentLinkedQueue<Key> occurrenceOrder; private final ConcurrentLinkedQueue<Key> occurrenceOrder;
private ReentrantLock cleaningLock; private ReentrantReadWriteLock cleaningLock = new ReentrantReadWriteLock(true);
private ReadLock writeLock = cleaningLock.readLock();
private WriteLock readLock = cleaningLock.writeLock();
public Cache(int maxSize) { public Cache(int maxSize) {
data = new ConcurrentHashMap<>(maxSize); data = new ConcurrentHashMap<>(maxSize + 1, 0.75f, 6);
occurrenceOrder = new ConcurrentLinkedQueue<>(); occurrenceOrder = new ConcurrentLinkedQueue<>();
this.maxSize = maxSize; this.maxSize = maxSize;
cleaningLock = new ReentrantLock(true);
} }
public Cache() { public Cache() {
@ -34,14 +37,14 @@ public class Cache<Key, Value> {
Key potentialKey = occurrenceOrder.poll(); Key potentialKey = occurrenceOrder.poll();
CacheValue<Value> potential = data.get(potentialKey); CacheValue<Value> potential = data.get(potentialKey);
potential.occurrence--; potential.occurrence--;
cleaningLock.lock(); writeLock.lock();
try { try {
occ = potential.occurrence; occ = potential.occurrence;
if (occ < 1) { if (occ < 1) {
data.remove(potentialKey); data.remove(potentialKey);
} }
} finally { } finally {
cleaningLock.unlock(); writeLock.unlock();
} }
} while (occ > 0); } while (occ > 0);
} }
@ -56,16 +59,15 @@ public class Cache<Key, Value> {
*/ */
public Value getValue(Key key) { public Value getValue(Key key) {
CacheValue<Value> res = null; CacheValue<Value> res = null;
cleaningLock.lock(); readLock.lock();
try { try {
res = data.get(key); res = data.get(key);
if (res == null) return null; if (res == null) return null;
res.occurrence++; res.occurrence++;
occurrenceOrder.add(key); occurrenceOrder.add(key);
} finally { } finally {
cleaningLock.unlock(); readLock.unlock();
} }
return res.data; return res.data;
} }