diff options
author | Dmitri Plotnikov <dplotnikov@google.com> | 2009-09-21 15:01:41 -0700 |
---|---|---|
committer | Dmitri Plotnikov <dplotnikov@google.com> | 2009-09-21 15:15:01 -0700 |
commit | c91ffc49403818f280c382f01bbfd5cd9a9bca6b (patch) | |
tree | 06b4efb2182010d5b37171ccba070d3ce48f97da /src/com/android/providers/contacts/NameLookupBuilder.java | |
parent | 4e3790e646bce315a1b34c9dc474eb8152c8eea2 (diff) | |
download | packages_providers_ContactsProvider-c91ffc49403818f280c382f01bbfd5cd9a9bca6b.tar.gz packages_providers_ContactsProvider-c91ffc49403818f280c382f01bbfd5cd9a9bca6b.tar.bz2 packages_providers_ContactsProvider-c91ffc49403818f280c382f01bbfd5cd9a9bca6b.zip |
Fixing OOM exception in ContactsProvider2 caused by names that look like this: "A B C D E F G H I"
Since we are computing all possible permutation of names, a name with 10 words would
cause us to create 7,257,600 rows in the name_lookup table.
Limiting that to just 4 words, 48 rows max. Choosing the 4 longest words to
improve reliability of matching.
Change-Id: I83b1424cc14a291d8d8b615a356d6ec4f9e00aad
Diffstat (limited to 'src/com/android/providers/contacts/NameLookupBuilder.java')
-rw-r--r-- | src/com/android/providers/contacts/NameLookupBuilder.java | 28 |
1 files changed, 23 insertions, 5 deletions
diff --git a/src/com/android/providers/contacts/NameLookupBuilder.java b/src/com/android/providers/contacts/NameLookupBuilder.java index 95909d0a..9229a047 100644 --- a/src/com/android/providers/contacts/NameLookupBuilder.java +++ b/src/com/android/providers/contacts/NameLookupBuilder.java @@ -18,14 +18,18 @@ package com.android.providers.contacts; import com.android.providers.contacts.OpenHelper.NameLookupType; +import java.util.Arrays; +import java.util.Comparator; + /** * Given a full name, constructs all possible variants of the name. */ public abstract class NameLookupBuilder { + private static final int MAX_NAME_TOKENS = 4; + private final NameSplitter mSplitter; - private String[] mNormalizedNames = new String[NameSplitter.MAX_TOKENS]; - private String[][] mNicknameClusters = new String[NameSplitter.MAX_TOKENS][]; + private String[][] mNicknameClusters = new String[MAX_NAME_TOKENS][]; private StringBuilder mStringBuilder1 = new StringBuilder(); private StringBuilder mStringBuilder2 = new StringBuilder(); private String[] mNames = new String[NameSplitter.MAX_TOKENS]; @@ -61,16 +65,30 @@ public abstract class NameLookupBuilder { } for (int i = 0; i < tokenCount; i++) { - mNormalizedNames[i] = normalizeName(mNames[i]); + mNames[i] = normalizeName(mNames[i]); + } + + boolean tooManyTokens = tokenCount > MAX_NAME_TOKENS; + if (tooManyTokens) { + insertNameVariant(rawContactId, dataId, tokenCount, NameLookupType.NAME_EXACT, true); + + // Favor longer parts of the name + Arrays.sort(mNames, 0, tokenCount, new Comparator<String>() { + + public int compare(String s1, String s2) { + return s2.length() - s1.length(); + } + }); + + tokenCount = MAX_NAME_TOKENS; } // Phase I: insert all variants not involving nickname clusters for (int i = 0; i < tokenCount; i++) { - mNames[i] = mNormalizedNames[i]; mNicknameClusters[i] = getCommonNicknameClusters(mNames[i]); } - insertNameVariants(rawContactId, dataId, 0, tokenCount, true, true); + insertNameVariants(rawContactId, dataId, 0, tokenCount, !tooManyTokens, true); insertNicknamePermutations(rawContactId, dataId, 0, tokenCount); } |