]> granicus.if.org Git - icu/commitdiff
ICU-20916 late computation of roundedThreshold to ensure it is up to date
authorMarkus Scherer <markus.icu@gmail.com>
Tue, 17 Mar 2020 22:31:31 +0000 (15:31 -0700)
committerMarkus Scherer <markus.icu@gmail.com>
Wed, 18 Mar 2020 01:28:32 +0000 (18:28 -0700)
icu4c/source/common/locdistance.cpp
icu4j/main/classes/core/src/com/ibm/icu/impl/locale/LocaleDistance.java

index 26d3ff78e5ee1c5c47495636024ed707734315d7..18e4d91bce921ba31b6ea5481a094bd656851133 100644 (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;
index 796f4e976ef1cc0f352d294042abc22e7a0b7f7d..fb16814f640d8ba2a5b7b95be17d03d8c010c71f 100644 (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;