Avoiding concurrent errors when deleting weak references

This commit is contained in:
Vitor Pamplona
2025-08-18 16:52:17 -04:00
parent d4d60cb1ff
commit 5c0d71f034

View File

@@ -31,18 +31,24 @@ class LargeSoftCache<K, V> : CacheOperations<K, V> {
fun get(key: K): V? { fun get(key: K): V? {
val softRef = cache.get(key) val softRef = cache.get(key)
val value = softRef?.get() if (softRef == null) return null
val value = softRef.get()
return if (value != null) { return if (value != null) {
value value
} else { } else {
cache.remove(key) cache.remove(key, softRef)
null null
} }
} }
fun remove(key: K) = cache.remove(key) fun remove(key: K) = cache.remove(key)
fun removeIf(
key: K,
value: WeakReference<V>,
) = cache.remove(key, value)
override fun size() = cache.size override fun size() = cache.size
fun isEmpty() = cache.isEmpty() fun isEmpty() = cache.isEmpty()
@@ -95,14 +101,14 @@ class LargeSoftCache<K, V> : CacheOperations<K, V> {
* this method can be called periodically or when memory pressure is high. * this method can be called periodically or when memory pressure is high.
*/ */
fun cleanUp() { fun cleanUp() {
val keysToRemove = mutableListOf<K>() val keysToRemove = mutableMapOf<K, WeakReference<V>>()
forEach { key, softRef -> cache.forEach { key, softRef ->
if (softRef == null) { if (softRef.get() == null) {
keysToRemove.add(key) keysToRemove.put(key, softRef)
} }
} }
keysToRemove.forEach { key -> keysToRemove.forEach { key, value ->
cache.remove(key) cache.remove(key, value)
println("Cleaned up entry for key: $key (object was garbage collected)") println("Cleaned up entry for key: $key (object was garbage collected)")
} }
println("Cache cleanup completed. Remaining size: ${cache.size}") println("Cache cleanup completed. Remaining size: ${cache.size}")
@@ -122,7 +128,7 @@ class LargeSoftCache<K, V> : CacheOperations<K, V> {
) { ) {
val value = ref.get() val value = ref.get()
if (value == null) { if (value == null) {
cache.remove(k) cache.removeIf(k, ref)
} else { } else {
inner.accept(k, value) inner.accept(k, value)
} }