Release v6.1.3

Make search engine synchronous
Offload some search engine tasks to background threads
Minor search engine speedups
This commit is contained in:
NerdNumber9
2017-08-26 03:40:59 -04:00
parent bcc2ec1668
commit 84121ff901
14 changed files with 262 additions and 83 deletions

View File

@ -11,6 +11,7 @@ import io.realm.Realm
import io.realm.RealmQuery
import io.realm.RealmResults
import rx.Observable
import timber.log.Timber
import kotlin.reflect.KClass
fun Realm.ehMetaQueryFromUrl(url: String,
@ -50,7 +51,7 @@ private fun pervEdenSourceToLang(source: Long)
fun Realm.pervEdenMetaQueryFromUrl(url: String,
source: Long,
meta: RealmQuery<PervEdenGalleryMetadata>?) =
meta: RealmQuery<PervEdenGalleryMetadata>? = null) =
pervEdenMetadataQuery(
PervEdenGalleryMetadata.pvIdFromUrl(url),
source,
@ -74,7 +75,7 @@ fun Realm.loadPervEdenAsync(pvId: String, source: Long): Observable<PervEdenGall
.asObservable()
fun Realm.nhentaiMetaQueryFromUrl(url: String,
meta: RealmQuery<NHentaiMetadata>?) =
meta: RealmQuery<NHentaiMetadata>? = null) =
nhentaiMetadataQuery(
NHentaiMetadata.nhIdFromUrl(url),
meta
@ -95,11 +96,13 @@ fun Realm.loadNhentaiAsync(nhId: Long): Observable<NHentaiMetadata?>
.asObservable()
fun Realm.loadAllMetadata(): Map<KClass<out SearchableGalleryMetadata>, RealmResults<out SearchableGalleryMetadata>> =
mapOf(
Pair(ExGalleryMetadata::class, where(ExGalleryMetadata::class.java).findAll()),
Pair(NHentaiMetadata::class, where(NHentaiMetadata::class.java).findAll()),
Pair(PervEdenGalleryMetadata::class, where(PervEdenGalleryMetadata::class.java).findAll())
)
listOf<Pair<KClass<out SearchableGalleryMetadata>, RealmQuery<out SearchableGalleryMetadata>>>(
Pair(ExGalleryMetadata::class, where(ExGalleryMetadata::class.java)),
Pair(NHentaiMetadata::class, where(NHentaiMetadata::class.java)),
Pair(PervEdenGalleryMetadata::class, where(PervEdenGalleryMetadata::class.java))
).map {
Pair(it.first, it.second.findAllSorted(SearchableGalleryMetadata::mangaId.name))
}.toMap()
fun Realm.queryMetadataFromManga(manga: Manga,
meta: RealmQuery<out SearchableGalleryMetadata>? = null): RealmQuery<out SearchableGalleryMetadata> =
@ -112,3 +115,21 @@ fun Realm.queryMetadataFromManga(manga: Manga,
NHENTAI_SOURCE_ID -> nhentaiMetaQueryFromUrl(manga.url, meta as? RealmQuery<NHentaiMetadata>)
else -> throw IllegalArgumentException("Unknown source type!")
}
fun Realm.syncMangaIds(mangas: List<Manga>) {
Timber.d("--> EH: Begin syncing ${mangas.size} manga IDs...")
executeTransaction {
mangas.filter {
isLewdSource(it.source)
}.forEach { manga ->
try {
queryMetadataFromManga(manga).findFirst()?.let { meta ->
meta.mangaId = manga.id
}
} catch(e: Exception) {
Timber.w(e, "Error syncing manga IDs! Ignoring...")
}
}
}
Timber.d("--> EH: Finish syncing ${mangas.size} manga IDs!")
}

View File

@ -56,10 +56,10 @@ open class ExGalleryMetadata : RealmObject(), SearchableGalleryMetadata {
override fun getTitles() = listOf(title, altTitle).filterNotNull()
@Ignore
override val titleFields = listOf(
ExGalleryMetadata::title.name,
ExGalleryMetadata::altTitle.name
)
override val titleFields = TITLE_FIELDS
@Index
override var mangaId: Long? = null
companion object {
private fun splitGalleryUrl(url: String)
@ -72,5 +72,10 @@ open class ExGalleryMetadata : RealmObject(), SearchableGalleryMetadata {
fun galleryToken(url: String) =
splitGalleryUrl(url).last()
val TITLE_FIELDS = listOf(
ExGalleryMetadata::title.name,
ExGalleryMetadata::altTitle.name
)
}
}

View File

@ -53,11 +53,10 @@ open class NHentaiMetadata : RealmObject(), SearchableGalleryMetadata {
override fun getTitles() = listOf(japaneseTitle, englishTitle, shortTitle).filterNotNull()
@Ignore
override val titleFields = listOf(
NHentaiMetadata::japaneseTitle.name,
NHentaiMetadata::englishTitle.name,
NHentaiMetadata::shortTitle.name
)
override val titleFields = TITLE_FIELDS
@Index
override var mangaId: Long? = null
companion object {
val BASE_URL = "https://nhentai.net"
@ -71,6 +70,12 @@ open class NHentaiMetadata : RealmObject(), SearchableGalleryMetadata {
fun nhIdFromUrl(url: String)
= url.split("/").last { it.isNotBlank() }.toLong()
val TITLE_FIELDS = listOf(
NHentaiMetadata::japaneseTitle.name,
NHentaiMetadata::englishTitle.name,
NHentaiMetadata::shortTitle.name
)
}
}

View File

@ -45,10 +45,10 @@ open class PervEdenGalleryMetadata : RealmObject(), SearchableGalleryMetadata {
}).filterNotNull()
@Ignore
override val titleFields = listOf(
//TODO Somehow include altTitles
PervEdenGalleryMetadata::title.name
)
override val titleFields = TITLE_FIELDS
@Index
override var mangaId: Long? = null
companion object {
private fun splitGalleryUrl(url: String)
@ -57,6 +57,11 @@ open class PervEdenGalleryMetadata : RealmObject(), SearchableGalleryMetadata {
}
fun pvIdFromUrl(url: String) = splitGalleryUrl(url).last()
val TITLE_FIELDS = listOf(
//TODO Somehow include altTitles
PervEdenGalleryMetadata::title.name
)
}
}

View File

@ -21,4 +21,6 @@ interface SearchableGalleryMetadata: RealmModel {
fun getTitles(): List<String>
val titleFields: List<String>
var mangaId: Long?
}

View File

@ -2,18 +2,17 @@ package exh.search
import exh.metadata.models.SearchableGalleryMetadata
import exh.metadata.models.Tag
import exh.util.beginLog
import io.realm.Case
import io.realm.RealmResults
import io.realm.RealmQuery
class SearchEngine {
private val queryCache = mutableMapOf<String, List<QueryComponent>>()
fun filterResults(metadata: RealmResults<out SearchableGalleryMetadata>, query: List<QueryComponent>):
RealmResults<out SearchableGalleryMetadata> {
val first = metadata.firstOrNull() ?: return metadata
val rQuery = metadata.where()//.beginLog(SearchableGalleryMetadata::class.java)
fun <T : SearchableGalleryMetadata> filterResults(rQuery: RealmQuery<T>,
query: List<QueryComponent>,
titleFields: List<String>):
RealmQuery<T> {
var queryEmpty = true
fun matchTagList(namespace: String?,
@ -59,14 +58,13 @@ class SearchEngine {
rQuery.beginGroup()
//Match title
first.titleFields
.forEachIndexed { index, s ->
queryEmpty = false
if(index > 0)
rQuery.or()
titleFields.forEachIndexed { index, s ->
queryEmpty = false
if(index > 0)
rQuery.or()
rQuery.like(s, component.asLenientTitleQuery(), Case.INSENSITIVE)
}
rQuery.like(s, component.asLenientTitleQuery(), Case.INSENSITIVE)
}
//Match tags
matchTagList(null, component, false) //We already deal with exclusions here
@ -89,7 +87,7 @@ class SearchEngine {
}
}
}
return rQuery.findAll()
return rQuery
}
fun parseQuery(query: String) = queryCache.getOrPut(query, {

View File

@ -88,7 +88,6 @@ class MetadataFetchDialog {
db.getLibraryMangas().asRxSingle().subscribe {
if(!explicit && it.isEmpty()) {
//Do not open dialog on startup if no manga
preferenceHelper.migrateLibraryAsked2().set(true)
} else {
//Not logged in but have ExHentai galleries
if (!preferenceHelper.enableExhentai().getOrDefault()) {
@ -109,9 +108,7 @@ class MetadataFetchDialog {
.onNegative({ _, _ -> adviseMigrationLater(activity) })
.cancelable(false)
.canceledOnTouchOutside(false)
.dismissListener {
preferenceHelper.migrateLibraryAsked2().set(true)
}.show()
.show()
}
}
}