update filter alghoritm

This commit is contained in:
2026-08-09 17:57:53 +03:00
parent 9e40ab2fd1
commit 2c0c244060
2 changed files with 13 additions and 34 deletions
@@ -2,7 +2,6 @@ package ru.shadowsparky.vbox.backend.data
import org.koin.core.annotation.Single import org.koin.core.annotation.Single
import ru.shadowsparky.vbox.shared.domain.model.VideoItem import ru.shadowsparky.vbox.shared.domain.model.VideoItem
import kotlin.math.max
@Single @Single
class FuzzyMovieSearchFilter { class FuzzyMovieSearchFilter {
@@ -15,20 +14,9 @@ class FuzzyMovieSearchFilter {
if (titleNormalized.contains(query)) { if (titleNormalized.contains(query)) {
return@map Pair(movie, 1.0) return@map Pair(movie, 1.0)
} }
val queryWords = query.split(" ") val score = titleNormalized.fuzzySimilarity(query)
val titleWords = titleNormalized.split(" ") Pair(movie, score)
var maxScore = 0.0 }.filter { it.second >= THRESHOLD }.sortedByDescending { it.second }.map { it.first }
for (qWord in queryWords) {
for (tWord in titleWords) {
val score = tWord.fuzzySimilarity(qWord)
if (score > maxScore) maxScore = score
}
}
Pair(movie, maxScore)
}
.filter { it.second >= THRESHOLD }
.sortedByDescending { it.second }
.map { it.first }
} }
private fun String.normalize(): String { private fun String.normalize(): String {
@@ -61,27 +49,18 @@ class FuzzyMovieSearchFilter {
private fun String.fuzzySimilarity(other: String): Double { private fun String.fuzzySimilarity(other: String): Double {
if (this == other) return 1.0 if (this == other) return 1.0
if (this.isEmpty() || other.isEmpty()) return 0.0 if (this.isBlank() || other.isBlank()) return 0.0
val s1 = this val s1Pairs = this.windowed(2)
val dp = IntArray(other.length + 1) { it } val s2Pairs = other.windowed(2).toMutableList()
for (i in 1..s1.length) { if (s1Pairs.isEmpty() || s2Pairs.isEmpty()) return 0.0
var prev = dp[0] var matches = 0
dp[0] = i for (pair in s1Pairs) {
for (j in 1..other.length) { if (s2Pairs.remove(pair)) { matches++ }
val temp = dp[j]
if (s1[i - 1] == other[j - 1]) {
dp[j] = prev
} else {
dp[j] = minOf(dp[j - 1], dp[j], prev) + 1
}
prev = temp
}
} }
val maxLen = max(s1.length, other.length) return (2.0 * matches) / (s1Pairs.size + other.windowed(2).size)
return (maxLen - dp[other.length]).toDouble() / maxLen
} }
private companion object { private companion object {
const val THRESHOLD: Double = 0.5 const val THRESHOLD: Double = 0.45
} }
} }
@@ -26,7 +26,7 @@ class SessionVideoApi(
private val linksMutex = Mutex() private val linksMutex = Mutex()
override suspend fun fetchNewVideos(query: String?): VideosResponse { override suspend fun fetchNewVideos(query: String?): VideosResponse {
val cacheKey = query.orEmpty() val cacheKey = query?.trim().orEmpty()
videosCache.getValid(cacheKey)?.let { return it } videosCache.getValid(cacheKey)?.let { return it }
return videosMutex.withLock { return videosMutex.withLock {
videosCache.getValid(cacheKey) ?: run { videosCache.getValid(cacheKey) ?: run {