Merge "Remove DictionaryUpdateController."
This commit is contained in:
commit
5c1416e426
3 changed files with 21 additions and 107 deletions
|
@ -89,8 +89,8 @@ public class ContactsBinaryDictionary extends ExpandableBinaryDictionary {
|
||||||
registerObserver(context);
|
registerObserver(context);
|
||||||
|
|
||||||
// Load the current binary dictionary from internal storage. If no binary dictionary exists,
|
// Load the current binary dictionary from internal storage. If no binary dictionary exists,
|
||||||
// loadDictionary will start a new thread to generate one asynchronously.
|
// reloadDictionaryIfRequired will start a new thread to generate one asynchronously.
|
||||||
loadDictionary();
|
reloadDictionaryIfRequired();
|
||||||
}
|
}
|
||||||
|
|
||||||
private synchronized void registerObserver(final Context context) {
|
private synchronized void registerObserver(final Context context) {
|
||||||
|
@ -100,7 +100,7 @@ public class ContactsBinaryDictionary extends ExpandableBinaryDictionary {
|
||||||
new ContentObserver(null) {
|
new ContentObserver(null) {
|
||||||
@Override
|
@Override
|
||||||
public void onChange(boolean self) {
|
public void onChange(boolean self) {
|
||||||
setRequiresReload(true);
|
setNeedsToReload();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
@ -27,7 +27,6 @@ import com.android.inputmethod.latin.makedict.UnsupportedFormatException;
|
||||||
import com.android.inputmethod.latin.makedict.WordProperty;
|
import com.android.inputmethod.latin.makedict.WordProperty;
|
||||||
import com.android.inputmethod.latin.SuggestedWords.SuggestedWordInfo;
|
import com.android.inputmethod.latin.SuggestedWords.SuggestedWordInfo;
|
||||||
import com.android.inputmethod.latin.utils.AsyncResultHolder;
|
import com.android.inputmethod.latin.utils.AsyncResultHolder;
|
||||||
import com.android.inputmethod.latin.utils.CollectionUtils;
|
|
||||||
import com.android.inputmethod.latin.utils.CombinedFormatUtils;
|
import com.android.inputmethod.latin.utils.CombinedFormatUtils;
|
||||||
import com.android.inputmethod.latin.utils.ExecutorUtils;
|
import com.android.inputmethod.latin.utils.ExecutorUtils;
|
||||||
import com.android.inputmethod.latin.utils.FileUtils;
|
import com.android.inputmethod.latin.utils.FileUtils;
|
||||||
|
@ -38,7 +37,6 @@ import java.util.ArrayList;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.Locale;
|
import java.util.Locale;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.concurrent.ConcurrentHashMap;
|
|
||||||
import java.util.concurrent.CountDownLatch;
|
import java.util.concurrent.CountDownLatch;
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
import java.util.concurrent.atomic.AtomicBoolean;
|
import java.util.concurrent.atomic.AtomicBoolean;
|
||||||
|
@ -74,15 +72,6 @@ abstract public class ExpandableBinaryDictionary extends Dictionary {
|
||||||
|
|
||||||
private static final int DICTIONARY_FORMAT_VERSION = FormatSpec.VERSION4;
|
private static final int DICTIONARY_FORMAT_VERSION = FormatSpec.VERSION4;
|
||||||
|
|
||||||
/**
|
|
||||||
* A static map of update controllers, each of which records the time of accesses to a single
|
|
||||||
* binary dictionary file and tracks whether the file is regenerating. The key for this map is
|
|
||||||
* the dictionary name and the value is the shared dictionary time recorder associated with
|
|
||||||
* that dictionary name.
|
|
||||||
*/
|
|
||||||
private static final ConcurrentHashMap<String, DictionaryUpdateController>
|
|
||||||
sDictNameDictionaryUpdateControllerMap = CollectionUtils.newConcurrentHashMap();
|
|
||||||
|
|
||||||
/** The application context. */
|
/** The application context. */
|
||||||
protected final Context mContext;
|
protected final Context mContext;
|
||||||
|
|
||||||
|
@ -105,14 +94,9 @@ abstract public class ExpandableBinaryDictionary extends Dictionary {
|
||||||
/** Dictionary file */
|
/** Dictionary file */
|
||||||
private final File mDictFile;
|
private final File mDictFile;
|
||||||
|
|
||||||
// TODO: remove, once dynamic operations is serialized
|
private final AtomicBoolean mProcessingLargeTask;
|
||||||
/** Controls updating the shared binary dictionary file across multiple instances. */
|
private boolean mNeedsToReload;
|
||||||
private final DictionaryUpdateController mDictNameDictionaryUpdateController;
|
|
||||||
|
|
||||||
// TODO: remove, once dynamic operations is serialized
|
|
||||||
/** Controls updating the local binary dictionary for this instance. */
|
|
||||||
private final DictionaryUpdateController mPerInstanceDictionaryUpdateController =
|
|
||||||
new DictionaryUpdateController();
|
|
||||||
|
|
||||||
/* A extension for a binary dictionary file. */
|
/* A extension for a binary dictionary file. */
|
||||||
protected static final String DICT_FILE_EXTENSION = ".dict";
|
protected static final String DICT_FILE_EXTENSION = ".dict";
|
||||||
|
@ -145,21 +129,6 @@ abstract public class ExpandableBinaryDictionary extends Dictionary {
|
||||||
return mBinaryDictionary.isValidDictionary();
|
return mBinaryDictionary.isValidDictionary();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets the dictionary update controller for the given dictionary name.
|
|
||||||
*/
|
|
||||||
private static DictionaryUpdateController getDictionaryUpdateController(
|
|
||||||
final String dictName) {
|
|
||||||
DictionaryUpdateController recorder = sDictNameDictionaryUpdateControllerMap.get(dictName);
|
|
||||||
if (recorder == null) {
|
|
||||||
synchronized(sDictNameDictionaryUpdateControllerMap) {
|
|
||||||
recorder = new DictionaryUpdateController();
|
|
||||||
sDictNameDictionaryUpdateControllerMap.put(dictName, recorder);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return recorder;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a new expandable binary dictionary.
|
* Creates a new expandable binary dictionary.
|
||||||
*
|
*
|
||||||
|
@ -179,7 +148,8 @@ abstract public class ExpandableBinaryDictionary extends Dictionary {
|
||||||
mLocale = locale;
|
mLocale = locale;
|
||||||
mDictFile = getDictFile(context, dictName, dictFile);
|
mDictFile = getDictFile(context, dictName, dictFile);
|
||||||
mBinaryDictionary = null;
|
mBinaryDictionary = null;
|
||||||
mDictNameDictionaryUpdateController = getDictionaryUpdateController(dictName);
|
mProcessingLargeTask = new AtomicBoolean();
|
||||||
|
mNeedsToReload = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static File getDictFile(final Context context, final String dictName,
|
public static File getDictFile(final Context context, final String dictName,
|
||||||
|
@ -286,7 +256,7 @@ abstract public class ExpandableBinaryDictionary extends Dictionary {
|
||||||
try {
|
try {
|
||||||
mBinaryDictionary.flushWithGC();
|
mBinaryDictionary.flushWithGC();
|
||||||
} finally {
|
} finally {
|
||||||
mDictNameDictionaryUpdateController.mProcessingLargeTask.set(false);
|
mProcessingLargeTask.set(false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -388,7 +358,7 @@ abstract public class ExpandableBinaryDictionary extends Dictionary {
|
||||||
callback.onFinished();
|
callback.onFinished();
|
||||||
}
|
}
|
||||||
if (locked) {
|
if (locked) {
|
||||||
mDictNameDictionaryUpdateController.mProcessingLargeTask.set(false);
|
mProcessingLargeTask.set(false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -461,25 +431,11 @@ abstract public class ExpandableBinaryDictionary extends Dictionary {
|
||||||
return mBinaryDictionary.isValidBigram(word1, word2);
|
return mBinaryDictionary.isValidBigram(word1, word2);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Load the current binary dictionary from internal storage in a background thread. If no binary
|
|
||||||
* dictionary exists, this method will generate one.
|
|
||||||
*/
|
|
||||||
protected void loadDictionary() {
|
|
||||||
mPerInstanceDictionaryUpdateController.mLastUpdateRequestTime = System.currentTimeMillis();
|
|
||||||
reloadDictionaryIfRequired();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Loads the current binary dictionary from internal storage. Assumes the dictionary file
|
* Loads the current binary dictionary from internal storage. Assumes the dictionary file
|
||||||
* exists.
|
* exists.
|
||||||
*/
|
*/
|
||||||
private void loadBinaryDictionaryLocked() {
|
private void loadBinaryDictionaryLocked() {
|
||||||
if (DEBUG) {
|
|
||||||
Log.d(TAG, "Loading binary dictionary: " + mDictName + " request="
|
|
||||||
+ mDictNameDictionaryUpdateController.mLastUpdateRequestTime + " update="
|
|
||||||
+ mDictNameDictionaryUpdateController.mLastUpdateTime);
|
|
||||||
}
|
|
||||||
if (DBG_STRESS_TEST) {
|
if (DBG_STRESS_TEST) {
|
||||||
// Test if this class does not cause problems when it takes long time to load binary
|
// Test if this class does not cause problems when it takes long time to load binary
|
||||||
// dictionary.
|
// dictionary.
|
||||||
|
@ -505,11 +461,6 @@ abstract public class ExpandableBinaryDictionary extends Dictionary {
|
||||||
* Create a new binary dictionary and load initial contents.
|
* Create a new binary dictionary and load initial contents.
|
||||||
*/
|
*/
|
||||||
private void createNewDictionaryLocked() {
|
private void createNewDictionaryLocked() {
|
||||||
if (DEBUG) {
|
|
||||||
Log.d(TAG, "Generating binary dictionary: " + mDictName + " request="
|
|
||||||
+ mDictNameDictionaryUpdateController.mLastUpdateRequestTime + " update="
|
|
||||||
+ mDictNameDictionaryUpdateController.mLastUpdateTime);
|
|
||||||
}
|
|
||||||
removeBinaryDictionaryLocked();
|
removeBinaryDictionaryLocked();
|
||||||
createOnMemoryBinaryDictionaryLocked();
|
createOnMemoryBinaryDictionaryLocked();
|
||||||
loadInitialContentsLocked();
|
loadInitialContentsLocked();
|
||||||
|
@ -529,20 +480,11 @@ abstract public class ExpandableBinaryDictionary extends Dictionary {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Marks that the dictionary is out of date and requires a reload.
|
* Marks that the dictionary needs to be reloaded.
|
||||||
*
|
*
|
||||||
* @param requiresRebuild Indicates that the source dictionary content has changed and a rebuild
|
|
||||||
* of the binary file is required. If not true, the next reload process will only read
|
|
||||||
* the current binary dictionary from file.
|
|
||||||
*/
|
*/
|
||||||
protected void setRequiresReload(final boolean requiresRebuild) {
|
protected void setNeedsToReload() {
|
||||||
final long time = System.currentTimeMillis();
|
mNeedsToReload = true;
|
||||||
mPerInstanceDictionaryUpdateController.mLastUpdateRequestTime = time;
|
|
||||||
mDictNameDictionaryUpdateController.mLastUpdateRequestTime = time;
|
|
||||||
if (DEBUG) {
|
|
||||||
Log.d(TAG, "Reload request: " + mDictName + ": request=" + time + " update="
|
|
||||||
+ mDictNameDictionaryUpdateController.mLastUpdateTime);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -559,18 +501,17 @@ 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 || mPerInstanceDictionaryUpdateController.isOutOfDate();
|
return mBinaryDictionary == null || mNeedsToReload;
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean processingLargeTask() {
|
private boolean processingLargeTask() {
|
||||||
return mDictNameDictionaryUpdateController.mProcessingLargeTask.get();
|
return mProcessingLargeTask.get();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Returns whether the dictionary is being used for a large task. If true, we should not use
|
// Returns whether the dictionary is being used for a large task. If true, we should not use
|
||||||
// this dictionary for latency sensitive operations.
|
// this dictionary for latency sensitive operations.
|
||||||
private boolean setProcessingLargeTaskIfNot() {
|
private boolean setProcessingLargeTaskIfNot() {
|
||||||
return mDictNameDictionaryUpdateController.mProcessingLargeTask.compareAndSet(
|
return mProcessingLargeTask.compareAndSet(false /* expect */ , true /* update */);
|
||||||
false /* expect */ , true /* update */);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -584,28 +525,17 @@ abstract public class ExpandableBinaryDictionary extends Dictionary {
|
||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
try {
|
try {
|
||||||
final long time = System.currentTimeMillis();
|
if (!dictionaryFileExists() || haveContentsChanged()) {
|
||||||
final boolean openedDictIsOutOfDate =
|
|
||||||
mDictNameDictionaryUpdateController.isOutOfDate();
|
|
||||||
if (!dictionaryFileExists()
|
|
||||||
|| (openedDictIsOutOfDate && haveContentsChanged())) {
|
|
||||||
// If the shared dictionary file does not exist or is out of date and
|
// If the shared dictionary file does not exist or is out of date and
|
||||||
// contents have been updated, the first instance that acquires the lock
|
// contents have been updated, the first instance that acquires the lock
|
||||||
// will generate a new one
|
// will generate a new one
|
||||||
mDictNameDictionaryUpdateController.mLastUpdateTime = time;
|
|
||||||
createNewDictionaryLocked();
|
createNewDictionaryLocked();
|
||||||
} else if (openedDictIsOutOfDate) {
|
} else if (mBinaryDictionary == null) {
|
||||||
// If not, the reload request was unnecessary so revert
|
|
||||||
// LastUpdateRequestTime to LastUpdateTime.
|
|
||||||
mDictNameDictionaryUpdateController.mLastUpdateRequestTime =
|
|
||||||
mDictNameDictionaryUpdateController.mLastUpdateTime;
|
|
||||||
} else if (mBinaryDictionary == null ||
|
|
||||||
mPerInstanceDictionaryUpdateController.mLastUpdateTime
|
|
||||||
< mDictNameDictionaryUpdateController.mLastUpdateTime) {
|
|
||||||
// Otherwise, if the local dictionary is older than the shared dictionary,
|
// Otherwise, if the local dictionary is older than the shared dictionary,
|
||||||
// load the shared dictionary.
|
// load the shared dictionary.
|
||||||
loadBinaryDictionaryLocked();
|
loadBinaryDictionaryLocked();
|
||||||
}
|
}
|
||||||
|
mNeedsToReload = false;
|
||||||
if (mBinaryDictionary != null && !(isValidDictionaryLocked()
|
if (mBinaryDictionary != null && !(isValidDictionaryLocked()
|
||||||
// TODO: remove the check below
|
// TODO: remove the check below
|
||||||
&& matchesExpectedBinaryDictFormatVersionForThisType(
|
&& matchesExpectedBinaryDictFormatVersionForThisType(
|
||||||
|
@ -613,12 +543,10 @@ abstract public class ExpandableBinaryDictionary extends Dictionary {
|
||||||
// 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. writeBinaryDictionary will remove the
|
||||||
// existing files if appropriate.
|
// existing files if appropriate.
|
||||||
mDictNameDictionaryUpdateController.mLastUpdateTime = time;
|
|
||||||
createNewDictionaryLocked();
|
createNewDictionaryLocked();
|
||||||
}
|
}
|
||||||
mPerInstanceDictionaryUpdateController.mLastUpdateTime = time;
|
|
||||||
} finally {
|
} finally {
|
||||||
mDictNameDictionaryUpdateController.mProcessingLargeTask.set(false);
|
mProcessingLargeTask.set(false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -643,20 +571,6 @@ abstract public class ExpandableBinaryDictionary extends Dictionary {
|
||||||
ExecutorUtils.getExecutor(mDictName).replaceAndExecute(oldTask, newTask);
|
ExecutorUtils.getExecutor(mDictName).replaceAndExecute(oldTask, newTask);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* For tracking whether the dictionary is out of date and the dictionary is used in a large
|
|
||||||
* task. Can be shared across multiple dictionary instances that access the same filename.
|
|
||||||
*/
|
|
||||||
private static class DictionaryUpdateController {
|
|
||||||
public volatile long mLastUpdateTime = 0;
|
|
||||||
public volatile long mLastUpdateRequestTime = 0;
|
|
||||||
public volatile AtomicBoolean mProcessingLargeTask = new AtomicBoolean();
|
|
||||||
|
|
||||||
public boolean isOutOfDate() {
|
|
||||||
return (mLastUpdateRequestTime > mLastUpdateTime);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO: Implement BinaryDictionary.isInDictionary().
|
// TODO: Implement BinaryDictionary.isInDictionary().
|
||||||
@UsedForTesting
|
@UsedForTesting
|
||||||
public boolean isInUnderlyingBinaryDictionaryForTests(final String word) {
|
public boolean isInUnderlyingBinaryDictionaryForTests(final String word) {
|
||||||
|
|
|
@ -116,12 +116,12 @@ 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) {
|
||||||
setRequiresReload(true);
|
setNeedsToReload();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
cres.registerContentObserver(Words.CONTENT_URI, true, mObserver);
|
cres.registerContentObserver(Words.CONTENT_URI, true, mObserver);
|
||||||
mEnabled = readIsEnabled();
|
mEnabled = readIsEnabled();
|
||||||
loadDictionary();
|
reloadDictionaryIfRequired();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
Loading…
Reference in a new issue