Changed to use of read and write locks in cache.
Also added specifics to constructor for the hash map.
This commit is contained in:
parent
8d392cd779
commit
2b05dfe4cc
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user