am 28ebe2db: Merge "Check whether contacts have changed using hashCode()."
* commit '28ebe2db237b5e0b5989ebcca644f469ecda66e3': Check whether contacts have changed using hashCode().main
commit
a73bcfac39
|
@ -31,9 +31,12 @@ import android.util.Log;
|
||||||
|
|
||||||
import com.android.inputmethod.annotations.UsedForTesting;
|
import com.android.inputmethod.annotations.UsedForTesting;
|
||||||
import com.android.inputmethod.latin.personalization.AccountUtils;
|
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 com.android.inputmethod.latin.utils.StringUtils;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Locale;
|
import java.util.Locale;
|
||||||
|
|
||||||
|
@ -60,7 +63,10 @@ public class ContactsBinaryDictionary extends ExpandableBinaryDictionary {
|
||||||
private static final int INDEX_NAME = 1;
|
private static final int INDEX_NAME = 1;
|
||||||
|
|
||||||
/** The number of contacts in the most recent dictionary rebuild. */
|
/** 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;
|
private ContentObserver mObserver;
|
||||||
|
|
||||||
|
@ -96,7 +102,14 @@ public class ContactsBinaryDictionary extends ExpandableBinaryDictionary {
|
||||||
new ContentObserver(null) {
|
new ContentObserver(null) {
|
||||||
@Override
|
@Override
|
||||||
public void onChange(boolean self) {
|
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;
|
return;
|
||||||
}
|
}
|
||||||
if (cursor.moveToFirst()) {
|
if (cursor.moveToFirst()) {
|
||||||
sContactCountAtLastRebuild = getContactCount();
|
mContactCountAtLastRebuild = getContactCount();
|
||||||
addWordsLocked(cursor);
|
addWordsLocked(cursor);
|
||||||
}
|
}
|
||||||
} catch (final SQLiteException e) {
|
} catch (final SQLiteException e) {
|
||||||
|
@ -167,9 +180,11 @@ public class ContactsBinaryDictionary extends ExpandableBinaryDictionary {
|
||||||
|
|
||||||
private void addWordsLocked(final Cursor cursor) {
|
private void addWordsLocked(final Cursor cursor) {
|
||||||
int count = 0;
|
int count = 0;
|
||||||
|
final ArrayList<String> names = CollectionUtils.newArrayList();
|
||||||
while (!cursor.isAfterLast() && count < MAX_CONTACT_COUNT) {
|
while (!cursor.isAfterLast() && count < MAX_CONTACT_COUNT) {
|
||||||
String name = cursor.getString(INDEX_NAME);
|
String name = cursor.getString(INDEX_NAME);
|
||||||
if (isValidName(name)) {
|
if (isValidName(name)) {
|
||||||
|
names.add(name);
|
||||||
addNameLocked(name);
|
addNameLocked(name);
|
||||||
++count;
|
++count;
|
||||||
} else {
|
} else {
|
||||||
|
@ -179,6 +194,7 @@ public class ContactsBinaryDictionary extends ExpandableBinaryDictionary {
|
||||||
}
|
}
|
||||||
cursor.moveToNext();
|
cursor.moveToNext();
|
||||||
}
|
}
|
||||||
|
mHashCodeAtLastRebuild = names.hashCode();
|
||||||
}
|
}
|
||||||
|
|
||||||
private int getContactCount() {
|
private int getContactCount() {
|
||||||
|
@ -258,8 +274,7 @@ public class ContactsBinaryDictionary extends ExpandableBinaryDictionary {
|
||||||
return end;
|
return end;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
private boolean haveContentsChanged() {
|
||||||
protected boolean haveContentsChanged() {
|
|
||||||
final long startTime = SystemClock.uptimeMillis();
|
final long startTime = SystemClock.uptimeMillis();
|
||||||
final int contactCount = getContactCount();
|
final int contactCount = getContactCount();
|
||||||
if (contactCount > MAX_CONTACT_COUNT) {
|
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?
|
// TODO: Sort and check only the MAX_CONTACT_COUNT most recent contacts?
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (contactCount != sContactCountAtLastRebuild) {
|
if (contactCount != mContactCountAtLastRebuild) {
|
||||||
if (DEBUG) {
|
if (DEBUG) {
|
||||||
Log.d(TAG, "Contact count changed: " + sContactCountAtLastRebuild + " to "
|
Log.d(TAG, "Contact count changed: " + mContactCountAtLastRebuild + " to "
|
||||||
+ contactCount);
|
+ contactCount);
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
|
@ -283,20 +298,20 @@ public class ContactsBinaryDictionary extends ExpandableBinaryDictionary {
|
||||||
if (null == cursor) {
|
if (null == cursor) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
final ArrayList<String> names = CollectionUtils.newArrayList();
|
||||||
try {
|
try {
|
||||||
if (cursor.moveToFirst()) {
|
if (cursor.moveToFirst()) {
|
||||||
while (!cursor.isAfterLast()) {
|
while (!cursor.isAfterLast()) {
|
||||||
String name = cursor.getString(INDEX_NAME);
|
String name = cursor.getString(INDEX_NAME);
|
||||||
if (isValidName(name) && !isNameInDictionaryLocked(name)) {
|
if (isValidName(name)) {
|
||||||
if (DEBUG) {
|
names.add(name);
|
||||||
Log.d(TAG, "Contact name missing: " + name + " (runtime = "
|
|
||||||
+ (SystemClock.uptimeMillis() - startTime) + " ms)");
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
cursor.moveToNext();
|
cursor.moveToNext();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (names.hashCode() != mHashCodeAtLastRebuild) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
} finally {
|
} finally {
|
||||||
cursor.close();
|
cursor.close();
|
||||||
}
|
}
|
||||||
|
@ -313,33 +328,4 @@ public class ContactsBinaryDictionary extends ExpandableBinaryDictionary {
|
||||||
}
|
}
|
||||||
return false;
|
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;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -92,8 +92,8 @@ abstract public class ExpandableBinaryDictionary extends Dictionary {
|
||||||
/** Indicates whether a task for reloading the dictionary has been scheduled. */
|
/** Indicates whether a task for reloading the dictionary has been scheduled. */
|
||||||
private final AtomicBoolean mIsReloading;
|
private final AtomicBoolean mIsReloading;
|
||||||
|
|
||||||
/** Indicates whether the current dictionary needs to be reloaded. */
|
/** Indicates whether the current dictionary needs to be recreated. */
|
||||||
private boolean mNeedsToReload;
|
private boolean mNeedsToRecreate;
|
||||||
|
|
||||||
private final ReentrantReadWriteLock mLock;
|
private final ReentrantReadWriteLock mLock;
|
||||||
|
|
||||||
|
@ -107,13 +107,6 @@ abstract public class ExpandableBinaryDictionary extends Dictionary {
|
||||||
*/
|
*/
|
||||||
protected abstract void loadInitialContentsLocked();
|
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) {
|
private boolean matchesExpectedBinaryDictFormatVersionForThisType(final int formatVersion) {
|
||||||
return formatVersion == FormatSpec.VERSION4;
|
return formatVersion == FormatSpec.VERSION4;
|
||||||
}
|
}
|
||||||
|
@ -147,7 +140,7 @@ abstract public class ExpandableBinaryDictionary extends Dictionary {
|
||||||
mDictFile = getDictFile(context, dictName, dictFile);
|
mDictFile = getDictFile(context, dictName, dictFile);
|
||||||
mBinaryDictionary = null;
|
mBinaryDictionary = null;
|
||||||
mIsReloading = new AtomicBoolean();
|
mIsReloading = new AtomicBoolean();
|
||||||
mNeedsToReload = false;
|
mNeedsToRecreate = false;
|
||||||
mLock = new ReentrantReadWriteLock();
|
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() {
|
protected void setNeedsToRecreate() {
|
||||||
mNeedsToReload = true;
|
mNeedsToRecreate = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -511,7 +504,7 @@ abstract public class ExpandableBinaryDictionary extends Dictionary {
|
||||||
* Returns whether a dictionary reload is required.
|
* Returns whether a dictionary reload is required.
|
||||||
*/
|
*/
|
||||||
private boolean isReloadRequired() {
|
private boolean isReloadRequired() {
|
||||||
return mBinaryDictionary == null || mNeedsToReload;
|
return mBinaryDictionary == null || mNeedsToRecreate;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -523,8 +516,7 @@ abstract public class ExpandableBinaryDictionary extends Dictionary {
|
||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
try {
|
try {
|
||||||
// TODO: Quit checking contents in ExpandableBinaryDictionary.
|
if (!mDictFile.exists() || mNeedsToRecreate) {
|
||||||
if (!mDictFile.exists() || (mNeedsToReload && haveContentsChanged())) {
|
|
||||||
// If the dictionary file does not exist or contents have been updated,
|
// If the dictionary file does not exist or contents have been updated,
|
||||||
// generate a new one.
|
// generate a new one.
|
||||||
createNewDictionaryLocked();
|
createNewDictionaryLocked();
|
||||||
|
@ -536,12 +528,12 @@ abstract public class ExpandableBinaryDictionary extends Dictionary {
|
||||||
&& matchesExpectedBinaryDictFormatVersionForThisType(
|
&& matchesExpectedBinaryDictFormatVersionForThisType(
|
||||||
mBinaryDictionary.getFormatVersion()))) {
|
mBinaryDictionary.getFormatVersion()))) {
|
||||||
// Binary dictionary or its format version is not valid. Regenerate
|
// 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.
|
// existing files if appropriate.
|
||||||
createNewDictionaryLocked();
|
createNewDictionaryLocked();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
mNeedsToReload = false;
|
mNeedsToRecreate = false;
|
||||||
} finally {
|
} finally {
|
||||||
mIsReloading.set(false);
|
mIsReloading.set(false);
|
||||||
}
|
}
|
||||||
|
|
|
@ -98,7 +98,7 @@ public class UserBinaryDictionary extends ExpandableBinaryDictionary {
|
||||||
// devices. On older versions of the platform, the hook above will be called instead.
|
// devices. On older versions of the platform, the hook above will be called instead.
|
||||||
@Override
|
@Override
|
||||||
public void onChange(final boolean self, final Uri uri) {
|
public void onChange(final boolean self, final Uri uri) {
|
||||||
setNeedsToReload();
|
setNeedsToRecreate();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
cres.registerContentObserver(Words.CONTENT_URI, true, mObserver);
|
cres.registerContentObserver(Words.CONTENT_URI, true, mObserver);
|
||||||
|
@ -272,9 +272,4 @@ public class UserBinaryDictionary extends ExpandableBinaryDictionary {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
protected boolean haveContentsChanged() {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -73,11 +73,6 @@ public abstract class DecayingExpandableBinaryDictionaryBase extends ExpandableB
|
||||||
return attributeMap;
|
return attributeMap;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
protected boolean haveContentsChanged() {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void loadInitialContentsLocked() {
|
protected void loadInitialContentsLocked() {
|
||||||
// No initial contents.
|
// No initial contents.
|
||||||
|
|
Loading…
Reference in New Issue