Skip to content

Commit

Permalink
perf: 优化查询逻辑
Browse files Browse the repository at this point in the history
  • Loading branch information
lisonge committed Dec 26, 2023
1 parent b1d0e66 commit 589df8f
Show file tree
Hide file tree
Showing 6 changed files with 187 additions and 307 deletions.
28 changes: 4 additions & 24 deletions app/src/main/kotlin/li/songe/gkd/data/AppRule.kt
Original file line number Diff line number Diff line change
@@ -1,43 +1,23 @@
package li.songe.gkd.data

import li.songe.gkd.service.TopActivity
import li.songe.selector.Selector

class AppRule(
matches: List<Selector>,
excludeMatches: List<Selector>,
actionDelay: Long,
quickFind: Boolean,
matchDelay: Long,
matchTime: Long?,
resetMatch: String?,
key: Int?,
preKeys: Set<Int>,
index: Int,
rule: RawSubscription.RawAppRule,
subsItem: SubsItem,
group: RawSubscription.RawAppGroup,
rawSubs: RawSubscription,
val appId: String,
val activityIds: List<String>,
val excludeActivityIds: List<String>,
val app: RawSubscription.RawApp,
) : ResolvedRule(
matches = matches,
excludeMatches = excludeMatches,
actionDelay = actionDelay,
quickFind = quickFind,
matchDelay = matchDelay,
matchTime = matchTime,
resetMatch = resetMatch,
key = key,
preKeys = preKeys,
index = index,
rule = rule,
group = group,
subsItem = subsItem,
rawSubs = rawSubs,
) {
val appId = app.id
val activityIds = getFixActivityIds(app.id, rule.activityIds ?: group.activityIds)
val excludeActivityIds =
getFixActivityIds(app.id, rule.excludeActivityIds ?: group.excludeActivityIds)

override val type = "app"
override fun matchActivity(topActivity: TopActivity?): Boolean {
Expand Down
35 changes: 12 additions & 23 deletions app/src/main/kotlin/li/songe/gkd/data/GlobalRule.kt
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
package li.songe.gkd.data

import li.songe.gkd.service.TopActivity
import li.songe.selector.Selector

data class GlobalApp(
val id: String,
Expand All @@ -11,39 +10,29 @@ data class GlobalApp(
)

class GlobalRule(
matches: List<Selector>,
excludeMatches: List<Selector>,
actionDelay: Long,
quickFind: Boolean,
matchDelay: Long,
matchTime: Long?,
resetMatch: String?,
key: Int?,
preKeys: Set<Int>,
index: Int,
subsItem: SubsItem,
rule: RawSubscription.RawGlobalRule,
group: RawSubscription.RawGlobalGroup,
rawSubs: RawSubscription,
val apps: Map<String, GlobalApp>,
val matchAnyApp: Boolean,
) : ResolvedRule(
matches = matches,
excludeMatches = excludeMatches,
actionDelay = actionDelay,
quickFind = quickFind,
matchDelay = matchDelay,
matchTime = matchTime,
resetMatch = resetMatch,
key = key,
preKeys = preKeys,
index = index,
rule = rule,
group = group,
subsItem = subsItem,
rawSubs = rawSubs,
) {

val matchAnyApp = rule.matchAnyApp ?: group.matchAnyApp ?: true
val apps = mutableMapOf<String, GlobalApp>().apply {
(rule.apps ?: group.apps ?: emptyList()).forEach { a ->
this[a.id] = GlobalApp(
id = a.id,
enable = a.enable ?: true,
activityIds = getFixActivityIds(a.id, a.activityIds),
excludeActivityIds = getFixActivityIds(a.id, a.excludeActivityIds)
)
}
}

override val type = "global"

private val excludeAppIds = apps.filter { e -> !e.value.enable }.keys
Expand Down
138 changes: 90 additions & 48 deletions app/src/main/kotlin/li/songe/gkd/data/ResolvedRule.kt
Original file line number Diff line number Diff line change
Expand Up @@ -9,26 +9,63 @@ import li.songe.gkd.service.querySelector
import li.songe.selector.Selector

sealed class ResolvedRule(
val matches: List<Selector>,
val excludeMatches: List<Selector>,

val actionDelay: Long,
val quickFind: Boolean,

val matchDelay: Long,
val matchTime: Long?,
val resetMatch: String?,

val key: Int?,
val preKeys: Set<Int>,

val index: Int,
val rule: RawSubscription.RawRuleProps,
val group: RawSubscription.RawGroupProps,
val rawSubs: RawSubscription,
val subsItem: SubsItem,
) {
var preAppRules: Set<ResolvedRule> = emptySet()
val key = rule.key
val index = group.rules.indexOf(rule)
val preKeys = (rule.preKeys ?: emptyList()).toSet()
val resetMatch = rule.resetMatch ?: group.resetMatch
val matches = rule.matches.map { s -> Selector.parse(s) }
val excludeMatches = (rule.excludeMatches ?: emptyList()).map { s -> Selector.parse(s) }
val matchDelay = rule.matchDelay ?: group.matchDelay ?: 0L
val actionDelay = rule.actionDelay ?: group.actionDelay ?: 0L
val matchTime = rule.matchTime ?: group.matchTime
val quickFind = rule.quickFind ?: group.quickFind ?: false

val actionCdKey = rule.actionCdKey ?: group.actionCdKey
val actionCd = rule.actionCd ?: if (actionCdKey != null) {
group.rules.find { r -> r.key == actionCdKey }?.actionCd
} else {
null
} ?: group.actionCd ?: 1000L

val actionMaximumKey = rule.actionMaximumKey ?: group.actionMaximumKey
val actionMaximum = rule.actionMaximum ?: if (actionMaximumKey != null) {
group.rules.find { r -> r.key == actionMaximumKey }?.actionMaximum
} else {
null
} ?: group.actionMaximum

var groupRules: List<ResolvedRule> = emptyList()
set(value) {
field = value
// 共享次数
if (actionMaximumKey != null) {
val otherRule = field.find { r -> r.key == actionMaximumKey }
if (otherRule != null) {
actionCount = otherRule.actionCount
}
}
// 共享 cd
if (actionCdKey != null) {
val otherRule = field.find { r -> r.key == actionCdKey }
if (otherRule != null) {
actionTriggerTime = otherRule.actionTriggerTime
}
}
preRules = field.filter { otherRule ->
(otherRule.key != null) && preKeys.contains(
otherRule.key
)
}.toSet()
}

var preRules = emptySet<ResolvedRule>()
val hasNext = group.rules.any { r -> r.preKeys?.any { k -> k == rule.key } == true }

var actionDelayTriggerTime = 0L
var actionDelayJob: Job? = null
fun checkDelay(): Boolean {
Expand All @@ -39,14 +76,6 @@ sealed class ResolvedRule(
return false
}

val actionCdKey = rule.actionCdKey ?: group.actionCdKey
val actionCd = rule.actionCd ?: (if (actionCdKey != null) {
group.rules.find { r -> r.key == actionCdKey }?.actionCd
?: group.actionCd
} else {
null
} ?: group.actionCd ?: 1000L)

var actionTriggerTime = Value(0L)
fun trigger() {
actionTriggerTime.value = System.currentTimeMillis()
Expand All @@ -57,14 +86,6 @@ sealed class ResolvedRule(
lastTriggerRule = this
}

val actionMaximumKey = rule.actionMaximumKey ?: group.actionMaximumKey
val actionMaximum = rule.actionMaximum ?: ((if (actionMaximumKey != null) {
group.rules.find { r -> r.key == actionMaximumKey }?.actionMaximum
?: group.actionMaximum
} else {
null
}) ?: group.actionMaximum)

var actionCount = Value(0)

var matchChangedTime = 0L
Expand Down Expand Up @@ -93,48 +114,69 @@ sealed class ResolvedRule(

var matchDelayJob: Job? = null

val statusCode: Int
val status: RuleStatus
get() {
if (actionMaximum != null) {
if (actionCount.value >= actionMaximum) {
return 1 // 达到最大执行次数
return RuleStatus.Status1 // 达到最大执行次数
}
}
if (preAppRules.isNotEmpty()) { // 需要提前点击某个规则
lastTriggerRule ?: return 2
return if (preAppRules.any { it === lastTriggerRule }) {
0
if (preRules.isNotEmpty()) { // 需要提前点击某个规则
return if (preRules.any { it === lastTriggerRule }) {
RuleStatus.StatusOk
} else {
3 // 上一个点击的规则不在当前需要点击的列表
RuleStatus.Status2
}
}
val t = System.currentTimeMillis()
if (matchDelay > 0 && t - matchChangedTime < matchDelay) {
return 4 // 处于匹配延迟中
return RuleStatus.Status3 // 处于匹配延迟中
}
if (matchTime != null && t - matchChangedTime > matchLimitTime) {
return 5 // 超出匹配时间
return RuleStatus.Status4 // 超出匹配时间
}
if (actionTriggerTime.value + actionCd > t) {
return 6 // 处于冷却时间
return RuleStatus.Status5 // 处于冷却时间
}
if (actionDelayTriggerTime > 0) {
if (actionDelayTriggerTime + actionDelay > t) {
return 7 // 处于点击延迟中
return RuleStatus.Status6 // 处于点击延迟中
}
}
return 0
return RuleStatus.StatusOk
}
abstract val type: String
abstract fun matchActivity(topActivity: TopActivity?): Boolean

fun statusText(): String {
return "id:${subsItem.id}, v:${rawSubs.version}, rType:${type}, gKey=${group.key}, gName:${group.name}, rIndex:${index}, rKey:${key}, rCode:${
statusCode
}"
return "id:${subsItem.id}, v:${rawSubs.version}, type:${type}, gKey=${group.key}, gName:${group.name}, index:${index}, key:${key}, status:${status.name}"
}

abstract val type: String
abstract fun matchActivity(topActivity: TopActivity?): Boolean

}

sealed class RuleStatus(val name: String) {
data object StatusOk : RuleStatus("ok")
data object Status1 : RuleStatus("达到最大执行次数")
data object Status2 : RuleStatus("需要提前点击某个规则")
data object Status3 : RuleStatus("处于匹配延迟")
data object Status4 : RuleStatus("超出匹配时间")
data object Status5 : RuleStatus("处于冷却时间")
data object Status6 : RuleStatus("处于点击延迟")
}

fun getFixActivityIds(
appId: String,
activityIds: List<String>?,
): List<String> {
activityIds ?: return emptyList()
return activityIds.map { activityId ->
if (activityId.startsWith('.')) { // .a.b.c -> com.x.y.x.a.b.c
appId + activityId
} else {
activityId
}
}
}


2 changes: 0 additions & 2 deletions app/src/main/kotlin/li/songe/gkd/service/AbState.kt
Original file line number Diff line number Diff line change
Expand Up @@ -103,8 +103,6 @@ var lastTriggerTime = 0L
var appChangeTime = 0L

fun insertClickLog(rule: ResolvedRule) {
rule.trigger()
toastClickTip()
appScope.launchTry(Dispatchers.IO) {
val clickLog = ClickLog(
appId = topActivityFlow.value.appId,
Expand Down
Loading

0 comments on commit 589df8f

Please sign in to comment.