summaryrefslogtreecommitdiff
path: root/java/com/android/dialer/enrichedcall/FuzzyPhoneNumberMatcher.java
diff options
context:
space:
mode:
Diffstat (limited to 'java/com/android/dialer/enrichedcall/FuzzyPhoneNumberMatcher.java')
-rw-r--r--java/com/android/dialer/enrichedcall/FuzzyPhoneNumberMatcher.java50
1 files changed, 40 insertions, 10 deletions
diff --git a/java/com/android/dialer/enrichedcall/FuzzyPhoneNumberMatcher.java b/java/com/android/dialer/enrichedcall/FuzzyPhoneNumberMatcher.java
index 250c64313..6f4d97521 100644
--- a/java/com/android/dialer/enrichedcall/FuzzyPhoneNumberMatcher.java
+++ b/java/com/android/dialer/enrichedcall/FuzzyPhoneNumberMatcher.java
@@ -16,20 +16,50 @@
package com.android.dialer.enrichedcall;
import android.support.annotation.NonNull;
-import com.android.dialer.common.Assert;
/** Utility for comparing phone numbers. */
public class FuzzyPhoneNumberMatcher {
- /** Returns {@code true} if the given numbers can be interpreted to be the same. */
- public static boolean matches(@NonNull String a, @NonNull String b) {
- String aNormalized = Assert.isNotNull(a).replaceAll("[^0-9]", "");
- String bNormalized = Assert.isNotNull(b).replaceAll("[^0-9]", "");
- if (aNormalized.length() < 7 || bNormalized.length() < 7) {
- return false;
+ private static final int REQUIRED_MATCHED_DIGITS = 7;
+
+ /**
+ * Returns {@code true} if the given numbers can be interpreted to be the same.
+ *
+ * <p>This method is called numerous times when rendering the call log. Using string methods is
+ * too slow, so character by character matching is used instead.
+ */
+ public static boolean matches(@NonNull String lhs, @NonNull String rhs) {
+ return lastSevenDigitsCharacterByCharacterMatches(lhs, rhs);
+ }
+
+ /**
+ * This strategy examines the numbers character by character starting from the end. If the last
+ * {@link #REQUIRED_MATCHED_DIGITS} match, it returns {@code true}.
+ */
+ private static boolean lastSevenDigitsCharacterByCharacterMatches(
+ @NonNull String lhs, @NonNull String rhs) {
+ int lhsIndex = lhs.length() - 1;
+ int rhsIndex = rhs.length() - 1;
+
+ int matchedDigits = 0;
+
+ while (lhsIndex >= 0 && rhsIndex >= 0) {
+ if (!Character.isDigit(lhs.charAt(lhsIndex))) {
+ --lhsIndex;
+ continue;
+ }
+ if (!Character.isDigit(rhs.charAt(rhsIndex))) {
+ --rhsIndex;
+ continue;
+ }
+ if (lhs.charAt(lhsIndex) != rhs.charAt(rhsIndex)) {
+ break;
+ }
+ --lhsIndex;
+ --rhsIndex;
+ ++matchedDigits;
}
- String aMatchable = aNormalized.substring(aNormalized.length() - 7);
- String bMatchable = bNormalized.substring(bNormalized.length() - 7);
- return aMatchable.equals(bMatchable);
+
+ return matchedDigits >= REQUIRED_MATCHED_DIGITS;
}
}