aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorhannibal2 <24389977+hannibal002@users.noreply.github.com>2024-08-18 09:43:50 +0200
committerGitHub <noreply@github.com>2024-08-18 09:43:50 +0200
commit944a97516d6ebcf3f473700f854ff8f0219385b9 (patch)
tree93225fb659c327ae5bc6d378aae6c4d0baed4cef
parente9502e6a00cfcc72faac485bc52703c1f5bae15d (diff)
downloadskyhanni-944a97516d6ebcf3f473700f854ff8f0219385b9.tar.gz
skyhanni-944a97516d6ebcf3f473700f854ff8f0219385b9.tar.bz2
skyhanni-944a97516d6ebcf3f473700f854ff8f0219385b9.zip
Fix: Time Limited Cache Lock (#2370)
Co-authored-by: hannibal2 <24389977+hannibal00212@users.noreply.github.com>
-rw-r--r--src/main/java/at/hannibal2/skyhanni/utils/TimeLimitedCache.kt38
1 files changed, 34 insertions, 4 deletions
diff --git a/src/main/java/at/hannibal2/skyhanni/utils/TimeLimitedCache.kt b/src/main/java/at/hannibal2/skyhanni/utils/TimeLimitedCache.kt
index 018c858fa..4c96c9b3c 100644
--- a/src/main/java/at/hannibal2/skyhanni/utils/TimeLimitedCache.kt
+++ b/src/main/java/at/hannibal2/skyhanni/utils/TimeLimitedCache.kt
@@ -1,7 +1,9 @@
package at.hannibal2.skyhanni.utils
import com.google.common.cache.CacheBuilder
+import java.util.concurrent.ConcurrentMap
import java.util.concurrent.TimeUnit
+import java.util.concurrent.locks.ReentrantReadWriteLock
import kotlin.time.Duration
class TimeLimitedCache<K : Any, V : Any>(
@@ -9,9 +11,18 @@ class TimeLimitedCache<K : Any, V : Any>(
private val removalListener: (K?, V?) -> Unit = { _, _ -> },
) : Iterable<Map.Entry<K, V>> {
+ private val cacheLock = ReentrantReadWriteLock()
+
private val cache = CacheBuilder.newBuilder()
.expireAfterWrite(expireAfterWrite.inWholeMilliseconds, TimeUnit.MILLISECONDS)
- .removalListener { removalListener(it.key, it.value) }
+ .removalListener {
+ cacheLock.writeLock().lock()
+ try {
+ removalListener(it.key, it.value)
+ } finally {
+ cacheLock.writeLock().unlock()
+ }
+ }
.build<K, V>()
// TODO IntelliJ cant replace this, find another way?
@@ -27,11 +38,30 @@ class TimeLimitedCache<K : Any, V : Any>(
fun remove(key: K) = cache.invalidate(key)
- fun entries(): Set<Map.Entry<K, V>> = cache.asMap().entries
+ fun entries(): Set<Map.Entry<K, V>> = getMap().entries
+
+ fun values(): Collection<V> = getMap().values
+
+ fun keys(): Set<K> = getMap().keys
- fun values(): Collection<V> = cache.asMap().values
+ /**
+ * Modifications to the returned map are not supported and may lead to unexpected behavior.
+ * This method is intended for read-only operations such as iteration or retrieval of values.
+ *
+ * @return A read-only view of the cache's underlying map.
+ */
+ private fun getMap(): ConcurrentMap<K, V> {
+ val asMap: ConcurrentMap<K, V>
- fun keys(): Set<K> = cache.asMap().keys
+ cacheLock.readLock().lock()
+ try {
+ asMap = cache.asMap()
+ } finally {
+ cacheLock.readLock().unlock()
+ }
+
+ return asMap
+ }
fun containsKey(key: K): Boolean = cache.getIfPresent(key) != null