Support isSuccessful in SuccessfulResultCollector

Since now SuccessfulResultCollector do not run computation of
resultingApplicability for error candidate before
getFinalCandidates(). It is very useful because we can do not run
all checks for error candidates if we have not-error candidate.
This commit is contained in:
Stanislav Erokhin
2017-08-15 16:34:58 +03:00
parent 6b8293ae5b
commit da003d48ff
@@ -208,14 +208,7 @@ class TowerResolver {
abstract fun getFinalCandidates(): Collection<C> abstract fun getFinalCandidates(): Collection<C>
fun pushCandidates(candidates: Collection<C>) { abstract fun pushCandidates(candidates: Collection<C>)
val filteredCandidates = candidates.filter {
it.resultingApplicability != ResolutionCandidateApplicability.HIDDEN
}
if (filteredCandidates.isNotEmpty()) addCandidates(filteredCandidates)
}
protected abstract fun addCandidates(candidates: Collection<C>)
} }
class AllCandidatesCollector<C : Candidate>: ResultCollector<C>() { class AllCandidatesCollector<C : Candidate>: ResultCollector<C>() {
@@ -225,33 +218,51 @@ class TowerResolver {
override fun getFinalCandidates(): Collection<C> = allCandidates override fun getFinalCandidates(): Collection<C> = allCandidates
override fun addCandidates(candidates: Collection<C>) { override fun pushCandidates(candidates: Collection<C>) {
allCandidates.addAll(candidates) candidates.filterNotTo(allCandidates) {
it.resultingApplicability == ResolutionCandidateApplicability.HIDDEN
}
} }
} }
class SuccessfulResultCollector<C : Candidate>: ResultCollector<C>() { class SuccessfulResultCollector<C : Candidate> : ResultCollector<C>() {
private var currentCandidates: Collection<C> = emptyList() private var candidateGroups = arrayListOf<Collection<C>>()
private var currentLevel: ResolutionCandidateApplicability? = null private var isSuccessful = false
override fun getSuccessfulCandidates(): Collection<C>? = getResolved() override fun getSuccessfulCandidates(): Collection<C>? {
if (!isSuccessful) return null
val firstGroupWithResolved = candidateGroups.firstOrNull {
it.any { it.resultingApplicability == ResolutionCandidateApplicability.RESOLVED }
} ?: return null
fun getResolved() = currentCandidates.takeIf { currentLevel == ResolutionCandidateApplicability.RESOLVED } return firstGroupWithResolved.filter { it.resultingApplicability == ResolutionCandidateApplicability.RESOLVED }
fun getResolvedLowPriority() = currentCandidates.takeIf { currentLevel == ResolutionCandidateApplicability.RESOLVED_LOW_PRIORITY }
fun getErrors() = currentCandidates.takeIf {
currentLevel == null || currentLevel!! > ResolutionCandidateApplicability.RESOLVED_LOW_PRIORITY
} }
override fun getFinalCandidates() = getResolved() ?: getResolvedLowPriority() ?: getErrors() ?: emptyList() override fun pushCandidates(candidates: Collection<C>) {
val thereIsSuccessful = candidates.any { it.isSuccessful }
if (!isSuccessful && !thereIsSuccessful) {
candidateGroups.add(candidates)
return
}
override fun addCandidates(candidates: Collection<C>) { if (!isSuccessful) {
val minimalLevel = candidates.map { it.resultingApplicability }.min()!! candidateGroups.clear()
if (currentLevel == null || currentLevel!! > minimalLevel) { isSuccessful = true
currentLevel = minimalLevel }
currentCandidates = candidates.filter { it.resultingApplicability == minimalLevel } if (thereIsSuccessful) {
candidateGroups.add(candidates.filter { it.isSuccessful })
} }
} }
override fun getFinalCandidates(): Collection<C> {
val moreSuitableGroup = candidateGroups.minBy { it.groupApplicability } ?: return emptyList()
val groupApplicability = moreSuitableGroup.groupApplicability
if (groupApplicability == ResolutionCandidateApplicability.HIDDEN) return emptyList()
return moreSuitableGroup.filter { it.resultingApplicability == groupApplicability }
}
private val Collection<C>.groupApplicability get() =
minBy { it.resultingApplicability }?.resultingApplicability ?: ResolutionCandidateApplicability.HIDDEN
} }
} }