Merge "Check whether contacts have changed using hashCode()."

main
Keisuke Kuroyanagi 2014-05-09 03:48:19 +00:00 committed by Android (Google) Code Review
commit 28ebe2db23
4 changed files with 39 additions and 71 deletions

View File

@ -31,9 +31,12 @@ import android.util.Log;
import com.android.inputmethod.annotations.UsedForTesting;
import com.android.inputmethod.latin.personalization.AccountUtils;
import com.android.inputmethod.latin.utils.CollectionUtils;
import com.android.inputmethod.latin.utils.ExecutorUtils;
import com.android.inputmethod.latin.utils.StringUtils;
import java.io.File;
import java.util.ArrayList;
import java.util.List;
import java.util.Locale;
@ -60,7 +63,10 @@ public class ContactsBinaryDictionary extends ExpandableBinaryDictionary {
private static final int INDEX_NAME = 1;
/** The number of contacts in the most recent dictionary rebuild. */
static private int sContactCountAtLastRebuild = 0;
private int mContactCountAtLastRebuild = 0;
/** The hash code of ArrayList of contacts names in the most recent dictionary rebuild. */
private int mHashCodeAtLastRebuild = 0;
private ContentObserver mObserver;
@ -96,7 +102,14 @@ public class ContactsBinaryDictionary extends ExpandableBinaryDictionary {
new ContentObserver(null) {
@Override
public void onChange(boolean self) {
setNeedsToReload();
ExecutorUtils.getExecutor("Check Contacts").execute(new Runnable() {
@Override
public void run() {
if (haveContentsChanged()) {
setNeedsToRecreate();
}
}
});
}
});
}
@ -143,7 +156,7 @@ public class ContactsBinaryDictionary extends ExpandableBinaryDictionary {
return;
}
if (cursor.moveToFirst()) {
sContactCountAtLastRebuild = getContactCount();
mContactCountAtLastRebuild = getContactCount();
addWordsLocked(cursor);
}
} catch (final SQLiteException e) {
@ -167,9 +180,11 @@ public class ContactsBinaryDictionary extends ExpandableBinaryDictionary {
private void addWordsLocked(final Cursor cursor) {
int count = 0;
final ArrayList<String> names = CollectionUtils.newArrayList();
while (!cursor.isAfterLast() && count < MAX_CONTACT_COUNT) {
String name = cursor.getString(INDEX_NAME);
if (isValidName(name)) {
names.add(name);
addNameLocked(name);
++count;
} else {
@ -179,6 +194,7 @@ public class ContactsBinaryDictionary extends ExpandableBinaryDictionary {
}
cursor.moveToNext();
}
mHashCodeAtLastRebuild = names.hashCode();
}
private int getContactCount() {
@ -258,8 +274,7 @@ public class ContactsBinaryDictionary extends ExpandableBinaryDictionary {
return end;
}
@Override
protected boolean haveContentsChanged() {
private boolean haveContentsChanged() {
final long startTime = SystemClock.uptimeMillis();
final int contactCount = getContactCount();
if (contactCount > MAX_CONTACT_COUNT) {
@ -268,9 +283,9 @@ public class ContactsBinaryDictionary extends ExpandableBinaryDictionary {
// TODO: Sort and check only the MAX_CONTACT_COUNT most recent contacts?
return false;
}
if (contactCount != sContactCountAtLastRebuild) {
if (contactCount != mContactCountAtLastRebuild) {
if (DEBUG) {
Log.d(TAG, "Contact count changed: " + sContactCountAtLastRebuild + " to "
Log.d(TAG, "Contact count changed: " + mContactCountAtLastRebuild + " to "
+ contactCount);
}
return true;
@ -283,20 +298,20 @@ public class ContactsBinaryDictionary extends ExpandableBinaryDictionary {
if (null == cursor) {
return false;
}
final ArrayList<String> names = CollectionUtils.newArrayList();
try {
if (cursor.moveToFirst()) {
while (!cursor.isAfterLast()) {
String name = cursor.getString(INDEX_NAME);
if (isValidName(name) && !isNameInDictionaryLocked(name)) {
if (DEBUG) {
Log.d(TAG, "Contact name missing: " + name + " (runtime = "
+ (SystemClock.uptimeMillis() - startTime) + " ms)");
}
return true;
if (isValidName(name)) {
names.add(name);
}
cursor.moveToNext();
}
}
if (names.hashCode() != mHashCodeAtLastRebuild) {
return true;
}
} finally {
cursor.close();
}
@ -313,33 +328,4 @@ public class ContactsBinaryDictionary extends ExpandableBinaryDictionary {
}
return false;
}
/**
* Checks if the words in a name are in the current binary dictionary.
*/
private boolean isNameInDictionaryLocked(final String name) {
int len = StringUtils.codePointCount(name);
String prevWord = null;
for (int i = 0; i < len; i++) {
if (Character.isLetter(name.codePointAt(i))) {
int end = getWordEndPosition(name, len, i);
String word = name.substring(i, end);
i = end - 1;
final int wordLen = StringUtils.codePointCount(word);
if (wordLen < MAX_WORD_LENGTH && wordLen > 1) {
if (!TextUtils.isEmpty(prevWord) && mUseFirstLastBigrams) {
if (!isValidBigramLocked(prevWord, word)) {
return false;
}
} else {
if (!isValidWordLocked(word)) {
return false;
}
}
prevWord = word;
}
}
}
return true;
}
}

View File

@ -92,8 +92,8 @@ abstract public class ExpandableBinaryDictionary extends Dictionary {
/** Indicates whether a task for reloading the dictionary has been scheduled. */
private final AtomicBoolean mIsReloading;
/** Indicates whether the current dictionary needs to be reloaded. */
private boolean mNeedsToReload;
/** Indicates whether the current dictionary needs to be recreated. */
private boolean mNeedsToRecreate;
private final ReentrantReadWriteLock mLock;
@ -107,13 +107,6 @@ abstract public class ExpandableBinaryDictionary extends Dictionary {
*/
protected abstract void loadInitialContentsLocked();
/**
* Indicates that the source dictionary contents have changed and a rebuild of the binary file
* is required. If it returns false, the next reload will only read the current binary
* dictionary from file.
*/
protected abstract boolean haveContentsChanged();
private boolean matchesExpectedBinaryDictFormatVersionForThisType(final int formatVersion) {
return formatVersion == FormatSpec.VERSION4;
}
@ -147,7 +140,7 @@ abstract public class ExpandableBinaryDictionary extends Dictionary {
mDictFile = getDictFile(context, dictName, dictFile);
mBinaryDictionary = null;
mIsReloading = new AtomicBoolean();
mNeedsToReload = false;
mNeedsToRecreate = false;
mLock = new ReentrantReadWriteLock();
}
@ -489,11 +482,11 @@ abstract public class ExpandableBinaryDictionary extends Dictionary {
}
/**
* Marks that the dictionary needs to be reloaded.
* Marks that the dictionary needs to be recreated.
*
*/
protected void setNeedsToReload() {
mNeedsToReload = true;
protected void setNeedsToRecreate() {
mNeedsToRecreate = true;
}
/**
@ -511,7 +504,7 @@ abstract public class ExpandableBinaryDictionary extends Dictionary {
* Returns whether a dictionary reload is required.
*/
private boolean isReloadRequired() {
return mBinaryDictionary == null || mNeedsToReload;
return mBinaryDictionary == null || mNeedsToRecreate;
}
/**
@ -523,8 +516,7 @@ abstract public class ExpandableBinaryDictionary extends Dictionary {
@Override
public void run() {
try {
// TODO: Quit checking contents in ExpandableBinaryDictionary.
if (!mDictFile.exists() || (mNeedsToReload && haveContentsChanged())) {
if (!mDictFile.exists() || mNeedsToRecreate) {
// If the dictionary file does not exist or contents have been updated,
// generate a new one.
createNewDictionaryLocked();
@ -536,12 +528,12 @@ abstract public class ExpandableBinaryDictionary extends Dictionary {
&& matchesExpectedBinaryDictFormatVersionForThisType(
mBinaryDictionary.getFormatVersion()))) {
// Binary dictionary or its format version is not valid. Regenerate
// the dictionary file. writeBinaryDictionary will remove the
// the dictionary file. createNewDictionaryLocked will remove the
// existing files if appropriate.
createNewDictionaryLocked();
}
}
mNeedsToReload = false;
mNeedsToRecreate = false;
} finally {
mIsReloading.set(false);
}

View File

@ -98,7 +98,7 @@ public class UserBinaryDictionary extends ExpandableBinaryDictionary {
// devices. On older versions of the platform, the hook above will be called instead.
@Override
public void onChange(final boolean self, final Uri uri) {
setNeedsToReload();
setNeedsToRecreate();
}
};
cres.registerContentObserver(Words.CONTENT_URI, true, mObserver);
@ -272,9 +272,4 @@ public class UserBinaryDictionary extends ExpandableBinaryDictionary {
}
}
}
@Override
protected boolean haveContentsChanged() {
return true;
}
}

View File

@ -73,11 +73,6 @@ public abstract class DecayingExpandableBinaryDictionaryBase extends ExpandableB
return attributeMap;
}
@Override
protected boolean haveContentsChanged() {
return false;
}
@Override
protected void loadInitialContentsLocked() {
// No initial contents.