Merge "Create ver4 dictionary files with the dictionary name."
This commit is contained in:
commit
549ae3d84e
22 changed files with 180 additions and 152 deletions
|
@ -72,7 +72,7 @@ public class ContactsBinaryDictionary extends ExpandableBinaryDictionary {
|
||||||
private final boolean mUseFirstLastBigrams;
|
private final boolean mUseFirstLastBigrams;
|
||||||
|
|
||||||
public ContactsBinaryDictionary(final Context context, final Locale locale) {
|
public ContactsBinaryDictionary(final Context context, final Locale locale) {
|
||||||
super(context, getFilenameWithLocale(NAME, locale), locale,
|
super(context, getDictNameWithLocale(NAME, locale), locale,
|
||||||
Dictionary.TYPE_CONTACTS, false /* isUpdatable */);
|
Dictionary.TYPE_CONTACTS, false /* isUpdatable */);
|
||||||
mLocale = locale;
|
mLocale = locale;
|
||||||
mUseFirstLastBigrams = useFirstLastBigramsForLocale(locale);
|
mUseFirstLastBigrams = useFirstLastBigramsForLocale(locale);
|
||||||
|
|
|
@ -69,14 +69,14 @@ abstract public class ExpandableBinaryDictionary extends Dictionary {
|
||||||
/**
|
/**
|
||||||
* A static map of update controllers, each of which records the time of accesses to a single
|
* 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
|
* binary dictionary file and tracks whether the file is regenerating. The key for this map is
|
||||||
* the filename and the value is the shared dictionary time recorder associated with that
|
* the dictionary name and the value is the shared dictionary time recorder associated with
|
||||||
* filename.
|
* that dictionary name.
|
||||||
*/
|
*/
|
||||||
private static final ConcurrentHashMap<String, DictionaryUpdateController>
|
private static final ConcurrentHashMap<String, DictionaryUpdateController>
|
||||||
sFilenameDictionaryUpdateControllerMap = CollectionUtils.newConcurrentHashMap();
|
sDictNameDictionaryUpdateControllerMap = CollectionUtils.newConcurrentHashMap();
|
||||||
|
|
||||||
private static final ConcurrentHashMap<String, PrioritizedSerialExecutor>
|
private static final ConcurrentHashMap<String, PrioritizedSerialExecutor>
|
||||||
sFilenameExecutorMap = CollectionUtils.newConcurrentHashMap();
|
sDictNameExecutorMap = CollectionUtils.newConcurrentHashMap();
|
||||||
|
|
||||||
/** The application context. */
|
/** The application context. */
|
||||||
protected final Context mContext;
|
protected final Context mContext;
|
||||||
|
@ -92,11 +92,11 @@ abstract public class ExpandableBinaryDictionary extends Dictionary {
|
||||||
protected AbstractDictionaryWriter mDictionaryWriter;
|
protected AbstractDictionaryWriter mDictionaryWriter;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The name of this dictionary, used as the filename for storing the binary dictionary. Multiple
|
* The name of this dictionary, used as a part of the filename for storing the binary
|
||||||
* dictionary instances with the same filename is supported, with access controlled by
|
* dictionary. Multiple dictionary instances with the same name is supported, with access
|
||||||
* DictionaryTimeRecorder.
|
* controlled by DictionaryUpdateController.
|
||||||
*/
|
*/
|
||||||
private final String mFilename;
|
private final String mDictName;
|
||||||
|
|
||||||
/** Dictionary locale */
|
/** Dictionary locale */
|
||||||
private final Locale mLocale;
|
private final Locale mLocale;
|
||||||
|
@ -106,7 +106,7 @@ abstract public class ExpandableBinaryDictionary extends Dictionary {
|
||||||
|
|
||||||
// TODO: remove, once dynamic operations is serialized
|
// TODO: remove, once dynamic operations is serialized
|
||||||
/** Controls updating the shared binary dictionary file across multiple instances. */
|
/** Controls updating the shared binary dictionary file across multiple instances. */
|
||||||
private final DictionaryUpdateController mFilenameDictionaryUpdateController;
|
private final DictionaryUpdateController mDictNameDictionaryUpdateController;
|
||||||
|
|
||||||
// TODO: remove, once dynamic operations is serialized
|
// TODO: remove, once dynamic operations is serialized
|
||||||
/** Controls updating the local binary dictionary for this instance. */
|
/** Controls updating the local binary dictionary for this instance. */
|
||||||
|
@ -144,34 +144,46 @@ abstract public class ExpandableBinaryDictionary extends Dictionary {
|
||||||
return mBinaryDictionary.isValidDictionary();
|
return mBinaryDictionary.isValidDictionary();
|
||||||
}
|
}
|
||||||
|
|
||||||
protected String getFileNameExtensionToOpenDict() {
|
protected String getFileNameToCreateDict(final String dictName) {
|
||||||
return "";
|
return dictName + DICT_FILE_EXTENSION;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected String getFileNameToOpenDict(final String dictName) {
|
||||||
|
return getFileNameToCreateDict(dictName);
|
||||||
|
}
|
||||||
|
|
||||||
|
private File getFileToCreateDict() {
|
||||||
|
return new File(mContext.getFilesDir(), getFileNameToCreateDict(mDictName));
|
||||||
|
}
|
||||||
|
|
||||||
|
private File getFileToOpenDict() {
|
||||||
|
return new File(mContext.getFilesDir(), getFileNameToOpenDict(mDictName));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the dictionary update controller for the given filename.
|
* Gets the dictionary update controller for the given dictionary name.
|
||||||
*/
|
*/
|
||||||
private static DictionaryUpdateController getDictionaryUpdateController(
|
private static DictionaryUpdateController getDictionaryUpdateController(
|
||||||
String filename) {
|
final String dictName) {
|
||||||
DictionaryUpdateController recorder = sFilenameDictionaryUpdateControllerMap.get(filename);
|
DictionaryUpdateController recorder = sDictNameDictionaryUpdateControllerMap.get(dictName);
|
||||||
if (recorder == null) {
|
if (recorder == null) {
|
||||||
synchronized(sFilenameDictionaryUpdateControllerMap) {
|
synchronized(sDictNameDictionaryUpdateControllerMap) {
|
||||||
recorder = new DictionaryUpdateController();
|
recorder = new DictionaryUpdateController();
|
||||||
sFilenameDictionaryUpdateControllerMap.put(filename, recorder);
|
sDictNameDictionaryUpdateControllerMap.put(dictName, recorder);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return recorder;
|
return recorder;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the executor for the given filename.
|
* Gets the executor for the given dictionary name.
|
||||||
*/
|
*/
|
||||||
private static PrioritizedSerialExecutor getExecutor(final String filename) {
|
private static PrioritizedSerialExecutor getExecutor(final String dictName) {
|
||||||
PrioritizedSerialExecutor executor = sFilenameExecutorMap.get(filename);
|
PrioritizedSerialExecutor executor = sDictNameExecutorMap.get(dictName);
|
||||||
if (executor == null) {
|
if (executor == null) {
|
||||||
synchronized(sFilenameExecutorMap) {
|
synchronized(sDictNameExecutorMap) {
|
||||||
executor = new PrioritizedSerialExecutor();
|
executor = new PrioritizedSerialExecutor();
|
||||||
sFilenameExecutorMap.put(filename, executor);
|
sDictNameExecutorMap.put(dictName, executor);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return executor;
|
return executor;
|
||||||
|
@ -190,28 +202,28 @@ abstract public class ExpandableBinaryDictionary extends Dictionary {
|
||||||
* Creates a new expandable binary dictionary.
|
* Creates a new expandable binary dictionary.
|
||||||
*
|
*
|
||||||
* @param context The application context of the parent.
|
* @param context The application context of the parent.
|
||||||
* @param filename The filename for this binary dictionary. Multiple dictionaries with the same
|
* @param dictName The name of the dictionary. Multiple instances with the same
|
||||||
* filename is supported.
|
* name is supported.
|
||||||
* @param locale the dictionary locale.
|
* @param locale the dictionary locale.
|
||||||
* @param dictType the dictionary type, as a human-readable string
|
* @param dictType the dictionary type, as a human-readable string
|
||||||
* @param isUpdatable whether to support dynamically updating the dictionary. Please note that
|
* @param isUpdatable whether to support dynamically updating the dictionary. Please note that
|
||||||
* dynamic dictionary has negative effects on memory space and computation time.
|
* dynamic dictionary has negative effects on memory space and computation time.
|
||||||
*/
|
*/
|
||||||
public ExpandableBinaryDictionary(final Context context, final String filename,
|
public ExpandableBinaryDictionary(final Context context, final String dictName,
|
||||||
final Locale locale, final String dictType, final boolean isUpdatable) {
|
final Locale locale, final String dictType, final boolean isUpdatable) {
|
||||||
super(dictType);
|
super(dictType);
|
||||||
mFilename = filename;
|
mDictName = dictName;
|
||||||
mContext = context;
|
mContext = context;
|
||||||
mLocale = locale;
|
mLocale = locale;
|
||||||
mIsUpdatable = isUpdatable;
|
mIsUpdatable = isUpdatable;
|
||||||
mBinaryDictionary = null;
|
mBinaryDictionary = null;
|
||||||
mFilenameDictionaryUpdateController = getDictionaryUpdateController(filename);
|
mDictNameDictionaryUpdateController = getDictionaryUpdateController(dictName);
|
||||||
// Currently, only dynamic personalization dictionary is updatable.
|
// Currently, only dynamic personalization dictionary is updatable.
|
||||||
mDictionaryWriter = getDictionaryWriter(context, isUpdatable);
|
mDictionaryWriter = getDictionaryWriter(context, isUpdatable);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected static String getFilenameWithLocale(final String name, final Locale locale) {
|
protected static String getDictNameWithLocale(final String name, final Locale locale) {
|
||||||
return name + "." + locale.toString() + DICT_FILE_EXTENSION;
|
return name + "." + locale.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -219,7 +231,7 @@ abstract public class ExpandableBinaryDictionary extends Dictionary {
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public void close() {
|
public void close() {
|
||||||
getExecutor(mFilename).execute(new Runnable() {
|
getExecutor(mDictName).execute(new Runnable() {
|
||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
if (mBinaryDictionary!= null) {
|
if (mBinaryDictionary!= null) {
|
||||||
|
@ -232,7 +244,7 @@ abstract public class ExpandableBinaryDictionary extends Dictionary {
|
||||||
|
|
||||||
protected void closeBinaryDictionary() {
|
protected void closeBinaryDictionary() {
|
||||||
// Ensure that no other threads are accessing the local binary dictionary.
|
// Ensure that no other threads are accessing the local binary dictionary.
|
||||||
getExecutor(mFilename).execute(new Runnable() {
|
getExecutor(mDictName).execute(new Runnable() {
|
||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
if (mBinaryDictionary != null) {
|
if (mBinaryDictionary != null) {
|
||||||
|
@ -245,7 +257,7 @@ abstract public class ExpandableBinaryDictionary extends Dictionary {
|
||||||
|
|
||||||
protected Map<String, String> getHeaderAttributeMap() {
|
protected Map<String, String> getHeaderAttributeMap() {
|
||||||
HashMap<String, String> attributeMap = new HashMap<String, String>();
|
HashMap<String, String> attributeMap = new HashMap<String, String>();
|
||||||
attributeMap.put(FormatSpec.FileHeader.DICTIONARY_ID_ATTRIBUTE, mFilename);
|
attributeMap.put(FormatSpec.FileHeader.DICTIONARY_ID_ATTRIBUTE, mDictName);
|
||||||
attributeMap.put(FormatSpec.FileHeader.DICTIONARY_LOCALE_ATTRIBUTE, mLocale.toString());
|
attributeMap.put(FormatSpec.FileHeader.DICTIONARY_LOCALE_ATTRIBUTE, mLocale.toString());
|
||||||
attributeMap.put(FormatSpec.FileHeader.DICTIONARY_VERSION_ATTRIBUTE,
|
attributeMap.put(FormatSpec.FileHeader.DICTIONARY_VERSION_ATTRIBUTE,
|
||||||
String.valueOf(TimeUnit.MILLISECONDS.toSeconds(System.currentTimeMillis())));
|
String.valueOf(TimeUnit.MILLISECONDS.toSeconds(System.currentTimeMillis())));
|
||||||
|
@ -253,19 +265,18 @@ abstract public class ExpandableBinaryDictionary extends Dictionary {
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void clear() {
|
protected void clear() {
|
||||||
getExecutor(mFilename).execute(new Runnable() {
|
getExecutor(mDictName).execute(new Runnable() {
|
||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
if (mDictionaryWriter == null) {
|
if (mDictionaryWriter == null) {
|
||||||
mBinaryDictionary.close();
|
mBinaryDictionary.close();
|
||||||
final File file = new File(mContext.getFilesDir(), mFilename);
|
final File file = getFileToCreateDict();
|
||||||
file.delete();
|
file.delete();
|
||||||
BinaryDictionary.createEmptyDictFile(file.getAbsolutePath(),
|
BinaryDictionary.createEmptyDictFile(file.getAbsolutePath(),
|
||||||
DICTIONARY_FORMAT_VERSION, getHeaderAttributeMap());
|
DICTIONARY_FORMAT_VERSION, getHeaderAttributeMap());
|
||||||
// We have 'fileToOpen' in addition to 'file' for the v4 dictionary format
|
// We have 'fileToOpen' in addition to 'file' for the v4 dictionary format
|
||||||
// where 'file' is a directory, and 'fileToOpen' is a normal file.
|
// where 'file' is a directory, and 'fileToOpen' is a normal file.
|
||||||
final File fileToOpen = new File(mContext.getFilesDir(), mFilename
|
final File fileToOpen = getFileToOpenDict();
|
||||||
+ getFileNameExtensionToOpenDict());
|
|
||||||
// TODO: Make BinaryDictionary's constructor be able to accept filename
|
// TODO: Make BinaryDictionary's constructor be able to accept filename
|
||||||
// without extension.
|
// without extension.
|
||||||
mBinaryDictionary = new BinaryDictionary(
|
mBinaryDictionary = new BinaryDictionary(
|
||||||
|
@ -305,7 +316,7 @@ abstract public class ExpandableBinaryDictionary extends Dictionary {
|
||||||
* Check whether GC is needed and run GC if required.
|
* Check whether GC is needed and run GC if required.
|
||||||
*/
|
*/
|
||||||
protected void runGCIfRequired(final boolean mindsBlockByGC) {
|
protected void runGCIfRequired(final boolean mindsBlockByGC) {
|
||||||
getExecutor(mFilename).execute(new Runnable() {
|
getExecutor(mDictName).execute(new Runnable() {
|
||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
runGCIfRequiredInternalLocked(mindsBlockByGC);
|
runGCIfRequiredInternalLocked(mindsBlockByGC);
|
||||||
|
@ -318,13 +329,13 @@ abstract public class ExpandableBinaryDictionary extends Dictionary {
|
||||||
if (mBinaryDictionary.needsToRunGC(mindsBlockByGC)) {
|
if (mBinaryDictionary.needsToRunGC(mindsBlockByGC)) {
|
||||||
if (setProcessingLargeTaskIfNot()) {
|
if (setProcessingLargeTaskIfNot()) {
|
||||||
// Run GC after currently existing time sensitive operations.
|
// Run GC after currently existing time sensitive operations.
|
||||||
getExecutor(mFilename).executePrioritized(new Runnable() {
|
getExecutor(mDictName).executePrioritized(new Runnable() {
|
||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
try {
|
try {
|
||||||
mBinaryDictionary.flushWithGC();
|
mBinaryDictionary.flushWithGC();
|
||||||
} finally {
|
} finally {
|
||||||
mFilenameDictionaryUpdateController.mProcessingLargeTask.set(false);
|
mDictNameDictionaryUpdateController.mProcessingLargeTask.set(false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -339,10 +350,10 @@ abstract public class ExpandableBinaryDictionary extends Dictionary {
|
||||||
final String shortcutTarget, final int shortcutFreq, final boolean isNotAWord,
|
final String shortcutTarget, final int shortcutFreq, final boolean isNotAWord,
|
||||||
final boolean isBlacklisted, final int timestamp) {
|
final boolean isBlacklisted, final int timestamp) {
|
||||||
if (!mIsUpdatable) {
|
if (!mIsUpdatable) {
|
||||||
Log.w(TAG, "addWordDynamically is called for non-updatable dictionary: " + mFilename);
|
Log.w(TAG, "addWordDynamically is called for non-updatable dictionary: " + mDictName);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
getExecutor(mFilename).execute(new Runnable() {
|
getExecutor(mDictName).execute(new Runnable() {
|
||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
runGCIfRequiredInternalLocked(true /* mindsBlockByGC */);
|
runGCIfRequiredInternalLocked(true /* mindsBlockByGC */);
|
||||||
|
@ -359,10 +370,10 @@ abstract public class ExpandableBinaryDictionary extends Dictionary {
|
||||||
final int frequency, final int timestamp) {
|
final int frequency, final int timestamp) {
|
||||||
if (!mIsUpdatable) {
|
if (!mIsUpdatable) {
|
||||||
Log.w(TAG, "addBigramDynamically is called for non-updatable dictionary: "
|
Log.w(TAG, "addBigramDynamically is called for non-updatable dictionary: "
|
||||||
+ mFilename);
|
+ mDictName);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
getExecutor(mFilename).execute(new Runnable() {
|
getExecutor(mDictName).execute(new Runnable() {
|
||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
runGCIfRequiredInternalLocked(true /* mindsBlockByGC */);
|
runGCIfRequiredInternalLocked(true /* mindsBlockByGC */);
|
||||||
|
@ -377,10 +388,10 @@ abstract public class ExpandableBinaryDictionary extends Dictionary {
|
||||||
protected void removeBigramDynamically(final String word0, final String word1) {
|
protected void removeBigramDynamically(final String word0, final String word1) {
|
||||||
if (!mIsUpdatable) {
|
if (!mIsUpdatable) {
|
||||||
Log.w(TAG, "removeBigramDynamically is called for non-updatable dictionary: "
|
Log.w(TAG, "removeBigramDynamically is called for non-updatable dictionary: "
|
||||||
+ mFilename);
|
+ mDictName);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
getExecutor(mFilename).execute(new Runnable() {
|
getExecutor(mDictName).execute(new Runnable() {
|
||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
runGCIfRequiredInternalLocked(true /* mindsBlockByGC */);
|
runGCIfRequiredInternalLocked(true /* mindsBlockByGC */);
|
||||||
|
@ -401,10 +412,10 @@ abstract public class ExpandableBinaryDictionary extends Dictionary {
|
||||||
final AddMultipleDictionaryEntriesCallback callback) {
|
final AddMultipleDictionaryEntriesCallback callback) {
|
||||||
if (!mIsUpdatable) {
|
if (!mIsUpdatable) {
|
||||||
Log.w(TAG, "addMultipleDictionaryEntriesDynamically is called for non-updatable " +
|
Log.w(TAG, "addMultipleDictionaryEntriesDynamically is called for non-updatable " +
|
||||||
"dictionary: " + mFilename);
|
"dictionary: " + mDictName);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
getExecutor(mFilename).execute(new Runnable() {
|
getExecutor(mDictName).execute(new Runnable() {
|
||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
final boolean locked = setProcessingLargeTaskIfNot();
|
final boolean locked = setProcessingLargeTaskIfNot();
|
||||||
|
@ -417,7 +428,7 @@ abstract public class ExpandableBinaryDictionary extends Dictionary {
|
||||||
callback.onFinished();
|
callback.onFinished();
|
||||||
}
|
}
|
||||||
if (locked) {
|
if (locked) {
|
||||||
mFilenameDictionaryUpdateController.mProcessingLargeTask.set(false);
|
mDictNameDictionaryUpdateController.mProcessingLargeTask.set(false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -435,7 +446,7 @@ abstract public class ExpandableBinaryDictionary extends Dictionary {
|
||||||
}
|
}
|
||||||
final AsyncResultHolder<ArrayList<SuggestedWordInfo>> holder =
|
final AsyncResultHolder<ArrayList<SuggestedWordInfo>> holder =
|
||||||
new AsyncResultHolder<ArrayList<SuggestedWordInfo>>();
|
new AsyncResultHolder<ArrayList<SuggestedWordInfo>>();
|
||||||
getExecutor(mFilename).executePrioritized(new Runnable() {
|
getExecutor(mDictName).executePrioritized(new Runnable() {
|
||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
if (mBinaryDictionary == null) {
|
if (mBinaryDictionary == null) {
|
||||||
|
@ -471,7 +482,7 @@ abstract public class ExpandableBinaryDictionary extends Dictionary {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
final AsyncResultHolder<Boolean> holder = new AsyncResultHolder<Boolean>();
|
final AsyncResultHolder<Boolean> holder = new AsyncResultHolder<Boolean>();
|
||||||
getExecutor(mFilename).executePrioritized(new Runnable() {
|
getExecutor(mDictName).executePrioritized(new Runnable() {
|
||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
holder.set(isValidWordLocked(word));
|
holder.set(isValidWordLocked(word));
|
||||||
|
@ -505,23 +516,22 @@ abstract public class ExpandableBinaryDictionary extends Dictionary {
|
||||||
*/
|
*/
|
||||||
private void loadBinaryDictionary() {
|
private void loadBinaryDictionary() {
|
||||||
if (DEBUG) {
|
if (DEBUG) {
|
||||||
Log.d(TAG, "Loading binary dictionary: " + mFilename + " request="
|
Log.d(TAG, "Loading binary dictionary: " + mDictName + " request="
|
||||||
+ mFilenameDictionaryUpdateController.mLastUpdateRequestTime + " update="
|
+ mDictNameDictionaryUpdateController.mLastUpdateRequestTime + " update="
|
||||||
+ mFilenameDictionaryUpdateController.mLastUpdateTime);
|
+ 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.
|
||||||
try {
|
try {
|
||||||
Log.w(TAG, "Start stress in loading: " + mFilename);
|
Log.w(TAG, "Start stress in loading: " + mDictName);
|
||||||
Thread.sleep(15000);
|
Thread.sleep(15000);
|
||||||
Log.w(TAG, "End stress in loading");
|
Log.w(TAG, "End stress in loading");
|
||||||
} catch (InterruptedException e) {
|
} catch (InterruptedException e) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
final File file = new File(mContext.getFilesDir(), mFilename
|
final File file = getFileToOpenDict();
|
||||||
+ getFileNameExtensionToOpenDict());
|
|
||||||
final String filename = file.getAbsolutePath();
|
final String filename = file.getAbsolutePath();
|
||||||
final long length = file.length();
|
final long length = file.length();
|
||||||
|
|
||||||
|
@ -533,7 +543,7 @@ abstract public class ExpandableBinaryDictionary extends Dictionary {
|
||||||
// swapping in the new one.
|
// swapping in the new one.
|
||||||
// TODO: Ensure multi-thread assignment of mBinaryDictionary.
|
// TODO: Ensure multi-thread assignment of mBinaryDictionary.
|
||||||
final BinaryDictionary oldBinaryDictionary = mBinaryDictionary;
|
final BinaryDictionary oldBinaryDictionary = mBinaryDictionary;
|
||||||
getExecutor(mFilename).executePrioritized(new Runnable() {
|
getExecutor(mDictName).executePrioritized(new Runnable() {
|
||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
mBinaryDictionary = newBinaryDictionary;
|
mBinaryDictionary = newBinaryDictionary;
|
||||||
|
@ -555,20 +565,20 @@ abstract public class ExpandableBinaryDictionary extends Dictionary {
|
||||||
*/
|
*/
|
||||||
private void writeBinaryDictionary() {
|
private void writeBinaryDictionary() {
|
||||||
if (DEBUG) {
|
if (DEBUG) {
|
||||||
Log.d(TAG, "Generating binary dictionary: " + mFilename + " request="
|
Log.d(TAG, "Generating binary dictionary: " + mDictName + " request="
|
||||||
+ mFilenameDictionaryUpdateController.mLastUpdateRequestTime + " update="
|
+ mDictNameDictionaryUpdateController.mLastUpdateRequestTime + " update="
|
||||||
+ mFilenameDictionaryUpdateController.mLastUpdateTime);
|
+ mDictNameDictionaryUpdateController.mLastUpdateTime);
|
||||||
}
|
}
|
||||||
if (needsToReloadBeforeWriting()) {
|
if (needsToReloadBeforeWriting()) {
|
||||||
mDictionaryWriter.clear();
|
mDictionaryWriter.clear();
|
||||||
loadDictionaryAsync();
|
loadDictionaryAsync();
|
||||||
mDictionaryWriter.write(mFilename, getHeaderAttributeMap());
|
mDictionaryWriter.write(getFileNameToCreateDict(mDictName), getHeaderAttributeMap());
|
||||||
} else {
|
} else {
|
||||||
if (mBinaryDictionary == null || !isValidDictionary()
|
if (mBinaryDictionary == null || !isValidDictionary()
|
||||||
// TODO: remove the check below
|
// TODO: remove the check below
|
||||||
|| !matchesExpectedBinaryDictFormatVersionForThisType(
|
|| !matchesExpectedBinaryDictFormatVersionForThisType(
|
||||||
mBinaryDictionary.getFormatVersion())) {
|
mBinaryDictionary.getFormatVersion())) {
|
||||||
final File file = new File(mContext.getFilesDir(), mFilename);
|
final File file = getFileToCreateDict();
|
||||||
if (!FileUtils.deleteRecursively(file)) {
|
if (!FileUtils.deleteRecursively(file)) {
|
||||||
Log.e(TAG, "Can't remove a file: " + file.getName());
|
Log.e(TAG, "Can't remove a file: " + file.getName());
|
||||||
}
|
}
|
||||||
|
@ -594,10 +604,10 @@ abstract public class ExpandableBinaryDictionary extends Dictionary {
|
||||||
protected void setRequiresReload(final boolean requiresRebuild) {
|
protected void setRequiresReload(final boolean requiresRebuild) {
|
||||||
final long time = SystemClock.uptimeMillis();
|
final long time = SystemClock.uptimeMillis();
|
||||||
mPerInstanceDictionaryUpdateController.mLastUpdateRequestTime = time;
|
mPerInstanceDictionaryUpdateController.mLastUpdateRequestTime = time;
|
||||||
mFilenameDictionaryUpdateController.mLastUpdateRequestTime = time;
|
mDictNameDictionaryUpdateController.mLastUpdateRequestTime = time;
|
||||||
if (DEBUG) {
|
if (DEBUG) {
|
||||||
Log.d(TAG, "Reload request: " + mFilename + ": request=" + time + " update="
|
Log.d(TAG, "Reload request: " + mDictName + ": request=" + time + " update="
|
||||||
+ mFilenameDictionaryUpdateController.mLastUpdateTime);
|
+ mDictNameDictionaryUpdateController.mLastUpdateTime);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -619,13 +629,13 @@ abstract public class ExpandableBinaryDictionary extends Dictionary {
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean processingLargeTask() {
|
private boolean processingLargeTask() {
|
||||||
return mFilenameDictionaryUpdateController.mProcessingLargeTask.get();
|
return mDictNameDictionaryUpdateController.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 mFilenameDictionaryUpdateController.mProcessingLargeTask.compareAndSet(
|
return mDictNameDictionaryUpdateController.mProcessingLargeTask.compareAndSet(
|
||||||
false /* expect */ , true /* update */);
|
false /* expect */ , true /* update */);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -636,13 +646,13 @@ abstract public class ExpandableBinaryDictionary extends Dictionary {
|
||||||
private final void reloadDictionary() {
|
private final void reloadDictionary() {
|
||||||
// Ensure that only one thread attempts to read or write to the shared binary dictionary
|
// Ensure that only one thread attempts to read or write to the shared binary dictionary
|
||||||
// file at the same time.
|
// file at the same time.
|
||||||
getExecutor(mFilename).execute(new Runnable() {
|
getExecutor(mDictName).execute(new Runnable() {
|
||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
try {
|
try {
|
||||||
final long time = SystemClock.uptimeMillis();
|
final long time = SystemClock.uptimeMillis();
|
||||||
final boolean dictionaryFileExists = dictionaryFileExists();
|
final boolean dictionaryFileExists = dictionaryFileExists();
|
||||||
if (mFilenameDictionaryUpdateController.isOutOfDate()
|
if (mDictNameDictionaryUpdateController.isOutOfDate()
|
||||||
|| !dictionaryFileExists) {
|
|| !dictionaryFileExists) {
|
||||||
// If the shared dictionary file does not exist or is out of date, the
|
// If the shared dictionary file does not exist or is out of date, the
|
||||||
// first instance that acquires the lock will generate a new one.
|
// first instance that acquires the lock will generate a new one.
|
||||||
|
@ -651,18 +661,18 @@ abstract public class ExpandableBinaryDictionary extends Dictionary {
|
||||||
// rebuild the binary dictionary. Empty dictionaries are supported (in
|
// rebuild the binary dictionary. Empty dictionaries are supported (in
|
||||||
// the case where loadDictionaryAsync() adds nothing) in order to
|
// the case where loadDictionaryAsync() adds nothing) in order to
|
||||||
// provide a uniform framework.
|
// provide a uniform framework.
|
||||||
mFilenameDictionaryUpdateController.mLastUpdateTime = time;
|
mDictNameDictionaryUpdateController.mLastUpdateTime = time;
|
||||||
writeBinaryDictionary();
|
writeBinaryDictionary();
|
||||||
loadBinaryDictionary();
|
loadBinaryDictionary();
|
||||||
} else {
|
} else {
|
||||||
// If not, the reload request was unnecessary so revert
|
// If not, the reload request was unnecessary so revert
|
||||||
// LastUpdateRequestTime to LastUpdateTime.
|
// LastUpdateRequestTime to LastUpdateTime.
|
||||||
mFilenameDictionaryUpdateController.mLastUpdateRequestTime =
|
mDictNameDictionaryUpdateController.mLastUpdateRequestTime =
|
||||||
mFilenameDictionaryUpdateController.mLastUpdateTime;
|
mDictNameDictionaryUpdateController.mLastUpdateTime;
|
||||||
}
|
}
|
||||||
} else if (mBinaryDictionary == null ||
|
} else if (mBinaryDictionary == null ||
|
||||||
mPerInstanceDictionaryUpdateController.mLastUpdateTime
|
mPerInstanceDictionaryUpdateController.mLastUpdateTime
|
||||||
< mFilenameDictionaryUpdateController.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.
|
||||||
loadBinaryDictionary();
|
loadBinaryDictionary();
|
||||||
|
@ -670,7 +680,7 @@ abstract public class ExpandableBinaryDictionary extends Dictionary {
|
||||||
// If we just loaded the binary dictionary, then mBinaryDictionary is not
|
// If we just loaded the binary dictionary, then mBinaryDictionary is not
|
||||||
// up-to-date yet so it's useless to test it right away. Schedule the check
|
// up-to-date yet so it's useless to test it right away. Schedule the check
|
||||||
// for right after it's loaded instead.
|
// for right after it's loaded instead.
|
||||||
getExecutor(mFilename).executePrioritized(new Runnable() {
|
getExecutor(mDictName).executePrioritized(new Runnable() {
|
||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
if (mBinaryDictionary != null && !(isValidDictionary()
|
if (mBinaryDictionary != null && !(isValidDictionary()
|
||||||
|
@ -680,7 +690,7 @@ 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.
|
||||||
mFilenameDictionaryUpdateController.mLastUpdateTime = time;
|
mDictNameDictionaryUpdateController.mLastUpdateTime = time;
|
||||||
writeBinaryDictionary();
|
writeBinaryDictionary();
|
||||||
loadBinaryDictionary();
|
loadBinaryDictionary();
|
||||||
}
|
}
|
||||||
|
@ -688,7 +698,7 @@ abstract public class ExpandableBinaryDictionary extends Dictionary {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
} finally {
|
} finally {
|
||||||
mFilenameDictionaryUpdateController.mProcessingLargeTask.set(false);
|
mDictNameDictionaryUpdateController.mProcessingLargeTask.set(false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -696,7 +706,7 @@ abstract public class ExpandableBinaryDictionary extends Dictionary {
|
||||||
|
|
||||||
// TODO: cache the file's existence so that we avoid doing a disk access each time.
|
// TODO: cache the file's existence so that we avoid doing a disk access each time.
|
||||||
private boolean dictionaryFileExists() {
|
private boolean dictionaryFileExists() {
|
||||||
final File file = new File(mContext.getFilesDir(), mFilename);
|
final File file = getFileToOpenDict();
|
||||||
return file.exists();
|
return file.exists();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -711,7 +721,7 @@ abstract public class ExpandableBinaryDictionary extends Dictionary {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
final Runnable oldTask = mUnfinishedFlushingTask.getAndSet(newTask);
|
final Runnable oldTask = mUnfinishedFlushingTask.getAndSet(newTask);
|
||||||
getExecutor(mFilename).replaceAndExecute(oldTask, newTask);
|
getExecutor(mDictName).replaceAndExecute(oldTask, newTask);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -732,7 +742,7 @@ abstract public class ExpandableBinaryDictionary extends Dictionary {
|
||||||
@UsedForTesting
|
@UsedForTesting
|
||||||
public boolean isInDictionaryForTests(final String word) {
|
public boolean isInDictionaryForTests(final String word) {
|
||||||
final AsyncResultHolder<Boolean> holder = new AsyncResultHolder<Boolean>();
|
final AsyncResultHolder<Boolean> holder = new AsyncResultHolder<Boolean>();
|
||||||
getExecutor(mFilename).executePrioritized(new Runnable() {
|
getExecutor(mDictName).executePrioritized(new Runnable() {
|
||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
if (mDictType == Dictionary.TYPE_USER_HISTORY) {
|
if (mDictType == Dictionary.TYPE_USER_HISTORY) {
|
||||||
|
@ -745,24 +755,24 @@ abstract public class ExpandableBinaryDictionary extends Dictionary {
|
||||||
|
|
||||||
@UsedForTesting
|
@UsedForTesting
|
||||||
public void shutdownExecutorForTests() {
|
public void shutdownExecutorForTests() {
|
||||||
getExecutor(mFilename).shutdown();
|
getExecutor(mDictName).shutdown();
|
||||||
}
|
}
|
||||||
|
|
||||||
@UsedForTesting
|
@UsedForTesting
|
||||||
public boolean isTerminatedForTests() {
|
public boolean isTerminatedForTests() {
|
||||||
return getExecutor(mFilename).isTerminated();
|
return getExecutor(mDictName).isTerminated();
|
||||||
}
|
}
|
||||||
|
|
||||||
@UsedForTesting
|
@UsedForTesting
|
||||||
protected void runAfterGcForDebug(final Runnable r) {
|
protected void runAfterGcForDebug(final Runnable r) {
|
||||||
getExecutor(mFilename).executePrioritized(new Runnable() {
|
getExecutor(mDictName).executePrioritized(new Runnable() {
|
||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
try {
|
try {
|
||||||
mBinaryDictionary.flushWithGC();
|
mBinaryDictionary.flushWithGC();
|
||||||
r.run();
|
r.run();
|
||||||
} finally {
|
} finally {
|
||||||
mFilenameDictionaryUpdateController.mProcessingLargeTask.set(false);
|
mDictNameDictionaryUpdateController.mProcessingLargeTask.set(false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
|
@ -18,7 +18,6 @@ package com.android.inputmethod.latin;
|
||||||
|
|
||||||
import android.content.ContentProviderClient;
|
import android.content.ContentProviderClient;
|
||||||
import android.content.ContentResolver;
|
import android.content.ContentResolver;
|
||||||
import android.content.ContentUris;
|
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.database.ContentObserver;
|
import android.database.ContentObserver;
|
||||||
import android.database.Cursor;
|
import android.database.Cursor;
|
||||||
|
@ -81,7 +80,7 @@ public class UserBinaryDictionary extends ExpandableBinaryDictionary {
|
||||||
|
|
||||||
public UserBinaryDictionary(final Context context, final Locale locale,
|
public UserBinaryDictionary(final Context context, final Locale locale,
|
||||||
final boolean alsoUseMoreRestrictiveLocales) {
|
final boolean alsoUseMoreRestrictiveLocales) {
|
||||||
super(context, getFilenameWithLocale(NAME, locale), locale, Dictionary.TYPE_USER,
|
super(context, getDictNameWithLocale(NAME, locale), locale, Dictionary.TYPE_USER,
|
||||||
false /* isUpdatable */);
|
false /* isUpdatable */);
|
||||||
if (null == locale) throw new NullPointerException(); // Catch the error earlier
|
if (null == locale) throw new NullPointerException(); // Catch the error earlier
|
||||||
final String localeStr = locale.toString();
|
final String localeStr = locale.toString();
|
||||||
|
|
|
@ -58,13 +58,13 @@ public abstract class DecayingExpandableBinaryDictionaryBase extends ExpandableB
|
||||||
/** Locale for which this user history dictionary is storing words */
|
/** Locale for which this user history dictionary is storing words */
|
||||||
private final Locale mLocale;
|
private final Locale mLocale;
|
||||||
|
|
||||||
private final String mFileName;
|
private final String mDictName;
|
||||||
|
|
||||||
/* package */ DecayingExpandableBinaryDictionaryBase(final Context context,
|
/* package */ DecayingExpandableBinaryDictionaryBase(final Context context,
|
||||||
final Locale locale, final String dictionaryType, final String fileName) {
|
final Locale locale, final String dictionaryType, final String dictName) {
|
||||||
super(context, fileName, locale, dictionaryType, true);
|
super(context, dictName, locale, dictionaryType, true);
|
||||||
mLocale = locale;
|
mLocale = locale;
|
||||||
mFileName = fileName;
|
mDictName = dictName;
|
||||||
if (mLocale != null && mLocale.toString().length() > 1) {
|
if (mLocale != null && mLocale.toString().length() > 1) {
|
||||||
reloadDictionaryIfRequired();
|
reloadDictionaryIfRequired();
|
||||||
}
|
}
|
||||||
|
@ -88,7 +88,7 @@ public abstract class DecayingExpandableBinaryDictionaryBase extends ExpandableB
|
||||||
FormatSpec.FileHeader.ATTRIBUTE_VALUE_TRUE);
|
FormatSpec.FileHeader.ATTRIBUTE_VALUE_TRUE);
|
||||||
attributeMap.put(FormatSpec.FileHeader.HAS_HISTORICAL_INFO_ATTRIBUTE,
|
attributeMap.put(FormatSpec.FileHeader.HAS_HISTORICAL_INFO_ATTRIBUTE,
|
||||||
FormatSpec.FileHeader.ATTRIBUTE_VALUE_TRUE);
|
FormatSpec.FileHeader.ATTRIBUTE_VALUE_TRUE);
|
||||||
attributeMap.put(FormatSpec.FileHeader.DICTIONARY_ID_ATTRIBUTE, mFileName);
|
attributeMap.put(FormatSpec.FileHeader.DICTIONARY_ID_ATTRIBUTE, mDictName);
|
||||||
attributeMap.put(FormatSpec.FileHeader.DICTIONARY_LOCALE_ATTRIBUTE, mLocale.toString());
|
attributeMap.put(FormatSpec.FileHeader.DICTIONARY_LOCALE_ATTRIBUTE, mLocale.toString());
|
||||||
attributeMap.put(FormatSpec.FileHeader.DICTIONARY_VERSION_ATTRIBUTE,
|
attributeMap.put(FormatSpec.FileHeader.DICTIONARY_VERSION_ATTRIBUTE,
|
||||||
String.valueOf(TimeUnit.MILLISECONDS.toSeconds(System.currentTimeMillis())));
|
String.valueOf(TimeUnit.MILLISECONDS.toSeconds(System.currentTimeMillis())));
|
||||||
|
@ -113,9 +113,13 @@ public abstract class DecayingExpandableBinaryDictionaryBase extends ExpandableB
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected String getFileNameExtensionToOpenDict() {
|
protected String getFileNameToCreateDict(final String dictName) {
|
||||||
// TODO: pass the directory name instead
|
return dictName;
|
||||||
return "/" + FormatSpec.HEADER_FILE_EXTENSION;
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected String getFileNameToOpenDict(final String dictName) {
|
||||||
|
return dictName + "/" + dictName + FormatSpec.HEADER_FILE_EXTENSION;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void addMultipleDictionaryEntriesToDictionary(
|
public void addMultipleDictionaryEntriesToDictionary(
|
||||||
|
@ -194,7 +198,7 @@ public abstract class DecayingExpandableBinaryDictionaryBase extends ExpandableB
|
||||||
};
|
};
|
||||||
|
|
||||||
// Load the dictionary from binary file
|
// Load the dictionary from binary file
|
||||||
final File dictFile = new File(mContext.getFilesDir(), mFileName);
|
final File dictFile = new File(mContext.getFilesDir(), mDictName);
|
||||||
final DictDecoder dictDecoder = FormatSpec.getDictDecoder(dictFile,
|
final DictDecoder dictDecoder = FormatSpec.getDictDecoder(dictFile,
|
||||||
DictDecoder.USE_BYTEARRAY);
|
DictDecoder.USE_BYTEARRAY);
|
||||||
if (dictDecoder == null) {
|
if (dictDecoder == null) {
|
||||||
|
|
|
@ -17,7 +17,6 @@
|
||||||
package com.android.inputmethod.latin.personalization;
|
package com.android.inputmethod.latin.personalization;
|
||||||
|
|
||||||
import com.android.inputmethod.latin.Dictionary;
|
import com.android.inputmethod.latin.Dictionary;
|
||||||
import com.android.inputmethod.latin.ExpandableBinaryDictionary;
|
|
||||||
import com.android.inputmethod.latin.utils.CollectionUtils;
|
import com.android.inputmethod.latin.utils.CollectionUtils;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
@ -33,11 +32,7 @@ public class PersonalizationDictionary extends DecayingExpandableBinaryDictionar
|
||||||
|
|
||||||
/* package */ PersonalizationDictionary(final Context context, final Locale locale) {
|
/* package */ PersonalizationDictionary(final Context context, final Locale locale) {
|
||||||
super(context, locale, Dictionary.TYPE_PERSONALIZATION,
|
super(context, locale, Dictionary.TYPE_PERSONALIZATION,
|
||||||
getDictionaryFileName(locale.toString()));
|
getDictNameWithLocale(NAME, locale));
|
||||||
}
|
|
||||||
|
|
||||||
private static String getDictionaryFileName(final String locale) {
|
|
||||||
return NAME + "." + locale + ExpandableBinaryDictionary.DICT_FILE_EXTENSION;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void registerUpdateSession(PersonalizationDictionaryUpdateSession session) {
|
public void registerUpdateSession(PersonalizationDictionaryUpdateSession session) {
|
||||||
|
|
|
@ -17,7 +17,6 @@
|
||||||
package com.android.inputmethod.latin.personalization;
|
package com.android.inputmethod.latin.personalization;
|
||||||
|
|
||||||
import com.android.inputmethod.latin.Dictionary;
|
import com.android.inputmethod.latin.Dictionary;
|
||||||
import com.android.inputmethod.latin.ExpandableBinaryDictionary;
|
|
||||||
|
|
||||||
import java.util.Locale;
|
import java.util.Locale;
|
||||||
|
|
||||||
|
@ -31,12 +30,7 @@ public class UserHistoryDictionary extends DecayingExpandableBinaryDictionaryBas
|
||||||
/* package for tests */ static final String NAME =
|
/* package for tests */ static final String NAME =
|
||||||
UserHistoryDictionary.class.getSimpleName();
|
UserHistoryDictionary.class.getSimpleName();
|
||||||
/* package */ UserHistoryDictionary(final Context context, final Locale locale) {
|
/* package */ UserHistoryDictionary(final Context context, final Locale locale) {
|
||||||
super(context, locale, Dictionary.TYPE_USER_HISTORY,
|
super(context, locale, Dictionary.TYPE_USER_HISTORY, getDictNameWithLocale(NAME, locale));
|
||||||
getDictionaryFileName(locale.toString()));
|
|
||||||
}
|
|
||||||
|
|
||||||
private static String getDictionaryFileName(final String locale) {
|
|
||||||
return NAME + "." + locale + ExpandableBinaryDictionary.DICT_FILE_EXTENSION;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void cancelAddingUserHistory(final String word0, final String word1) {
|
public void cancelAddingUserHistory(final String word0, final String word1) {
|
||||||
|
|
|
@ -73,8 +73,8 @@ class BigramDictContent : public SparseTableDictContent {
|
||||||
|
|
||||||
bool copyBigramList(const int bigramListPos, const int toPos);
|
bool copyBigramList(const int bigramListPos, const int toPos);
|
||||||
|
|
||||||
bool flushToFile(const char *const dictDirPath) const {
|
bool flushToFile(const char *const dictBasePath) const {
|
||||||
return flush(dictDirPath, Ver4DictConstants::BIGRAM_LOOKUP_TABLE_FILE_EXTENSION,
|
return flush(dictBasePath, Ver4DictConstants::BIGRAM_LOOKUP_TABLE_FILE_EXTENSION,
|
||||||
Ver4DictConstants::BIGRAM_CONTENT_TABLE_FILE_EXTENSION,
|
Ver4DictConstants::BIGRAM_CONTENT_TABLE_FILE_EXTENSION,
|
||||||
Ver4DictConstants::BIGRAM_FILE_EXTENSION);
|
Ver4DictConstants::BIGRAM_FILE_EXTENSION);
|
||||||
}
|
}
|
||||||
|
|
|
@ -71,7 +71,7 @@ bool ProbabilityDictContent::setProbabilityEntry(const int terminalId,
|
||||||
return writeEntry(probabilityEntry, entryPos);
|
return writeEntry(probabilityEntry, entryPos);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ProbabilityDictContent::flushToFile(const char *const dictDirPath) const {
|
bool ProbabilityDictContent::flushToFile(const char *const dictBasePath) const {
|
||||||
if (getEntryPos(mSize) < getBuffer()->getTailPosition()) {
|
if (getEntryPos(mSize) < getBuffer()->getTailPosition()) {
|
||||||
ProbabilityDictContent probabilityDictContentToWrite(mHasHistoricalInfo);
|
ProbabilityDictContent probabilityDictContentToWrite(mHasHistoricalInfo);
|
||||||
for (int i = 0; i < mSize; ++i) {
|
for (int i = 0; i < mSize; ++i) {
|
||||||
|
@ -81,10 +81,10 @@ bool ProbabilityDictContent::flushToFile(const char *const dictDirPath) const {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return probabilityDictContentToWrite.flush(dictDirPath,
|
return probabilityDictContentToWrite.flush(dictBasePath,
|
||||||
Ver4DictConstants::FREQ_FILE_EXTENSION);
|
Ver4DictConstants::FREQ_FILE_EXTENSION);
|
||||||
} else {
|
} else {
|
||||||
return flush(dictDirPath, Ver4DictConstants::FREQ_FILE_EXTENSION);
|
return flush(dictBasePath, Ver4DictConstants::FREQ_FILE_EXTENSION);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -46,8 +46,8 @@ int ShortcutDictContent::getShortcutListHeadPos(const int terminalId) const {
|
||||||
return addressLookupTable->get(terminalId);
|
return addressLookupTable->get(terminalId);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ShortcutDictContent::flushToFile(const char *const dictDirPath) const {
|
bool ShortcutDictContent::flushToFile(const char *const dictBasePath) const {
|
||||||
return flush(dictDirPath, Ver4DictConstants::SHORTCUT_LOOKUP_TABLE_FILE_EXTENSION,
|
return flush(dictBasePath, Ver4DictConstants::SHORTCUT_LOOKUP_TABLE_FILE_EXTENSION,
|
||||||
Ver4DictConstants::SHORTCUT_CONTENT_TABLE_FILE_EXTENSION,
|
Ver4DictConstants::SHORTCUT_CONTENT_TABLE_FILE_EXTENSION,
|
||||||
Ver4DictConstants::SHORTCUT_FILE_EXTENSION);
|
Ver4DictConstants::SHORTCUT_FILE_EXTENSION);
|
||||||
}
|
}
|
||||||
|
|
|
@ -53,7 +53,7 @@ class ShortcutDictContent : public SparseTableDictContent {
|
||||||
// Returns head position of shortcut list for a PtNode specified by terminalId.
|
// Returns head position of shortcut list for a PtNode specified by terminalId.
|
||||||
int getShortcutListHeadPos(const int terminalId) const;
|
int getShortcutListHeadPos(const int terminalId) const;
|
||||||
|
|
||||||
bool flushToFile(const char *const dictDirPath) const;
|
bool flushToFile(const char *const dictBasePath) const;
|
||||||
|
|
||||||
bool runGC(const TerminalPositionLookupTable::TerminalIdMap *const terminalIdMap,
|
bool runGC(const TerminalPositionLookupTable::TerminalIdMap *const terminalIdMap,
|
||||||
const ShortcutDictContent *const originalShortcutDictContent);
|
const ShortcutDictContent *const originalShortcutDictContent);
|
||||||
|
|
|
@ -59,9 +59,9 @@ class SingleDictContent : public DictContent {
|
||||||
return &mExpandableContentBuffer;
|
return &mExpandableContentBuffer;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool flush(const char *const dictDirPath, const char *const contentFileName) const {
|
bool flush(const char *const dictBasePath, const char *const contentFileNameSuffix) const {
|
||||||
return DictFileWritingUtils::flushBufferToFileInDir(dictDirPath, contentFileName,
|
return DictFileWritingUtils::flushBufferToFileWithSuffix(dictBasePath,
|
||||||
&mExpandableContentBuffer);
|
contentFileNameSuffix, &mExpandableContentBuffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
|
@ -18,18 +18,18 @@
|
||||||
|
|
||||||
namespace latinime {
|
namespace latinime {
|
||||||
|
|
||||||
bool SparseTableDictContent::flush(const char *const dictDirPath,
|
bool SparseTableDictContent::flush(const char *const dictBasePath,
|
||||||
const char *const lookupTableFileName, const char *const addressTableFileName,
|
const char *const lookupTableFileNameSuffix, const char *const addressTableFileNameSuffix,
|
||||||
const char *const contentFileName) const {
|
const char *const contentFileNameSuffix) const {
|
||||||
if (!DictFileWritingUtils::flushBufferToFileInDir(dictDirPath, lookupTableFileName,
|
if (!DictFileWritingUtils::flushBufferToFileWithSuffix(dictBasePath, lookupTableFileNameSuffix,
|
||||||
&mExpandableLookupTableBuffer)){
|
&mExpandableLookupTableBuffer)){
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (!DictFileWritingUtils::flushBufferToFileInDir(dictDirPath, addressTableFileName,
|
if (!DictFileWritingUtils::flushBufferToFileWithSuffix(dictBasePath, addressTableFileNameSuffix,
|
||||||
&mExpandableAddressTableBuffer)) {
|
&mExpandableAddressTableBuffer)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (!DictFileWritingUtils::flushBufferToFileInDir(dictDirPath, contentFileName,
|
if (!DictFileWritingUtils::flushBufferToFileWithSuffix(dictBasePath, contentFileNameSuffix,
|
||||||
&mExpandableContentBuffer)) {
|
&mExpandableContentBuffer)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
|
@ -50,7 +50,7 @@ bool TerminalPositionLookupTable::setTerminalPtNodePosition(
|
||||||
Ver4DictConstants::TERMINAL_ADDRESS_TABLE_ADDRESS_SIZE, getEntryPos(terminalId));
|
Ver4DictConstants::TERMINAL_ADDRESS_TABLE_ADDRESS_SIZE, getEntryPos(terminalId));
|
||||||
}
|
}
|
||||||
|
|
||||||
bool TerminalPositionLookupTable::flushToFile(const char *const dictDirPath) const {
|
bool TerminalPositionLookupTable::flushToFile(const char *const dictBasePath) const {
|
||||||
// If the used buffer size is smaller than the actual buffer size, regenerate the lookup
|
// If the used buffer size is smaller than the actual buffer size, regenerate the lookup
|
||||||
// table and write the new table to the file.
|
// table and write the new table to the file.
|
||||||
if (getEntryPos(mSize) < getBuffer()->getTailPosition()) {
|
if (getEntryPos(mSize) < getBuffer()->getTailPosition()) {
|
||||||
|
@ -63,12 +63,12 @@ bool TerminalPositionLookupTable::flushToFile(const char *const dictDirPath) con
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return lookupTableToWrite.flush(dictDirPath,
|
return lookupTableToWrite.flush(dictBasePath,
|
||||||
Ver4DictConstants::TERMINAL_ADDRESS_TABLE_FILE_EXTENSION);
|
Ver4DictConstants::TERMINAL_ADDRESS_TABLE_FILE_EXTENSION);
|
||||||
} else {
|
} else {
|
||||||
// We can simply use this lookup table because the buffer size has not been
|
// We can simply use this lookup table because the buffer size has not been
|
||||||
// changed.
|
// changed.
|
||||||
return flush(dictDirPath, Ver4DictConstants::TERMINAL_ADDRESS_TABLE_FILE_EXTENSION);
|
return flush(dictBasePath, Ver4DictConstants::TERMINAL_ADDRESS_TABLE_FILE_EXTENSION);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -44,7 +44,7 @@ class TerminalPositionLookupTable : public SingleDictContent {
|
||||||
return mSize;
|
return mSize;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool flushToFile(const char *const dictDirPath) const;
|
bool flushToFile(const char *const dictBasePath) const;
|
||||||
|
|
||||||
bool runGCTerminalIds(TerminalIdMap *const terminalIdMap);
|
bool runGCTerminalIds(TerminalIdMap *const terminalIdMap);
|
||||||
|
|
||||||
|
|
|
@ -17,6 +17,7 @@
|
||||||
#include "suggest/policyimpl/dictionary/structure/v4/ver4_dict_buffers.h"
|
#include "suggest/policyimpl/dictionary/structure/v4/ver4_dict_buffers.h"
|
||||||
|
|
||||||
#include <cerrno>
|
#include <cerrno>
|
||||||
|
#include <cstring>
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
|
|
||||||
|
@ -52,34 +53,42 @@ bool Ver4DictBuffers::flushHeaderAndDictBuffers(const char *const dictDirPath,
|
||||||
AKLOGE("Cannot create directory: %s. errno: %d.", tmpDirPath, errno);
|
AKLOGE("Cannot create directory: %s. errno: %d.", tmpDirPath, errno);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
// Get dictionary base path.
|
||||||
|
const int dictNameBufSize = strlen(dictDirPath) + 1 /* terminator */;
|
||||||
|
char dictName[dictNameBufSize];
|
||||||
|
FileUtils::getBasename(dictDirPath, dictNameBufSize, dictName);
|
||||||
|
const int dictBasePathBufSize = FileUtils::getFilePathBufSize(tmpDirPath, dictName);
|
||||||
|
char dictBasePath[dictBasePathBufSize];
|
||||||
|
FileUtils::getFilePath(tmpDirPath, dictName, dictBasePathBufSize, dictBasePath);
|
||||||
|
|
||||||
// Write header file.
|
// Write header file.
|
||||||
if (!DictFileWritingUtils::flushBufferToFileInDir(tmpDirPath,
|
if (!DictFileWritingUtils::flushBufferToFileWithSuffix(dictBasePath,
|
||||||
Ver4DictConstants::HEADER_FILE_EXTENSION, headerBuffer)) {
|
Ver4DictConstants::HEADER_FILE_EXTENSION, headerBuffer)) {
|
||||||
AKLOGE("Dictionary header file %s/%s cannot be written.", tmpDirPath,
|
AKLOGE("Dictionary header file %s%s cannot be written.", tmpDirPath,
|
||||||
Ver4DictConstants::HEADER_FILE_EXTENSION);
|
Ver4DictConstants::HEADER_FILE_EXTENSION);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
// Write trie file.
|
// Write trie file.
|
||||||
if (!DictFileWritingUtils::flushBufferToFileInDir(tmpDirPath,
|
if (!DictFileWritingUtils::flushBufferToFileWithSuffix(dictBasePath,
|
||||||
Ver4DictConstants::TRIE_FILE_EXTENSION, &mExpandableTrieBuffer)) {
|
Ver4DictConstants::TRIE_FILE_EXTENSION, &mExpandableTrieBuffer)) {
|
||||||
AKLOGE("Dictionary trie file %s/%s cannot be written.", tmpDirPath,
|
AKLOGE("Dictionary trie file %s%s cannot be written.", tmpDirPath,
|
||||||
Ver4DictConstants::TRIE_FILE_EXTENSION);
|
Ver4DictConstants::TRIE_FILE_EXTENSION);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
// Write dictionary contents.
|
// Write dictionary contents.
|
||||||
if (!mTerminalPositionLookupTable.flushToFile(tmpDirPath)) {
|
if (!mTerminalPositionLookupTable.flushToFile(dictBasePath)) {
|
||||||
AKLOGE("Terminal position lookup table cannot be written. %s", tmpDirPath);
|
AKLOGE("Terminal position lookup table cannot be written. %s", tmpDirPath);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (!mProbabilityDictContent.flushToFile(tmpDirPath)) {
|
if (!mProbabilityDictContent.flushToFile(dictBasePath)) {
|
||||||
AKLOGE("Probability dict content cannot be written. %s", tmpDirPath);
|
AKLOGE("Probability dict content cannot be written. %s", tmpDirPath);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (!mBigramDictContent.flushToFile(tmpDirPath)) {
|
if (!mBigramDictContent.flushToFile(dictBasePath)) {
|
||||||
AKLOGE("Bigram dict content cannot be written. %s", tmpDirPath);
|
AKLOGE("Bigram dict content cannot be written. %s", tmpDirPath);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (!mShortcutDictContent.flushToFile(tmpDirPath)) {
|
if (!mShortcutDictContent.flushToFile(dictBasePath)) {
|
||||||
AKLOGE("Shortcut dict content cannot be written. %s", tmpDirPath);
|
AKLOGE("Shortcut dict content cannot be written. %s", tmpDirPath);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
|
@ -83,11 +83,11 @@ const char *const DictFileWritingUtils::TEMP_FILE_SUFFIX_FOR_WRITING_DICT_FILE =
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* static */ bool DictFileWritingUtils::flushBufferToFileInDir(const char *const dirPath,
|
/* static */ bool DictFileWritingUtils::flushBufferToFileWithSuffix(const char *const basePath,
|
||||||
const char *const fileName, const BufferWithExtendableBuffer *const buffer) {
|
const char *const suffix, const BufferWithExtendableBuffer *const buffer) {
|
||||||
const int filePathBufSize = FileUtils::getFilePathBufSize(dirPath, fileName);
|
const int filePathBufSize = FileUtils::getFilePathWithSuffixBufSize(basePath, suffix);
|
||||||
char filePath[filePathBufSize];
|
char filePath[filePathBufSize];
|
||||||
FileUtils::getFilePath(dirPath, fileName, filePathBufSize, filePath);
|
FileUtils::getFilePathWithSuffix(basePath, suffix, filePathBufSize, filePath);
|
||||||
return flushBufferToFile(filePath, buffer);
|
return flushBufferToFile(filePath, buffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -37,7 +37,7 @@ class DictFileWritingUtils {
|
||||||
BufferWithExtendableBuffer *const dictHeader,
|
BufferWithExtendableBuffer *const dictHeader,
|
||||||
BufferWithExtendableBuffer *const dictBody);
|
BufferWithExtendableBuffer *const dictBody);
|
||||||
|
|
||||||
static bool flushBufferToFileInDir(const char *const dirPath, const char *const fileName,
|
static bool flushBufferToFileWithSuffix(const char *const basePath, const char *const suffix,
|
||||||
const BufferWithExtendableBuffer *const buffer);
|
const BufferWithExtendableBuffer *const buffer);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
|
@ -20,6 +20,7 @@
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
#include <dirent.h>
|
#include <dirent.h>
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
|
#include <libgen.h>
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
@ -138,4 +139,19 @@ namespace latinime {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* static */ void FileUtils::getBasename(const char *const filePath,
|
||||||
|
const int outNameBufSize, char *const outName) {
|
||||||
|
const int filePathBufSize = strlen(filePath) + 1 /* terminator */;
|
||||||
|
char filePathBuf[filePathBufSize];
|
||||||
|
snprintf(filePathBuf, filePathBufSize, "%s", filePath);
|
||||||
|
const char *const baseName = basename(filePathBuf);
|
||||||
|
const int baseNameLength = strlen(baseName);
|
||||||
|
if (baseNameLength >= outNameBufSize) {
|
||||||
|
AKLOGE("outNameBufSize is too small. dirPath: %s, outNameBufSize: %d",
|
||||||
|
filePath, outNameBufSize);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
snprintf(outName, baseNameLength + 1 /* terminator */, "%s", baseName);
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace latinime
|
} // namespace latinime
|
||||||
|
|
|
@ -48,6 +48,9 @@ class FileUtils {
|
||||||
static void getDirPath(const char *const filePath, const int dirPathBufSize,
|
static void getDirPath(const char *const filePath, const int dirPathBufSize,
|
||||||
char *const outDirPath);
|
char *const outDirPath);
|
||||||
|
|
||||||
|
static void getBasename(const char *const filePath, const int outNameBufSize,
|
||||||
|
char *const outName);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
DISALLOW_IMPLICIT_CONSTRUCTORS(FileUtils);
|
DISALLOW_IMPLICIT_CONSTRUCTORS(FileUtils);
|
||||||
};
|
};
|
||||||
|
|
|
@ -122,12 +122,13 @@ public class BinaryDictionaryDecayingTests extends AndroidTestCase {
|
||||||
FormatSpec.FileHeader.ATTRIBUTE_VALUE_TRUE);
|
FormatSpec.FileHeader.ATTRIBUTE_VALUE_TRUE);
|
||||||
attributeMap.put(FormatSpec.FileHeader.HAS_HISTORICAL_INFO_ATTRIBUTE,
|
attributeMap.put(FormatSpec.FileHeader.HAS_HISTORICAL_INFO_ATTRIBUTE,
|
||||||
FormatSpec.FileHeader.ATTRIBUTE_VALUE_TRUE);
|
FormatSpec.FileHeader.ATTRIBUTE_VALUE_TRUE);
|
||||||
|
final String headerFileName = file.getName() + FormatSpec.HEADER_FILE_EXTENSION;
|
||||||
if (BinaryDictionary.createEmptyDictFile(file.getAbsolutePath(),
|
if (BinaryDictionary.createEmptyDictFile(file.getAbsolutePath(),
|
||||||
FormatSpec.VERSION4, attributeMap)) {
|
FormatSpec.VERSION4, attributeMap)) {
|
||||||
return new File(file, FormatSpec.HEADER_FILE_EXTENSION);
|
return new File(file, headerFileName);
|
||||||
} else {
|
} else {
|
||||||
throw new IOException("Empty dictionary " + file.getAbsolutePath() + " "
|
throw new IOException("Empty dictionary " + file.getAbsolutePath() + " "
|
||||||
+ FormatSpec.HEADER_FILE_EXTENSION + " cannot be created.");
|
+ headerFileName + " cannot be created.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -70,12 +70,13 @@ public class BinaryDictionaryTests extends AndroidTestCase {
|
||||||
Map<String, String> attributeMap = new HashMap<String, String>();
|
Map<String, String> attributeMap = new HashMap<String, String>();
|
||||||
attributeMap.put(FormatSpec.FileHeader.SUPPORTS_DYNAMIC_UPDATE_ATTRIBUTE,
|
attributeMap.put(FormatSpec.FileHeader.SUPPORTS_DYNAMIC_UPDATE_ATTRIBUTE,
|
||||||
FormatSpec.FileHeader.ATTRIBUTE_VALUE_TRUE);
|
FormatSpec.FileHeader.ATTRIBUTE_VALUE_TRUE);
|
||||||
|
final String headerFileName = file.getName() + FormatSpec.HEADER_FILE_EXTENSION;
|
||||||
if (BinaryDictionary.createEmptyDictFile(file.getAbsolutePath(),
|
if (BinaryDictionary.createEmptyDictFile(file.getAbsolutePath(),
|
||||||
FormatSpec.VERSION4, attributeMap)) {
|
FormatSpec.VERSION4, attributeMap)) {
|
||||||
return new File(file, FormatSpec.HEADER_FILE_EXTENSION);
|
return new File(file, headerFileName);
|
||||||
} else {
|
} else {
|
||||||
throw new IOException("Empty dictionary " + file.getAbsolutePath() + " "
|
throw new IOException("Empty dictionary " + file.getAbsolutePath() + " "
|
||||||
+ FormatSpec.HEADER_FILE_EXTENSION + " cannot be created.");
|
+ headerFileName + " cannot be created.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -20,7 +20,6 @@ import android.test.AndroidTestCase;
|
||||||
import android.test.suitebuilder.annotation.LargeTest;
|
import android.test.suitebuilder.annotation.LargeTest;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
|
|
||||||
import com.android.inputmethod.latin.ExpandableBinaryDictionary;
|
|
||||||
import com.android.inputmethod.latin.utils.CollectionUtils;
|
import com.android.inputmethod.latin.utils.CollectionUtils;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
|
@ -137,8 +136,7 @@ public class UserHistoryDictionaryTests extends AndroidTestCase {
|
||||||
Log.d(TAG, "This test can be used for profiling.");
|
Log.d(TAG, "This test can be used for profiling.");
|
||||||
Log.d(TAG, "Usage: please set UserHistoryDictionary.PROFILE_SAVE_RESTORE to true.");
|
Log.d(TAG, "Usage: please set UserHistoryDictionary.PROFILE_SAVE_RESTORE to true.");
|
||||||
final String testFilenameSuffix = "test_random_words" + System.currentTimeMillis();
|
final String testFilenameSuffix = "test_random_words" + System.currentTimeMillis();
|
||||||
final String fileName = UserHistoryDictionary.NAME + "." + testFilenameSuffix
|
final String fileName = UserHistoryDictionary.NAME + "." + testFilenameSuffix;
|
||||||
+ ExpandableBinaryDictionary.DICT_FILE_EXTENSION;
|
|
||||||
|
|
||||||
final int numberOfWords = 1000;
|
final int numberOfWords = 1000;
|
||||||
final Random random = new Random(123456);
|
final Random random = new Random(123456);
|
||||||
|
@ -172,8 +170,7 @@ public class UserHistoryDictionaryTests extends AndroidTestCase {
|
||||||
// Create filename suffixes for this test.
|
// Create filename suffixes for this test.
|
||||||
for (int i = 0; i < numberOfLanguages; i++) {
|
for (int i = 0; i < numberOfLanguages; i++) {
|
||||||
testFilenameSuffixes[i] = "test_switching_languages" + i;
|
testFilenameSuffixes[i] = "test_switching_languages" + i;
|
||||||
final String fileName = UserHistoryDictionary.NAME + "." +
|
final String fileName = UserHistoryDictionary.NAME + "." + testFilenameSuffixes[i];
|
||||||
testFilenameSuffixes[i] + ExpandableBinaryDictionary.DICT_FILE_EXTENSION;
|
|
||||||
dictFiles[i] = new File(getContext().getFilesDir(), fileName);
|
dictFiles[i] = new File(getContext().getFilesDir(), fileName);
|
||||||
clearHistory(testFilenameSuffixes[i]);
|
clearHistory(testFilenameSuffixes[i]);
|
||||||
}
|
}
|
||||||
|
@ -217,8 +214,7 @@ public class UserHistoryDictionaryTests extends AndroidTestCase {
|
||||||
} finally {
|
} finally {
|
||||||
Log.d(TAG, "waiting for writing ...");
|
Log.d(TAG, "waiting for writing ...");
|
||||||
waitForWriting(testFilenameSuffix);
|
waitForWriting(testFilenameSuffix);
|
||||||
final String fileName = UserHistoryDictionary.NAME + "." + testFilenameSuffix
|
final String fileName = UserHistoryDictionary.NAME + "." + testFilenameSuffix;
|
||||||
+ ExpandableBinaryDictionary.DICT_FILE_EXTENSION;
|
|
||||||
final File dictFile = new File(getContext().getFilesDir(), fileName);
|
final File dictFile = new File(getContext().getFilesDir(), fileName);
|
||||||
if (dictFile != null) {
|
if (dictFile != null) {
|
||||||
assertTrue(dictFile.exists());
|
assertTrue(dictFile.exists());
|
||||||
|
|
Loading…
Reference in a new issue