Corrected false assumption in caching logic.
This commit is contained in:
parent
f637e79ea5
commit
f7eb94ae39
@ -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;
|
||||
}
|
||||
|
@ -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();
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
Loading…
Reference in New Issue
Block a user