diff options
Diffstat (limited to 'src/main/java/at/hannibal2/skyhanni/utils/TimeLimitedCache.kt')
-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 |