Search and parallelism in LocalMangaRepository.getList

This commit is contained in:
Koitharu
2022-04-19 09:25:12 +03:00
parent 98f16774c4
commit fa536220eb

View File

@@ -3,12 +3,17 @@ package org.koitharu.kotatsu.local.domain
import android.annotation.SuppressLint import android.annotation.SuppressLint
import android.net.Uri import android.net.Uri
import android.webkit.MimeTypeMap import android.webkit.MimeTypeMap
import androidx.annotation.WorkerThread
import androidx.collection.ArraySet import androidx.collection.ArraySet
import androidx.core.net.toFile import androidx.core.net.toFile
import androidx.core.net.toUri import androidx.core.net.toUri
import kotlinx.coroutines.Dispatchers import java.io.File
import kotlinx.coroutines.runInterruptible import java.io.IOException
import kotlinx.coroutines.withContext import java.util.*
import java.util.zip.ZipEntry
import java.util.zip.ZipFile
import kotlin.coroutines.CoroutineContext
import kotlinx.coroutines.*
import org.koitharu.kotatsu.core.exceptions.UnsupportedFileException import org.koitharu.kotatsu.core.exceptions.UnsupportedFileException
import org.koitharu.kotatsu.core.parser.MangaRepository import org.koitharu.kotatsu.core.parser.MangaRepository
import org.koitharu.kotatsu.local.data.CbzFilter import org.koitharu.kotatsu.local.data.CbzFilter
@@ -21,11 +26,8 @@ import org.koitharu.kotatsu.utils.AlphanumComparator
import org.koitharu.kotatsu.utils.ext.deleteAwait import org.koitharu.kotatsu.utils.ext.deleteAwait
import org.koitharu.kotatsu.utils.ext.readText import org.koitharu.kotatsu.utils.ext.readText
import org.koitharu.kotatsu.utils.ext.resolveName import org.koitharu.kotatsu.utils.ext.resolveName
import java.io.File
import java.io.IOException private const val MAX_PARALLELISM = 4
import java.util.*
import java.util.zip.ZipEntry
import java.util.zip.ZipFile
class LocalMangaRepository(private val storageManager: LocalStorageManager) : MangaRepository { class LocalMangaRepository(private val storageManager: LocalStorageManager) : MangaRepository {
@@ -38,11 +40,28 @@ class LocalMangaRepository(private val storageManager: LocalStorageManager) : Ma
tags: Set<MangaTag>?, tags: Set<MangaTag>?,
sortOrder: SortOrder? sortOrder: SortOrder?
): List<Manga> { ): List<Manga> {
require(offset == 0) { if (offset > 0) {
"LocalMangaRepository does not support pagination" return emptyList()
} }
val files = getAllFiles() val files = getAllFiles()
return files.mapNotNull { x -> runCatching { getFromFile(x) }.getOrNull() } val list = coroutineScope {
val dispatcher = Dispatchers.IO.limitedParallelism(MAX_PARALLELISM)
files.map { file ->
getFromFileAsync(file, dispatcher)
}.awaitAll()
}.filterNotNullTo(ArrayList(files.size))
if (!query.isNullOrEmpty()) {
list.retainAll { x ->
x.title.contains(query, ignoreCase = true) ||
x.altTitle?.contains(query, ignoreCase = true) == true
}
}
if (!tags.isNullOrEmpty()) {
list.retainAll { x ->
x.tags.containsAll(tags)
}
}
return list
} }
override suspend fun getDetails(manga: Manga) = when { override suspend fun getDetails(manga: Manga) = when {
@@ -99,6 +118,7 @@ class LocalMangaRepository(private val storageManager: LocalStorageManager) : Ma
CbzMangaOutput.filterChapters(cbz, ids) CbzMangaOutput.filterChapters(cbz, ids)
} }
@WorkerThread
@SuppressLint("DefaultLocale") @SuppressLint("DefaultLocale")
fun getFromFile(file: File): Manga = ZipFile(file).use { zip -> fun getFromFile(file: File): Manga = ZipFile(file).use { zip ->
val fileUri = file.toUri().toString() val fileUri = file.toUri().toString()
@@ -192,6 +212,15 @@ class LocalMangaRepository(private val storageManager: LocalStorageManager) : Ma
} }
} }
private fun CoroutineScope.getFromFileAsync(
file: File,
context: CoroutineContext,
): Deferred<Manga?> = async(context) {
runInterruptible {
runCatching { getFromFile(file) }.getOrNull()
}
}
private fun zipUri(file: File, entryName: String) = "cbz://${file.path}#$entryName" private fun zipUri(file: File, entryName: String) = "cbz://${file.path}#$entryName"
private fun findFirstImageEntry(entries: Enumeration<out ZipEntry>): ZipEntry? { private fun findFirstImageEntry(entries: Enumeration<out ZipEntry>): ZipEntry? {