diff options
author | hannibal2 <24389977+hannibal002@users.noreply.github.com> | 2024-08-18 09:43:50 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-08-18 09:43:50 +0200 |
commit | 944a97516d6ebcf3f473700f854ff8f0219385b9 (patch) | |
tree | 93225fb659c327ae5bc6d378aae6c4d0baed4cef | |
parent | e9502e6a00cfcc72faac485bc52703c1f5bae15d (diff) | |
download | skyhanni-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.kt | 38 |
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 |