Hitomi: improve speed (#3560)

* Hitomi: use set to improve filtering speed

* keep random sort

* optimize cache control
This commit is contained in:
AwkwardPeak7 2024-06-14 12:33:33 +05:00 committed by Draff
parent e710fee5c5
commit 927897c78b
No known key found for this signature in database
GPG Key ID: E8A89F3211677653
2 changed files with 37 additions and 26 deletions

View File

@ -1,7 +1,7 @@
ext { ext {
extName = 'Hitomi' extName = 'Hitomi'
extClass = '.HitomiFactory' extClass = '.HitomiFactory'
extVersionCode = 30 extVersionCode = 31
isNsfw = true isNsfw = true
} }

View File

@ -101,15 +101,18 @@ class Hitomi(
} }
private suspend fun getRangedResponse(url: String, range: LongRange?): ByteArray { private suspend fun getRangedResponse(url: String, range: LongRange?): ByteArray {
val rangeHeaders = when (range) { val request = when (range) {
null -> headers null -> GET(url, headers)
else -> headersBuilder() else -> {
.set("Range", "bytes=${range.first}-${range.last}") val rangeHeaders = headersBuilder()
.build() .set("Range", "bytes=${range.first}-${range.last}")
.build()
GET(url, rangeHeaders, CacheControl.FORCE_NETWORK)
}
} }
return client.newCall(GET(url, rangeHeaders, CacheControl.FORCE_NETWORK)) return client.newCall(request).awaitSuccess().use { it.body.bytes() }
.awaitSuccess().use { it.body.bytes() }
} }
private suspend fun hitomiSearch( private suspend fun hitomiSearch(
@ -123,12 +126,9 @@ class Hitomi(
val terms = query val terms = query
.trim() .trim()
.replace(Regex("""^\?"""), "")
.lowercase() .lowercase()
.split(Regex("\\s+")) .split(Regex("\\s+"))
.map { .toMutableList()
it.replace('_', ' ')
}.toMutableList()
filters.forEach { filters.forEach {
when (it) { when (it) {
@ -148,9 +148,16 @@ class Hitomi(
is TextFilter -> { is TextFilter -> {
if (it.state.isNotEmpty()) { if (it.state.isNotEmpty()) {
terms += it.state.split(",").map { tag -> terms += it.state.split(",").filter(String::isNotBlank).map { tag ->
val trimmed = tag.trim() val trimmed = tag.trim()
(if (trimmed.startsWith("-")) "-" else "") + it.type + ":" + trimmed.lowercase().removePrefix("-") buildString {
if (trimmed.startsWith('-')) {
append("-")
}
append(it.type)
append(":")
append(trimmed.lowercase().removePrefix("-"))
}
} }
} }
} }
@ -158,7 +165,7 @@ class Hitomi(
} }
} }
if (language != "all" && sortBy == Pair(null, "index")) { if (language != "all" && sortBy == Pair(null, "index") && !terms.any { it.contains(":") }) {
terms += "language:$language" terms += "language:$language"
} }
@ -204,17 +211,17 @@ class Hitomi(
val results = when { val results = when {
positiveTerms.isEmpty() || sortBy != Pair(null, "index") positiveTerms.isEmpty() || sortBy != Pair(null, "index")
-> getGalleryIDsFromNozomi(sortBy.first, sortBy.second, language) -> getGalleryIDsFromNozomi(sortBy.first, sortBy.second, language)
else -> ArrayList() else -> emptySet()
} }.toMutableSet()
fun filterPositive(newResults: Collection<Int>) { fun filterPositive(newResults: Set<Int>) {
when { when {
results.isEmpty() -> results.addAll(newResults) results.isEmpty() -> results.addAll(newResults)
else -> results.retainAll(newResults) else -> results.retainAll(newResults)
} }
} }
fun filterNegative(newResults: Collection<Int>) { fun filterNegative(newResults: Set<Int>) {
results.removeAll(newResults) results.removeAll(newResults)
} }
@ -228,14 +235,18 @@ class Hitomi(
filterNegative(it.await()) filterNegative(it.await())
} }
if (random) results.shuffled() else results if (random) {
results.toList().shuffled()
} else {
results.toList()
}
} }
// search.js // search.js
private suspend fun getGalleryIDsForQuery( private suspend fun getGalleryIDsForQuery(
query: String, query: String,
language: String = "all", language: String = "all",
): MutableList<Int> { ): Set<Int> {
query.replace("_", " ").let { query.replace("_", " ").let {
if (it.indexOf(':') > -1) { if (it.indexOf(':') > -1) {
val sides = it.split(":") val sides = it.split(":")
@ -262,13 +273,13 @@ class Hitomi(
val key = hashTerm(it) val key = hashTerm(it)
val node = getGalleryNodeAtAddress(0) val node = getGalleryNodeAtAddress(0)
val data = bSearch(key, node) ?: return ArrayList() val data = bSearch(key, node) ?: return emptySet()
return getGalleryIDsFromData(data) return getGalleryIDsFromData(data)
} }
} }
private suspend fun getGalleryIDsFromData(data: Pair<Long, Int>): MutableList<Int> { private suspend fun getGalleryIDsFromData(data: Pair<Long, Int>): Set<Int> {
val url = "$ltnUrl/galleriesindex/galleries.$galleriesIndexVersion.data" val url = "$ltnUrl/galleriesindex/galleries.$galleriesIndexVersion.data"
val (offset, length) = data val (offset, length) = data
require(length in 1..100000000) { require(length in 1..100000000) {
@ -277,7 +288,7 @@ class Hitomi(
val inbuf = getRangedResponse(url, offset.until(offset + length)) val inbuf = getRangedResponse(url, offset.until(offset + length))
val galleryIDs = mutableListOf<Int>() val galleryIDs = mutableSetOf<Int>()
val buffer = val buffer =
ByteBuffer ByteBuffer
@ -366,14 +377,14 @@ class Hitomi(
tag: String, tag: String,
language: String, language: String,
range: LongRange? = null, range: LongRange? = null,
): MutableList<Int> { ): Set<Int> {
val nozomiAddress = when (area) { val nozomiAddress = when (area) {
null -> "$ltnUrl/$tag-$language.nozomi" null -> "$ltnUrl/$tag-$language.nozomi"
else -> "$ltnUrl/$area/$tag-$language.nozomi" else -> "$ltnUrl/$area/$tag-$language.nozomi"
} }
val bytes = getRangedResponse(nozomiAddress, range) val bytes = getRangedResponse(nozomiAddress, range)
val nozomi = mutableListOf<Int>() val nozomi = mutableSetOf<Int>()
val arrayBuffer = ByteBuffer val arrayBuffer = ByteBuffer
.wrap(bytes) .wrap(bytes)