From: Markus Scherer Date: Tue, 17 Mar 2020 22:31:31 +0000 (-0700) Subject: ICU-20916 late computation of roundedThreshold to ensure it is up to date X-Git-Tag: release-67-rc~49 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=1b71013da0e6b765bd10ebf1d6717ddf8f380965;p=icu ICU-20916 late computation of roundedThreshold to ensure it is up to date --- diff --git a/icu4c/source/common/locdistance.cpp b/icu4c/source/common/locdistance.cpp index 26d3ff78e5e..18e4d91bce9 100644 --- a/icu4c/source/common/locdistance.cpp +++ b/icu4c/source/common/locdistance.cpp @@ -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; diff --git a/icu4j/main/classes/core/src/com/ibm/icu/impl/locale/LocaleDistance.java b/icu4j/main/classes/core/src/com/ibm/icu/impl/locale/LocaleDistance.java index 796f4e976ef..fb16814f640 100644 --- a/icu4j/main/classes/core/src/com/ibm/icu/impl/locale/LocaleDistance.java +++ b/icu4j/main/classes/core/src/com/ibm/icu/impl/locale/LocaleDistance.java @@ -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;