Optimize external plugin cursor

This commit is contained in:
Koitharu
2024-08-02 12:27:42 +03:00
parent 20852dbd12
commit 9768758ecc
4 changed files with 29 additions and 34 deletions

View File

@@ -16,8 +16,8 @@ android {
applicationId 'org.koitharu.kotatsu'
minSdk = 21
targetSdk = 35
versionCode = 657
versionName = '7.4'
versionCode = 658
versionName = '7.4.1'
generatedDensities = []
testInstrumentationRunner 'org.koitharu.kotatsu.HiltTestRunner'
ksp {
@@ -82,7 +82,7 @@ afterEvaluate {
}
dependencies {
//noinspection GradleDependency
implementation('com.github.KotatsuApp:kotatsu-parsers:a9fc534ea7') {
implementation('com.github.KotatsuApp:kotatsu-parsers:853c21e49f') {
exclude group: 'org.json', module: 'json'
}

View File

@@ -50,7 +50,7 @@ class ExternalPluginContentSource(
null -> Unit
}
contentResolver.query(uri.build(), null, null, null, filter?.sortOrder?.name)
.indexed()
.safe()
.use { cursor ->
val result = ArrayList<Manga>(cursor.count)
if (cursor.moveToFirst()) {
@@ -94,7 +94,7 @@ class ExternalPluginContentSource(
.appendPath(chapter.url)
.build()
contentResolver.query(uri, null, null, null, null)
.indexed()
.safe()
.use { cursor ->
val result = ArrayList<MangaPage>(cursor.count)
if (cursor.moveToFirst()) {
@@ -116,7 +116,7 @@ class ExternalPluginContentSource(
fun getTags(): Set<MangaTag> = runCatchingCompatibility {
val uri = "content://${source.authority}/tags".toUri()
contentResolver.query(uri, null, null, null, null)
.indexed()
.safe()
.use { cursor ->
val result = ArraySet<MangaTag>(cursor.count)
if (cursor.moveToFirst()) {
@@ -135,7 +135,7 @@ class ExternalPluginContentSource(
fun getCapabilities(): MangaSourceCapabilities? {
val uri = "content://${source.authority}/capabilities".toUri()
return contentResolver.query(uri, null, null, null, null)
.indexed()
.safe()
.use { cursor ->
if (cursor.moveToFirst()) {
MangaSourceCapabilities(
@@ -177,7 +177,7 @@ class ExternalPluginContentSource(
.appendPath(url)
.build()
return contentResolver.query(uri, null, null, null, null)
.indexed()
.safe()
.use { cursor ->
cursor.moveToFirst()
cursor.getManga()
@@ -190,7 +190,7 @@ class ExternalPluginContentSource(
.appendPath(url)
.build()
return contentResolver.query(uri, null, null, null, null)
.indexed()
.safe()
.use { cursor ->
val result = ArrayList<MangaChapter>(cursor.count)
if (cursor.moveToFirst()) {
@@ -212,7 +212,7 @@ class ExternalPluginContentSource(
}
}
private fun IndexedCursor.getManga() = Manga(
private fun SafeCursor.getManga() = Manga(
id = getLong(COLUMN_ID),
title = getString(COLUMN_TITLE),
altTitle = getStringOrNull(COLUMN_ALT_TITLE),
@@ -241,7 +241,7 @@ class ExternalPluginContentSource(
throw IncompatiblePluginException(source.name, e)
}
private fun Cursor?.indexed() = IndexedCursor(this ?: throw IncompatiblePluginException(source.name, null))
private fun Cursor?.safe() = SafeCursor(this ?: throw IncompatiblePluginException(source.name, null))
class MangaSourceCapabilities(
val availableSortOrders: Set<SortOrder>,

View File

@@ -2,77 +2,70 @@ package org.koitharu.kotatsu.core.parser.external
import android.database.Cursor
import android.database.CursorWrapper
import androidx.collection.MutableObjectIntMap
import androidx.collection.ObjectIntMap
import org.koitharu.kotatsu.core.util.ext.getBoolean
class IndexedCursor(cursor: Cursor) : CursorWrapper(cursor) {
private val columns: ObjectIntMap<String> = MutableObjectIntMap<String>(columnCount).also { result ->
val names = columnNames
names.forEachIndexed { index, s -> result.put(s, index) }
}
class SafeCursor(cursor: Cursor) : CursorWrapper(cursor) {
fun getString(columnName: String): String {
return getString(columns[columnName])
return getString(getColumnIndexOrThrow(columnName))
}
fun getStringOrNull(columnName: String): String? {
val columnIndex = columns.getOrDefault(columnName, -1)
val columnIndex = getColumnIndex(columnName)
return when {
columnIndex == -1 -> null
columnIndex < 0 -> null
isNull(columnIndex) -> null
else -> getString(columnIndex)
}
}
fun getBoolean(columnName: String): Boolean {
return getBoolean(columns[columnName])
return getBoolean(getColumnIndexOrThrow(columnName))
}
fun getBooleanOrDefault(columnName: String, defaultValue: Boolean): Boolean {
val columnIndex = columns.getOrDefault(columnName, -1)
val columnIndex = getColumnIndex(columnName)
return when {
columnIndex == -1 -> defaultValue
columnIndex < 0 -> defaultValue
isNull(columnIndex) -> defaultValue
else -> getBoolean(columnIndex)
}
}
fun getInt(columnName: String): Int {
return getInt(columns[columnName])
return getInt(getColumnIndexOrThrow(columnName))
}
fun getIntOrDefault(columnName: String, defaultValue: Int): Int {
val columnIndex = columns.getOrDefault(columnName, -1)
val columnIndex = getColumnIndex(columnName)
return when {
columnIndex == -1 -> defaultValue
columnIndex < 0 -> defaultValue
isNull(columnIndex) -> defaultValue
else -> getInt(columnIndex)
}
}
fun getLong(columnName: String): Long {
return getLong(columns[columnName])
return getLong(getColumnIndexOrThrow(columnName))
}
fun getLongOrDefault(columnName: String, defaultValue: Long): Long {
val columnIndex = columns.getOrDefault(columnName, -1)
val columnIndex = getColumnIndex(columnName)
return when {
columnIndex == -1 -> defaultValue
columnIndex < 0 -> defaultValue
isNull(columnIndex) -> defaultValue
else -> getLong(columnIndex)
}
}
fun getFloat(columnName: String): Float {
return getFloat(columns[columnName])
return getFloat(getColumnIndexOrThrow(columnName))
}
fun getFloatOrDefault(columnName: String, defaultValue: Float): Float {
val columnIndex = columns.getOrDefault(columnName, -1)
val columnIndex = getColumnIndex(columnName)
return when {
columnIndex == -1 -> defaultValue
columnIndex < 0 -> defaultValue
isNull(columnIndex) -> defaultValue
else -> getFloat(columnIndex)
}

View File

@@ -31,5 +31,7 @@ data class ReadingProgress(
CHAPTERS_LEFT -> totalChapters > 0 && percent in 0f..1f
}
fun isComplete() = percent >= 1f - Math.ulp(percent)
fun isReversed() = mode == PERCENT_LEFT || mode == CHAPTERS_LEFT
}