Loading java/src/com/android/inputmethod/latin/personalization/DynamicPredictionDictionaryBase.java +13 −1 Original line number Diff line number Diff line Loading @@ -43,6 +43,7 @@ import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; import java.util.ArrayList; import java.util.concurrent.atomic.AtomicReference; import java.util.concurrent.locks.ReentrantLock; /** Loading Loading @@ -75,6 +76,8 @@ public abstract class DynamicPredictionDictionaryBase extends ExpandableDictiona private final ArrayList<PersonalizationDictionaryUpdateSession> mSessions = CollectionUtils.newArrayList(); private final AtomicReference<AsyncTask<Void, Void, Void>> mWaitingTask; // Should always be false except when we use this class for test @UsedForTesting boolean mIsTest = false; Loading @@ -83,6 +86,7 @@ public abstract class DynamicPredictionDictionaryBase extends ExpandableDictiona super(context, dictionaryType); mLocale = locale; mPrefs = sp; mWaitingTask = new AtomicReference<AsyncTask<Void, Void, Void>>(); if (mLocale != null && mLocale.length() > 1) { loadDictionary(); } Loading Loading @@ -174,7 +178,11 @@ public abstract class DynamicPredictionDictionaryBase extends ExpandableDictiona */ private void flushPendingWrites() { // Create a background thread to write the pending entries new UpdateBinaryTask(mBigramList, mLocale, this, mPrefs, getContext()).execute(); final AsyncTask<Void, Void, Void> old = mWaitingTask.getAndSet(new UpdateBinaryTask( mBigramList, mLocale, this, mPrefs, getContext()).execute()); if (old != null) { old.cancel(false); } } @Override Loading Loading @@ -287,6 +295,7 @@ public abstract class DynamicPredictionDictionaryBase extends ExpandableDictiona @Override protected Void doInBackground(final Void... v) { if (isCancelled()) return null; if (mDynamicPredictionDictionary.mIsTest) { // If mIsTest == true, wait until the lock is released. mDynamicPredictionDictionary.mBigramListLock.lock(); Loading @@ -306,6 +315,9 @@ public abstract class DynamicPredictionDictionaryBase extends ExpandableDictiona } private void doWriteTaskLocked() { if (isCancelled()) return; mDynamicPredictionDictionary.mWaitingTask.compareAndSet(this, null); if (DBG_STRESS_TEST) { try { Log.w(TAG, "Start stress in closing: " + mLocale); Loading java/src/com/android/inputmethod/latin/personalization/UserHistoryPredictionDictionary.java +2 −1 Original line number Diff line number Diff line Loading @@ -26,7 +26,8 @@ import android.content.SharedPreferences; * cancellation or manual picks. This allows the keyboard to adapt to the typist over time. */ public class UserHistoryPredictionDictionary extends DynamicPredictionDictionaryBase { private static final String NAME = UserHistoryPredictionDictionary.class.getSimpleName(); /* package for tests */ static final String NAME = UserHistoryPredictionDictionary.class.getSimpleName(); /* package */ UserHistoryPredictionDictionary(final Context context, final String locale, final SharedPreferences sp) { super(context, locale, sp, Dictionary.TYPE_USER_HISTORY); Loading tests/src/com/android/inputmethod/latin/personalization/UserHistoryDictionaryTests.java +46 −47 Original line number Diff line number Diff line Loading @@ -29,6 +29,7 @@ import java.util.ArrayList; import java.util.List; import java.util.Random; import java.util.Set; import java.util.concurrent.TimeUnit; /** * Unit tests for UserHistoryDictionary Loading @@ -43,6 +44,8 @@ public class UserHistoryDictionaryTests extends AndroidTestCase { "n", "o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z" }; private static final int MIN_USER_HISTORY_DICTIONARY_FILE_SIZE = 1000; @Override public void setUp() { mPrefs = PreferenceManager.getDefaultSharedPreferences(getContext()); Loading Loading @@ -78,43 +81,42 @@ public class UserHistoryDictionaryTests extends AndroidTestCase { } } private void addAndWriteRandomWords(final String locale, final int numberOfWords, final Random random) { final List<String> words = generateWords(numberOfWords, random); final UserHistoryPredictionDictionary dict = PersonalizationDictionaryHelper.getUserHistoryPredictionDictionary(getContext(), locale, mPrefs); // Add random words to the user history dictionary. addToDict(dict, words); // write to file. dict.close(); } public void testRandomWords() { File dictFile = null; try { Log.d(TAG, "This test can be used for profiling."); Log.d(TAG, "Usage: please set UserHistoryDictionary.PROFILE_SAVE_RESTORE to true."); final String locale = "testRandomWords" + System.currentTimeMillis(); final int numberOfWords = 1000; final Random random = new Random(123456); List<String> words = generateWords(numberOfWords, random); final String locale = "testRandomWords"; final String fileName = "UserHistoryDictionary." + locale + ".dict"; dictFile = new File(getContext().getFilesDir(), fileName); final UserHistoryPredictionDictionary dict = PersonalizationDictionaryHelper.getUserHistoryPredictionDictionary( getContext(), locale, mPrefs); dict.mIsTest = true; addToDict(dict, words); try { Log.d(TAG, "waiting for adding the word ..."); Thread.sleep(2000); } catch (InterruptedException e) { Log.d(TAG, "InterruptedException: " + e); } // write to file dict.close(); addAndWriteRandomWords(locale, numberOfWords, random); } finally { try { Log.d(TAG, "waiting for writing ..."); Thread.sleep(5000); Thread.sleep(TimeUnit.MILLISECONDS.convert(5L, TimeUnit.SECONDS)); } catch (InterruptedException e) { Log.d(TAG, "InterruptedException: " + e); } } finally { final String fileName = UserHistoryPredictionDictionary.NAME + "." + locale + ".dict"; dictFile = new File(getContext().getFilesDir(), fileName); if (dictFile != null) { assertTrue(dictFile.exists()); assertTrue(dictFile.length() >= MIN_USER_HISTORY_DICTIONARY_FILE_SIZE); dictFile.delete(); } } Loading @@ -122,49 +124,46 @@ public class UserHistoryDictionaryTests extends AndroidTestCase { public void testStressTestForSwitchingLanguagesAndAddingWords() { final int numberOfLanguages = 2; final int numberOfLanguageSwitching = 100; final int numberOfWordsIntertedForEachLanguageSwitch = 100; final int numberOfLanguageSwitching = 80; final int numberOfWordsInsertedForEachLanguageSwitch = 100; final File dictFiles[] = new File[numberOfLanguages]; try { final Random random = new Random(123456); // Create locales for this test. String locales[] = new String[numberOfLanguages]; // Create filename suffixes for this test. String testFilenameSuffixes[] = new String[numberOfLanguages]; for (int i = 0; i < numberOfLanguages; i++) { locales[i] = "testSwitchingLanguages" + i; final String fileName = "UserHistoryDictionary." + locales[i] + ".dict"; testFilenameSuffixes[i] = "testSwitchingLanguages" + i; final String fileName = "UserHistoryDictionary." + testFilenameSuffixes[i] + ".dict"; dictFiles[i] = new File(getContext().getFilesDir(), fileName); } final long now = System.currentTimeMillis(); final long start = System.currentTimeMillis(); for (int i = 0; i < numberOfLanguageSwitching; i++) { final int index = i % numberOfLanguages; // Switch languages to locales[index]. final UserHistoryPredictionDictionary dict = PersonalizationDictionaryHelper.getUserHistoryPredictionDictionary( getContext(), locales[index], mPrefs); final List<String> words = generateWords( numberOfWordsIntertedForEachLanguageSwitch, random); // Add random words to the user history dictionary. addToDict(dict, words); // write to file dict.close(); // Switch languages to testFilenameSuffixes[index]. addAndWriteRandomWords(testFilenameSuffixes[index], numberOfWordsInsertedForEachLanguageSwitch, random); } final long end = System.currentTimeMillis(); Log.d(TAG, "testStressTestForSwitchingLanguageAndAddingWords took " + (end - now) + " ms"); + (end - start) + " ms"); } finally { Log.d(TAG, "waiting for writing ..."); try { Log.d(TAG, "waiting for writing ..."); Thread.sleep(5000); Thread.sleep(TimeUnit.MILLISECONDS.convert(5L, TimeUnit.SECONDS)); } catch (InterruptedException e) { Log.d(TAG, "InterruptedException: " + e); } } finally { for (final File file : dictFiles) { if (file != null) { assertTrue(file.exists()); assertTrue(file.length() >= MIN_USER_HISTORY_DICTIONARY_FILE_SIZE); file.delete(); } } Loading Loading
java/src/com/android/inputmethod/latin/personalization/DynamicPredictionDictionaryBase.java +13 −1 Original line number Diff line number Diff line Loading @@ -43,6 +43,7 @@ import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; import java.util.ArrayList; import java.util.concurrent.atomic.AtomicReference; import java.util.concurrent.locks.ReentrantLock; /** Loading Loading @@ -75,6 +76,8 @@ public abstract class DynamicPredictionDictionaryBase extends ExpandableDictiona private final ArrayList<PersonalizationDictionaryUpdateSession> mSessions = CollectionUtils.newArrayList(); private final AtomicReference<AsyncTask<Void, Void, Void>> mWaitingTask; // Should always be false except when we use this class for test @UsedForTesting boolean mIsTest = false; Loading @@ -83,6 +86,7 @@ public abstract class DynamicPredictionDictionaryBase extends ExpandableDictiona super(context, dictionaryType); mLocale = locale; mPrefs = sp; mWaitingTask = new AtomicReference<AsyncTask<Void, Void, Void>>(); if (mLocale != null && mLocale.length() > 1) { loadDictionary(); } Loading Loading @@ -174,7 +178,11 @@ public abstract class DynamicPredictionDictionaryBase extends ExpandableDictiona */ private void flushPendingWrites() { // Create a background thread to write the pending entries new UpdateBinaryTask(mBigramList, mLocale, this, mPrefs, getContext()).execute(); final AsyncTask<Void, Void, Void> old = mWaitingTask.getAndSet(new UpdateBinaryTask( mBigramList, mLocale, this, mPrefs, getContext()).execute()); if (old != null) { old.cancel(false); } } @Override Loading Loading @@ -287,6 +295,7 @@ public abstract class DynamicPredictionDictionaryBase extends ExpandableDictiona @Override protected Void doInBackground(final Void... v) { if (isCancelled()) return null; if (mDynamicPredictionDictionary.mIsTest) { // If mIsTest == true, wait until the lock is released. mDynamicPredictionDictionary.mBigramListLock.lock(); Loading @@ -306,6 +315,9 @@ public abstract class DynamicPredictionDictionaryBase extends ExpandableDictiona } private void doWriteTaskLocked() { if (isCancelled()) return; mDynamicPredictionDictionary.mWaitingTask.compareAndSet(this, null); if (DBG_STRESS_TEST) { try { Log.w(TAG, "Start stress in closing: " + mLocale); Loading
java/src/com/android/inputmethod/latin/personalization/UserHistoryPredictionDictionary.java +2 −1 Original line number Diff line number Diff line Loading @@ -26,7 +26,8 @@ import android.content.SharedPreferences; * cancellation or manual picks. This allows the keyboard to adapt to the typist over time. */ public class UserHistoryPredictionDictionary extends DynamicPredictionDictionaryBase { private static final String NAME = UserHistoryPredictionDictionary.class.getSimpleName(); /* package for tests */ static final String NAME = UserHistoryPredictionDictionary.class.getSimpleName(); /* package */ UserHistoryPredictionDictionary(final Context context, final String locale, final SharedPreferences sp) { super(context, locale, sp, Dictionary.TYPE_USER_HISTORY); Loading
tests/src/com/android/inputmethod/latin/personalization/UserHistoryDictionaryTests.java +46 −47 Original line number Diff line number Diff line Loading @@ -29,6 +29,7 @@ import java.util.ArrayList; import java.util.List; import java.util.Random; import java.util.Set; import java.util.concurrent.TimeUnit; /** * Unit tests for UserHistoryDictionary Loading @@ -43,6 +44,8 @@ public class UserHistoryDictionaryTests extends AndroidTestCase { "n", "o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z" }; private static final int MIN_USER_HISTORY_DICTIONARY_FILE_SIZE = 1000; @Override public void setUp() { mPrefs = PreferenceManager.getDefaultSharedPreferences(getContext()); Loading Loading @@ -78,43 +81,42 @@ public class UserHistoryDictionaryTests extends AndroidTestCase { } } private void addAndWriteRandomWords(final String locale, final int numberOfWords, final Random random) { final List<String> words = generateWords(numberOfWords, random); final UserHistoryPredictionDictionary dict = PersonalizationDictionaryHelper.getUserHistoryPredictionDictionary(getContext(), locale, mPrefs); // Add random words to the user history dictionary. addToDict(dict, words); // write to file. dict.close(); } public void testRandomWords() { File dictFile = null; try { Log.d(TAG, "This test can be used for profiling."); Log.d(TAG, "Usage: please set UserHistoryDictionary.PROFILE_SAVE_RESTORE to true."); final String locale = "testRandomWords" + System.currentTimeMillis(); final int numberOfWords = 1000; final Random random = new Random(123456); List<String> words = generateWords(numberOfWords, random); final String locale = "testRandomWords"; final String fileName = "UserHistoryDictionary." + locale + ".dict"; dictFile = new File(getContext().getFilesDir(), fileName); final UserHistoryPredictionDictionary dict = PersonalizationDictionaryHelper.getUserHistoryPredictionDictionary( getContext(), locale, mPrefs); dict.mIsTest = true; addToDict(dict, words); try { Log.d(TAG, "waiting for adding the word ..."); Thread.sleep(2000); } catch (InterruptedException e) { Log.d(TAG, "InterruptedException: " + e); } // write to file dict.close(); addAndWriteRandomWords(locale, numberOfWords, random); } finally { try { Log.d(TAG, "waiting for writing ..."); Thread.sleep(5000); Thread.sleep(TimeUnit.MILLISECONDS.convert(5L, TimeUnit.SECONDS)); } catch (InterruptedException e) { Log.d(TAG, "InterruptedException: " + e); } } finally { final String fileName = UserHistoryPredictionDictionary.NAME + "." + locale + ".dict"; dictFile = new File(getContext().getFilesDir(), fileName); if (dictFile != null) { assertTrue(dictFile.exists()); assertTrue(dictFile.length() >= MIN_USER_HISTORY_DICTIONARY_FILE_SIZE); dictFile.delete(); } } Loading @@ -122,49 +124,46 @@ public class UserHistoryDictionaryTests extends AndroidTestCase { public void testStressTestForSwitchingLanguagesAndAddingWords() { final int numberOfLanguages = 2; final int numberOfLanguageSwitching = 100; final int numberOfWordsIntertedForEachLanguageSwitch = 100; final int numberOfLanguageSwitching = 80; final int numberOfWordsInsertedForEachLanguageSwitch = 100; final File dictFiles[] = new File[numberOfLanguages]; try { final Random random = new Random(123456); // Create locales for this test. String locales[] = new String[numberOfLanguages]; // Create filename suffixes for this test. String testFilenameSuffixes[] = new String[numberOfLanguages]; for (int i = 0; i < numberOfLanguages; i++) { locales[i] = "testSwitchingLanguages" + i; final String fileName = "UserHistoryDictionary." + locales[i] + ".dict"; testFilenameSuffixes[i] = "testSwitchingLanguages" + i; final String fileName = "UserHistoryDictionary." + testFilenameSuffixes[i] + ".dict"; dictFiles[i] = new File(getContext().getFilesDir(), fileName); } final long now = System.currentTimeMillis(); final long start = System.currentTimeMillis(); for (int i = 0; i < numberOfLanguageSwitching; i++) { final int index = i % numberOfLanguages; // Switch languages to locales[index]. final UserHistoryPredictionDictionary dict = PersonalizationDictionaryHelper.getUserHistoryPredictionDictionary( getContext(), locales[index], mPrefs); final List<String> words = generateWords( numberOfWordsIntertedForEachLanguageSwitch, random); // Add random words to the user history dictionary. addToDict(dict, words); // write to file dict.close(); // Switch languages to testFilenameSuffixes[index]. addAndWriteRandomWords(testFilenameSuffixes[index], numberOfWordsInsertedForEachLanguageSwitch, random); } final long end = System.currentTimeMillis(); Log.d(TAG, "testStressTestForSwitchingLanguageAndAddingWords took " + (end - now) + " ms"); + (end - start) + " ms"); } finally { Log.d(TAG, "waiting for writing ..."); try { Log.d(TAG, "waiting for writing ..."); Thread.sleep(5000); Thread.sleep(TimeUnit.MILLISECONDS.convert(5L, TimeUnit.SECONDS)); } catch (InterruptedException e) { Log.d(TAG, "InterruptedException: " + e); } } finally { for (final File file : dictFiles) { if (file != null) { assertTrue(file.exists()); assertTrue(file.length() >= MIN_USER_HISTORY_DICTIONARY_FILE_SIZE); file.delete(); } } Loading