diff --git a/src/main/java/ca/recrown/islandsurvivalcraft/caching/Cache.java b/src/main/java/ca/recrown/islandsurvivalcraft/caching/Cache.java index 9ccdde2..1d24638 100644 --- a/src/main/java/ca/recrown/islandsurvivalcraft/caching/Cache.java +++ b/src/main/java/ca/recrown/islandsurvivalcraft/caching/Cache.java @@ -57,14 +57,15 @@ public class Cache { * @return the value associated to the key. */ public V get(K key) { - readLock.lock(); CacheValue 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; } diff --git a/src/main/java/ca/recrown/islandsurvivalcraft/caching/CacheUsageStack.java b/src/main/java/ca/recrown/islandsurvivalcraft/caching/CacheUsageStack.java index a441012..03e4466 100644 --- a/src/main/java/ca/recrown/islandsurvivalcraft/caching/CacheUsageStack.java +++ b/src/main/java/ca/recrown/islandsurvivalcraft/caching/CacheUsageStack.java @@ -7,27 +7,28 @@ class CacheUsageStack { private volatile CacheValue first, last; private final ReentrantLock lock = new ReentrantLock(); - private void addToTop(CacheValue value) { + private void addValueToStackTop(CacheValue value) { if (first != null) { first.front = value; value.back = first; } else { last = value; } + value.front = null; first = value; size++; } - private void removeValue(CacheValue value) { + private void removeValueFromStack(CacheValue 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 { public void moveToTop(CacheValue value) { lock.lock(); try { - removeValue(value); - addToTop(value); + if (!value.detached) { + removeValueFromStack(value); + addValueToStackTop(value); + } } finally { lock.unlock(); } @@ -50,8 +53,7 @@ class CacheUsageStack { success = lock.tryLock(); if (success) { try { - removeValue(value); - addToTop(value); + moveToTop(value); } finally { lock.unlock(); } @@ -62,7 +64,7 @@ class CacheUsageStack { public void add(CacheValue value) { lock.lock(); try { - addToTop(value); + addValueToStackTop(value); } finally { lock.unlock(); } @@ -73,7 +75,8 @@ class CacheUsageStack { lock.lock(); try { cacheValue = last; - removeValue(last); + removeValueFromStack(last); + cacheValue.detached = true; } finally { lock.unlock(); } diff --git a/src/main/java/ca/recrown/islandsurvivalcraft/caching/CacheValue.java b/src/main/java/ca/recrown/islandsurvivalcraft/caching/CacheValue.java index 0aaf880..d3196f1 100644 --- a/src/main/java/ca/recrown/islandsurvivalcraft/caching/CacheValue.java +++ b/src/main/java/ca/recrown/islandsurvivalcraft/caching/CacheValue.java @@ -1,7 +1,23 @@ package ca.recrown.islandsurvivalcraft.caching; class CacheValue { + /** + * 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 front, back; + + /** + * Whether or not this value is detached from the cache's hashmap. + */ + public volatile boolean detached; } \ No newline at end of file