ICU-20916 late computation of roundedThreshold to ensure it is up to date

This commit is contained in:
Markus Scherer 2020-03-17 15:31:31 -07:00
parent b1af32bfa7
commit 1b71013da0
2 changed files with 24 additions and 20 deletions

View File

@ -111,11 +111,6 @@ int32_t LocaleDistance::getBestIndexAndDistance(
const LSR **supportedLSRs, int32_t supportedLSRsLength,
int32_t shiftedThreshold,
ULocMatchFavorSubtag favorSubtag, ULocMatchDirection direction) const {
// Round up the shifted threshold (if fraction bits are not 0)
// for comparison with un-shifted distances until we need fraction bits.
// (If we simply shifted non-zero fraction bits away, then we might ignore a language
// when it's really still a micro distance below the threshold.)
int32_t roundedThreshold = (shiftedThreshold + DISTANCE_FRACTION_MASK) >> DISTANCE_SHIFT;
BytesTrie iter(trie);
// Look up the desired language only once for all supported LSRs.
// Its "distance" is either a match point value of 0, or a non-match negative value.
@ -155,6 +150,11 @@ int32_t LocaleDistance::getBestIndexAndDistance(
star = true;
}
U_ASSERT(0 <= distance && distance <= 100);
// Round up the shifted threshold (if fraction bits are not 0)
// for comparison with un-shifted distances until we need fraction bits.
// (If we simply shifted non-zero fraction bits away, then we might ignore a language
// when it's really still a micro distance below the threshold.)
int32_t roundedThreshold = (shiftedThreshold + DISTANCE_FRACTION_MASK) >> DISTANCE_SHIFT;
// We implement "favor subtag" by reducing the language subtag distance
// (unscientifically reducing it to a quarter of the normal value),
// so that the script distance is relatively more important.
@ -163,7 +163,9 @@ int32_t LocaleDistance::getBestIndexAndDistance(
if (favorSubtag == ULOCMATCH_FAVOR_SCRIPT) {
distance >>= 2;
}
if (distance >= roundedThreshold) {
// Let distance == roundedThreshold pass until the tie-breaker logic
// at the end of the loop.
if (distance > roundedThreshold) {
continue;
}
@ -181,7 +183,7 @@ int32_t LocaleDistance::getBestIndexAndDistance(
scriptDistance &= ~DISTANCE_IS_FINAL;
}
distance += scriptDistance;
if (distance >= roundedThreshold) {
if (distance > roundedThreshold) {
continue;
}
@ -191,7 +193,7 @@ int32_t LocaleDistance::getBestIndexAndDistance(
distance += defaultRegionDistance;
} else {
int32_t remainingThreshold = roundedThreshold - distance;
if (minRegionDistance >= remainingThreshold) {
if (minRegionDistance > remainingThreshold) {
continue;
}
@ -319,7 +321,7 @@ int32_t LocaleDistance::getRegionPartitionsDistance(
d = getFallbackRegionDistance(iter, startState);
star = true;
}
if (d >= threshold) {
if (d > threshold) {
return d;
} else if (regionDistance < d) {
regionDistance = d;
@ -332,7 +334,7 @@ int32_t LocaleDistance::getRegionPartitionsDistance(
}
} else if (!star) {
int32_t d = getFallbackRegionDistance(iter, startState);
if (d >= threshold) {
if (d > threshold) {
return d;
} else if (regionDistance < d) {
regionDistance = d;

View File

@ -244,11 +244,6 @@ public class LocaleDistance {
*/
public int getBestIndexAndDistance(LSR desired, LSR[] supportedLSRs, int supportedLSRsLength,
int shiftedThreshold, FavorSubtag favorSubtag, LocaleMatcher.Direction direction) {
// Round up the shifted threshold (if fraction bits are not 0)
// for comparison with un-shifted distances until we need fraction bits.
// (If we simply shifted non-zero fraction bits away, then we might ignore a language
// when it's really still a micro distance below the threshold.)
int roundedThreshold = (shiftedThreshold + DISTANCE_FRACTION_MASK) >> DISTANCE_SHIFT;
BytesTrie iter = new BytesTrie(trie);
// Look up the desired language only once for all supported LSRs.
// Its "distance" is either a match point value of 0, or a non-match negative value.
@ -288,6 +283,11 @@ public class LocaleDistance {
star = true;
}
assert 0 <= distance && distance <= 100;
// Round up the shifted threshold (if fraction bits are not 0)
// for comparison with un-shifted distances until we need fraction bits.
// (If we simply shifted non-zero fraction bits away, then we might ignore a language
// when it's really still a micro distance below the threshold.)
int roundedThreshold = (shiftedThreshold + DISTANCE_FRACTION_MASK) >> DISTANCE_SHIFT;
// We implement "favor subtag" by reducing the language subtag distance
// (unscientifically reducing it to a quarter of the normal value),
// so that the script distance is relatively more important.
@ -296,7 +296,9 @@ public class LocaleDistance {
if (favorSubtag == FavorSubtag.SCRIPT) {
distance >>= 2;
}
if (distance >= roundedThreshold) {
// Let distance == roundedThreshold pass until the tie-breaker logic
// at the end of the loop.
if (distance > roundedThreshold) {
continue;
}
@ -314,7 +316,7 @@ public class LocaleDistance {
scriptDistance &= ~DISTANCE_IS_FINAL;
}
distance += scriptDistance;
if (distance >= roundedThreshold) {
if (distance > roundedThreshold) {
continue;
}
@ -324,7 +326,7 @@ public class LocaleDistance {
distance += defaultRegionDistance;
} else {
int remainingThreshold = roundedThreshold - distance;
if (minRegionDistance >= remainingThreshold) {
if (minRegionDistance > remainingThreshold) {
continue;
}
@ -452,7 +454,7 @@ public class LocaleDistance {
d = getFallbackRegionDistance(iter, startState);
star = true;
}
if (d >= threshold) {
if (d > threshold) {
return d;
} else if (regionDistance < d) {
regionDistance = d;
@ -465,7 +467,7 @@ public class LocaleDistance {
}
} else if (!star) {
int d = getFallbackRegionDistance(iter, startState);
if (d >= threshold) {
if (d > threshold) {
return d;
} else if (regionDistance < d) {
regionDistance = d;