Regexes are now compiled only once by search engine.
This commit is contained in:
parent
097a83e3ba
commit
c49b865ee7
@ -1,4 +1,4 @@
|
|||||||
package exh.search
|
package exh.search
|
||||||
|
|
||||||
class Namespace(var namespace: Text,
|
class Namespace(var namespace: String,
|
||||||
var tag: Text? = null) : QueryComponent()
|
var tag: Text? = null) : QueryComponent()
|
||||||
|
@ -2,22 +2,18 @@ package exh.search
|
|||||||
|
|
||||||
import exh.metadata.models.ExGalleryMetadata
|
import exh.metadata.models.ExGalleryMetadata
|
||||||
import exh.metadata.models.Tag
|
import exh.metadata.models.Tag
|
||||||
import ru.lanwen.verbalregex.VerbalExpression
|
|
||||||
import java.util.*
|
|
||||||
|
|
||||||
class SearchEngine {
|
class SearchEngine {
|
||||||
//TODO Namespace alias
|
//TODO Namespace alias
|
||||||
fun matches(metadata: ExGalleryMetadata, query: List<QueryComponent>): Boolean {
|
fun matches(metadata: ExGalleryMetadata, query: List<QueryComponent>): Boolean {
|
||||||
|
|
||||||
fun matchTagList(tags: List<Tag>,
|
fun matchTagList(tags: List<Tag>,
|
||||||
component: Text,
|
component: Text): Boolean {
|
||||||
builder: VerbalExpression.Builder,
|
|
||||||
built: VerbalExpression): Boolean {
|
|
||||||
//Match tags
|
//Match tags
|
||||||
val tagMatcher = if(!component.exact)
|
val tagMatcher = if(!component.exact)
|
||||||
builder.anything().build()
|
component.asLenientRegex()
|
||||||
else
|
else
|
||||||
built
|
component.asRegex()
|
||||||
//Match beginning of tag
|
//Match beginning of tag
|
||||||
if (tags.find {
|
if (tags.find {
|
||||||
tagMatcher.testExact(it.name)
|
tagMatcher.testExact(it.name)
|
||||||
@ -32,28 +28,21 @@ class SearchEngine {
|
|||||||
|
|
||||||
for(component in query) {
|
for(component in query) {
|
||||||
if(component is Text) {
|
if(component is Text) {
|
||||||
val builder = component.asRegex()
|
|
||||||
val built = builder.build()
|
|
||||||
//Match title
|
//Match title
|
||||||
if (built.test(metadata.title?.toLowerCase())
|
if (component.asRegex().test(metadata.title?.toLowerCase())
|
||||||
|| built.test(metadata.altTitle?.toLowerCase())) {
|
|| component.asRegex().test(metadata.altTitle?.toLowerCase())) {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
//Match tags
|
//Match tags
|
||||||
if(!matchTagList(metadata.tags.entries.flatMap(MutableMap.MutableEntry<String, ArrayList<Tag>>::value),
|
if(!matchTagList(metadata.tags.entries.flatMap { it.value },
|
||||||
component,
|
component)) return false
|
||||||
builder,
|
|
||||||
built))
|
|
||||||
return false
|
|
||||||
} else if(component is Namespace) {
|
} else if(component is Namespace) {
|
||||||
//Match namespace
|
//Match namespace
|
||||||
val ns = metadata.tags.entries.filter {
|
val ns = metadata.tags.entries.filter {
|
||||||
it.key == component.namespace.rawTextOnly()
|
it.key == component.namespace
|
||||||
}.flatMap { it.value }
|
}.flatMap { it.value }
|
||||||
//Match tags
|
//Match tags
|
||||||
val builder = component.tag!!.asRegex()
|
if(!matchTagList(ns, component.tag!!))
|
||||||
val built = builder.build()
|
|
||||||
if(!matchTagList(ns, component.tag!!, builder, built))
|
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -110,7 +99,20 @@ class SearchEngine {
|
|||||||
nextIsExact = true
|
nextIsExact = true
|
||||||
} else if(char == ':') {
|
} else if(char == ':') {
|
||||||
flushText()
|
flushText()
|
||||||
namespace = Namespace(flushToText(), null)
|
var flushed = flushToText().rawTextOnly()
|
||||||
|
//Map tag aliases
|
||||||
|
flushed = when(flushed) {
|
||||||
|
"a" -> "artist"
|
||||||
|
"c", "char" -> "character"
|
||||||
|
"f" -> "female"
|
||||||
|
"g", "creator", "circle" -> "group"
|
||||||
|
"l", "lang" -> "language"
|
||||||
|
"m" -> "male"
|
||||||
|
"p", "series" -> "parody"
|
||||||
|
"r" -> "reclass"
|
||||||
|
else -> flushed
|
||||||
|
}
|
||||||
|
namespace = Namespace(flushed, null)
|
||||||
} else if(char == ' ' && !inQuotes) {
|
} else if(char == ' ' && !inQuotes) {
|
||||||
flushAll()
|
flushAll()
|
||||||
} else {
|
} else {
|
||||||
|
@ -6,7 +6,24 @@ import ru.lanwen.verbalregex.VerbalExpression
|
|||||||
class Text: QueryComponent() {
|
class Text: QueryComponent() {
|
||||||
val components = mutableListOf<TextComponent>()
|
val components = mutableListOf<TextComponent>()
|
||||||
|
|
||||||
fun asRegex(): VerbalExpression.Builder {
|
private var regex: VerbalExpression? = null
|
||||||
|
private var lenientRegex: VerbalExpression? = null
|
||||||
|
|
||||||
|
fun asRegex(): VerbalExpression {
|
||||||
|
if(regex == null) {
|
||||||
|
regex = baseBuilder().build()
|
||||||
|
}
|
||||||
|
return regex!!
|
||||||
|
}
|
||||||
|
|
||||||
|
fun asLenientRegex(): VerbalExpression {
|
||||||
|
if(lenientRegex == null) {
|
||||||
|
lenientRegex = baseBuilder().anything().build()
|
||||||
|
}
|
||||||
|
return lenientRegex!!
|
||||||
|
}
|
||||||
|
|
||||||
|
fun baseBuilder(): VerbalExpression.Builder {
|
||||||
val builder = VerbalExpression.regex()
|
val builder = VerbalExpression.regex()
|
||||||
for(component in components) {
|
for(component in components) {
|
||||||
when(component) {
|
when(component) {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user