Limit lifetime of memory content cache
This commit is contained in:
@@ -1,5 +0,0 @@
|
||||
package org.koitharu.kotatsu.core.cache
|
||||
|
||||
import androidx.collection.LruCache
|
||||
|
||||
class DeferredLruCache<T>(maxSize: Int) : LruCache<ContentCache.Key, SafeDeferred<T>>(maxSize)
|
||||
33
app/src/main/java/org/koitharu/kotatsu/core/cache/ExpiringLruCache.kt
vendored
Normal file
33
app/src/main/java/org/koitharu/kotatsu/core/cache/ExpiringLruCache.kt
vendored
Normal file
@@ -0,0 +1,33 @@
|
||||
package org.koitharu.kotatsu.core.cache
|
||||
|
||||
import androidx.collection.LruCache
|
||||
import java.util.concurrent.TimeUnit
|
||||
|
||||
class ExpiringLruCache<T>(
|
||||
val maxSize: Int,
|
||||
private val lifetime: Long,
|
||||
private val timeUnit: TimeUnit,
|
||||
) {
|
||||
|
||||
private val cache = LruCache<ContentCache.Key, ExpiringValue<T>>(maxSize)
|
||||
|
||||
operator fun get(key: ContentCache.Key): T? {
|
||||
val value = cache.get(key) ?: return null
|
||||
if (value.isExpired) {
|
||||
cache.remove(key)
|
||||
}
|
||||
return value.get()
|
||||
}
|
||||
|
||||
operator fun set(key: ContentCache.Key, value: T) {
|
||||
cache.put(key, ExpiringValue(value, lifetime, timeUnit))
|
||||
}
|
||||
|
||||
fun clear() {
|
||||
cache.evictAll()
|
||||
}
|
||||
|
||||
fun trimToSize(size: Int) {
|
||||
cache.trimToSize(size)
|
||||
}
|
||||
}
|
||||
34
app/src/main/java/org/koitharu/kotatsu/core/cache/ExpiringValue.kt
vendored
Normal file
34
app/src/main/java/org/koitharu/kotatsu/core/cache/ExpiringValue.kt
vendored
Normal file
@@ -0,0 +1,34 @@
|
||||
package org.koitharu.kotatsu.core.cache
|
||||
|
||||
import android.os.SystemClock
|
||||
import java.util.concurrent.TimeUnit
|
||||
|
||||
class ExpiringValue<T>(
|
||||
private val value: T,
|
||||
lifetime: Long,
|
||||
timeUnit: TimeUnit,
|
||||
) {
|
||||
|
||||
private val expiresAt = SystemClock.elapsedRealtime() + timeUnit.toMillis(lifetime)
|
||||
|
||||
val isExpired: Boolean
|
||||
get() = SystemClock.elapsedRealtime() >= expiresAt
|
||||
|
||||
fun get(): T? = if (isExpired) null else value
|
||||
|
||||
override fun equals(other: Any?): Boolean {
|
||||
if (this === other) return true
|
||||
if (javaClass != other?.javaClass) return false
|
||||
|
||||
other as ExpiringValue<*>
|
||||
|
||||
if (value != other.value) return false
|
||||
return expiresAt == other.expiresAt
|
||||
}
|
||||
|
||||
override fun hashCode(): Int {
|
||||
var result = value?.hashCode() ?: 0
|
||||
result = 31 * result + expiresAt.hashCode()
|
||||
return result
|
||||
}
|
||||
}
|
||||
@@ -6,6 +6,7 @@ import android.content.res.Configuration
|
||||
import org.koitharu.kotatsu.parsers.model.Manga
|
||||
import org.koitharu.kotatsu.parsers.model.MangaPage
|
||||
import org.koitharu.kotatsu.parsers.model.MangaSource
|
||||
import java.util.concurrent.TimeUnit
|
||||
|
||||
class MemoryContentCache(application: Application) : ContentCache, ComponentCallbacks2 {
|
||||
|
||||
@@ -13,8 +14,8 @@ class MemoryContentCache(application: Application) : ContentCache, ComponentCall
|
||||
application.registerComponentCallbacks(this)
|
||||
}
|
||||
|
||||
private val detailsCache = DeferredLruCache<Manga>(4)
|
||||
private val pagesCache = DeferredLruCache<List<MangaPage>>(4)
|
||||
private val detailsCache = ExpiringLruCache<SafeDeferred<Manga>>(4, 5, TimeUnit.MINUTES)
|
||||
private val pagesCache = ExpiringLruCache<SafeDeferred<List<MangaPage>>>(4, 10, TimeUnit.MINUTES)
|
||||
|
||||
override val isCachingEnabled: Boolean = true
|
||||
|
||||
@@ -23,7 +24,7 @@ class MemoryContentCache(application: Application) : ContentCache, ComponentCall
|
||||
}
|
||||
|
||||
override fun putDetails(source: MangaSource, url: String, details: SafeDeferred<Manga>) {
|
||||
detailsCache.put(ContentCache.Key(source, url), details)
|
||||
detailsCache[ContentCache.Key(source, url)] = details
|
||||
}
|
||||
|
||||
override suspend fun getPages(source: MangaSource, url: String): List<MangaPage>? {
|
||||
@@ -31,7 +32,7 @@ class MemoryContentCache(application: Application) : ContentCache, ComponentCall
|
||||
}
|
||||
|
||||
override fun putPages(source: MangaSource, url: String, pages: SafeDeferred<List<MangaPage>>) {
|
||||
pagesCache.put(ContentCache.Key(source, url), pages)
|
||||
pagesCache[ContentCache.Key(source, url)] = pages
|
||||
}
|
||||
|
||||
override fun onConfigurationChanged(newConfig: Configuration) = Unit
|
||||
@@ -43,17 +44,17 @@ class MemoryContentCache(application: Application) : ContentCache, ComponentCall
|
||||
trimCache(pagesCache, level)
|
||||
}
|
||||
|
||||
private fun trimCache(cache: DeferredLruCache<*>, level: Int) {
|
||||
private fun trimCache(cache: ExpiringLruCache<*>, level: Int) {
|
||||
when (level) {
|
||||
ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL,
|
||||
ComponentCallbacks2.TRIM_MEMORY_COMPLETE,
|
||||
ComponentCallbacks2.TRIM_MEMORY_MODERATE -> cache.evictAll()
|
||||
ComponentCallbacks2.TRIM_MEMORY_MODERATE -> cache.clear()
|
||||
|
||||
ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN,
|
||||
ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW,
|
||||
ComponentCallbacks2.TRIM_MEMORY_BACKGROUND -> cache.trimToSize(1)
|
||||
|
||||
else -> cache.trimToSize(cache.maxSize() / 2)
|
||||
else -> cache.trimToSize(cache.maxSize / 2)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user