Ensure PageLoader cache sync

This commit is contained in:
Dude so hot authored and renovate[bot] committed 2024-10-15 13:03:18 +08:00
1 parent eff5467ccf
commit e8c4b9ab78
4 files changed
+31 -34

No files matched your search

@@ -60,6 +60,7 @@ import com.hippo.ehviewer.util.AppConfig
import com.hippo.ehviewer.util.CrashHandler
import com.hippo.ehviewer.util.FavouriteStatusRouter
import com.hippo.ehviewer.util.FileUtils
import com.hippo.ehviewer.util.OSUtils
import com.hippo.ehviewer.util.isAtLeastO
import com.hippo.ehviewer.util.isAtLeastP
import com.hippo.ehviewer.util.isAtLeastS
@@ -107,7 +108,8 @@ class EhApplication :
launchUI { FavouriteStatusRouter.collect { (gid, slot) -> detailCache[gid]?.favoriteSlot = slot } }
launch { EhTagDatabase }
launch { EhDB }
dataStateFlow.value
launchIO { dataStateFlow.value }
launchIO { OSUtils.totalMemory }
launch {
if (DownloadManager.labelList.isNotEmpty() && Settings.downloadFilterMode.key !in Settings.prefs) {
Settings.downloadFilterMode.value = DownloadsFilterMode.CUSTOM.flag
@@ -118,13 +120,9 @@ class EhApplication :
FileUtils.cleanupDirectory(AppConfig.externalCrashDir)
FileUtils.cleanupDirectory(AppConfig.externalParseErrorDir)
}
launch {
cleanupDownload()
}
launch { cleanupDownload() }
if (Settings.requestNews) {
launch {
checkDawn()
}
launch { checkDawn() }
}
}
if (BuildConfig.DEBUG) {
@@ -13,6 +13,7 @@ import com.hippo.ehviewer.Settings
import com.hippo.ehviewer.image.hasQrCode
import eu.kanade.tachiyomi.util.system.logcat
import moe.tarsin.coroutines.runSuspendCatching
import moe.tarsin.kt.sync
private val detectQrCodeKey = Extras.Key(default = false)
@@ -33,7 +34,7 @@ object QrCodeInterceptor : Interceptor {
if (image is BitmapImageWithExtraInfo) {
fun compute() = runSuspendCatching { hasQrCode(image.image.bitmap) }.onFailure { logcat(it) }.getOrThrow()
val hasQrCode = when (val key = result.memoryCacheKey) {
is MemoryCache.Key -> synchronized(cache) { cache[key] } ?: compute().also { synchronized(cache) { cache[key] = it } }
is MemoryCache.Key -> cache.sync { cache[key] } ?: compute().also { cache.sync { cache[key] = it } }
null -> compute()
}
val new = image.copy(hasQrCode = hasQrCode)
@@ -6,32 +6,30 @@ import com.hippo.ehviewer.Settings
import com.hippo.ehviewer.image.Image
import com.hippo.ehviewer.util.OSUtils
import com.hippo.ehviewer.util.isAtLeastO
import eu.kanade.tachiyomi.util.lang.withIOContext
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.update
import moe.tarsin.kt.sync
private const val MAX_CACHE_SIZE = 512 * 1024 * 1024
private const val MIN_CACHE_SIZE = 128 * 1024 * 1024
abstract class PageLoader {
private val cache by lazy {
SieveCache<Int, Image>(
maxSize = if (isAtLeastO) {
(OSUtils.totalMemory / 16).toInt().coerceIn(MIN_CACHE_SIZE, MAX_CACHE_SIZE)
private val cache = SieveCache<Int, Image>(
maxSize = if (isAtLeastO) {
(OSUtils.totalMemory / 16).toInt().coerceIn(MIN_CACHE_SIZE, MAX_CACHE_SIZE)
} else {
(OSUtils.appMaxMemory / 3 * 2).toInt()
},
sizeOf = { _, v -> v.allocationSize.toInt() },
onEntryRemoved = { k, o, n, _ ->
if (o.isRecyclable) {
n ?: notifyPageWait(k)
o.recycle()
} else {
(OSUtils.appMaxMemory / 3 * 2).toInt()
},
sizeOf = { _, v -> v.allocationSize.toInt() },
onEntryRemoved = { k, o, n, _ ->
if (o.isRecyclable) {
n ?: notifyPageWait(k)
o.recycle()
} else {
o.isRecyclable = true
}
},
)
}
o.isRecyclable = true
}
},
)
val pages by lazy {
check(size > 0)
@@ -41,10 +39,7 @@ abstract class PageLoader {
private val prefetchPageCount = Settings.preloadImage
@CallSuper
open suspend fun awaitReady(): Boolean {
withIOContext { cache }
return true
}
open suspend fun awaitReady() = true
abstract val isReady: Boolean
@@ -53,11 +48,11 @@ abstract class PageLoader {
@CallSuper
open fun stop() {
cache.evictAll()
cache.sync { evictAll() }
}
fun restart() {
cache.evictAll()
cache.sync { evictAll() }
pages.forEach(Page::reset)
}
@@ -66,7 +61,7 @@ abstract class PageLoader {
private var lastRequestIndex = -1
fun request(index: Int) {
val image = cache[index]
val image = cache.sync { cache[index] }
if (image != null) {
notifyPageSucceed(index, image, false)
} else {
@@ -125,7 +120,7 @@ abstract class PageLoader {
fun notifyPageSucceed(index: Int, image: Image, replaceCache: Boolean = true) {
if (replaceCache) {
cache.put(index, image)
cache.sync { cache[index] = image }
}
pages[index].statusFlow.update { if (image.hasQrCode) PageStatus.Blocked(image) else PageStatus.Ready(image) }
}
@@ -0,0 +1,3 @@
package moe.tarsin.kt
inline fun <T : Any, R> T.sync(block: T.() -> R) = synchronized(this) { block(this) }