Corrected false assumption in caching logic.

This commit is contained in:
Harrison Deng 2020-04-30 00:09:58 -05:00
parent f637e79ea5
commit f7eb94ae39
3 changed files with 37 additions and 17 deletions

View File

@ -57,14 +57,15 @@ 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();
value = data.get(key);
if (value == null) return null;
if (readLock.tryLock()) {
try {
usage.tryMoveToTop(value);
} finally {
readLock.unlock();
}
}
return value.value;
}

View File

@ -7,27 +7,28 @@ class CacheUsageStack<K, V> {
private volatile CacheValue<K, V> first, last;
private final ReentrantLock lock = new ReentrantLock();
private void addToTop(CacheValue<K, V> value) {
private void addValueToStackTop(CacheValue<K, V> value) {
if (first != null) {
first.front = value;
value.back = first;
} else {
last = value;
}
value.front = null;
first = value;
size++;
}
private void removeValue(CacheValue<K, V> value) {
private void removeValueFromStack(CacheValue<K, V> value) {
if (value.front != null) {
value.front.back = value.back;
} else {
} else if (first == value) {
first = value.back;
}
if (value.back != null) {
value.back.front = value.front;
} else {
} else if (last == value) {
last = value.front;
}
value.front = null;
@ -38,8 +39,10 @@ class CacheUsageStack<K, V> {
public void moveToTop(CacheValue<K, V> value) {
lock.lock();
try {
removeValue(value);
addToTop(value);
if (!value.detached) {
removeValueFromStack(value);
addValueToStackTop(value);
}
} finally {
lock.unlock();
}
@ -50,8 +53,7 @@ class CacheUsageStack<K, V> {
success = lock.tryLock();
if (success) {
try {
removeValue(value);
addToTop(value);
moveToTop(value);
} finally {
lock.unlock();
}
@ -62,7 +64,7 @@ class CacheUsageStack<K, V> {
public void add(CacheValue<K, V> value) {
lock.lock();
try {
addToTop(value);
addValueToStackTop(value);
} finally {
lock.unlock();
}
@ -73,7 +75,8 @@ class CacheUsageStack<K, V> {
lock.lock();
try {
cacheValue = last;
removeValue(last);
removeValueFromStack(last);
cacheValue.detached = true;
} finally {
lock.unlock();
}

View File

@ -1,7 +1,23 @@
package ca.recrown.islandsurvivalcraft.caching;
class CacheValue<KeyType, ValueType> {
/**
* The key that represents this cache value in the caches hashmap.
*/
public volatile KeyType key;
/**
* The actual value that this cache value stores.
*/
public volatile ValueType value;
/**
* The cache value in this position.
*/
public volatile CacheValue<KeyType, ValueType> front, back;
/**
* Whether or not this value is detached from the cache's hashmap.
*/
public volatile boolean detached;
}