From 67c0ed8f8c14f79e61cbd16f841b1b1f3a7466d7 Mon Sep 17 00:00:00 2001 From: Keisuke Kuroyanagi Date: Thu, 24 Apr 2014 14:48:01 -0700 Subject: [PATCH] Handle user history dictionary as an ExpandableBinaryDictionary. Bug: 13755213 Change-Id: I1ea8a6df007af7153852f2d32bf5e8ec669c432b --- .../DictionaryFacilitatorForSuggest.java | 26 +++++++-------- .../latin/ExpandableBinaryDictionary.java | 8 ++--- ...ecayingExpandableBinaryDictionaryBase.java | 33 +------------------ .../UserHistoryDictionary.java | 33 ++++++++++++++++--- .../UserHistoryDictionaryTests.java | 4 +-- 5 files changed, 49 insertions(+), 55 deletions(-) diff --git a/java/src/com/android/inputmethod/latin/DictionaryFacilitatorForSuggest.java b/java/src/com/android/inputmethod/latin/DictionaryFacilitatorForSuggest.java index 78f64e08d..fa58fb09e 100644 --- a/java/src/com/android/inputmethod/latin/DictionaryFacilitatorForSuggest.java +++ b/java/src/com/android/inputmethod/latin/DictionaryFacilitatorForSuggest.java @@ -74,20 +74,18 @@ public class DictionaryFacilitatorForSuggest { // TODO: Remove sub dictionary members and use mSubDictMap. public final ContactsBinaryDictionary mContactsDictionary; public final UserBinaryDictionary mUserDictionary; - public final UserHistoryDictionary mUserHistoryDictionary; public final PersonalizationDictionary mPersonalizationDictionary; public Dictionaries() { mLocale = null; mContactsDictionary = null; mUserDictionary = null; - mUserHistoryDictionary = null; mPersonalizationDictionary = null; } public Dictionaries(final Locale locale, final Dictionary mainDict, final ContactsBinaryDictionary contactsDict, final UserBinaryDictionary userDict, - final UserHistoryDictionary userHistoryDict, + final ExpandableBinaryDictionary userHistoryDict, final PersonalizationDictionary personalizationDict) { mLocale = locale; // Main dictionary can be asynchronously loaded. @@ -96,8 +94,7 @@ public class DictionaryFacilitatorForSuggest { setSubDict(Dictionary.TYPE_CONTACTS, mContactsDictionary); mUserDictionary = userDict; setSubDict(Dictionary.TYPE_USER, mUserDictionary); - mUserHistoryDictionary = userHistoryDict; - setSubDict(Dictionary.TYPE_USER_HISTORY, mUserHistoryDictionary); + setSubDict(Dictionary.TYPE_USER_HISTORY, userHistoryDict); mPersonalizationDictionary = personalizationDict; setSubDict(Dictionary.TYPE_PERSONALIZATION, mPersonalizationDictionary); } @@ -193,9 +190,9 @@ public class DictionaryFacilitatorForSuggest { } // Open or move user history dictionary. - final UserHistoryDictionary newUserHistoryDict; + final ExpandableBinaryDictionary newUserHistoryDict; if (!closeUserHistoryDictionary && mDictionaries.hasDict(Dictionary.TYPE_USER_HISTORY)) { - newUserHistoryDict = mDictionaries.mUserHistoryDictionary; + newUserHistoryDict = mDictionaries.getSubDict(Dictionary.TYPE_USER_HISTORY); } else if (usePersonalizedDicts) { newUserHistoryDict = PersonalizationHelper.getUserHistoryDictionary(context, newLocale); } else { @@ -353,7 +350,7 @@ public class DictionaryFacilitatorForSuggest { final PersonalizationDictionary personalizationDict = mDictionaries.mPersonalizationDictionary; if (personalizationDict != null) { - personalizationDict.flush(); + personalizationDict.asyncFlushBinaryDictionary(); } } @@ -391,7 +388,9 @@ public class DictionaryFacilitatorForSuggest { public void addToUserHistory(final String suggestion, final boolean wasAutoCapitalized, final String previousWord, final int timeStampInSeconds) { final Dictionaries dictionaries = mDictionaries; - if (!dictionaries.hasDict(Dictionary.TYPE_USER_HISTORY)) { + final ExpandableBinaryDictionary userHistoryDictionary = + dictionaries.getSubDict(Dictionary.TYPE_USER_HISTORY); + if (userHistoryDictionary != null) { return; } final int maxFreq = getMaxFrequency(suggestion); @@ -433,14 +432,15 @@ public class DictionaryFacilitatorForSuggest { // We demote unrecognized words (frequency < 0, below) by specifying them as "invalid". // We don't add words with 0-frequency (assuming they would be profanity etc.). final boolean isValid = maxFreq > 0; - dictionaries.mUserHistoryDictionary.addToDictionary( - previousWord, secondWord, isValid, timeStampInSeconds); + UserHistoryDictionary.addToDictionary(userHistoryDictionary, previousWord, secondWord, + isValid, timeStampInSeconds); } public void cancelAddingUserHistory(final String previousWord, final String committedWord) { - final UserHistoryDictionary userHistoryDictionary = mDictionaries.mUserHistoryDictionary; + final ExpandableBinaryDictionary userHistoryDictionary = + mDictionaries.getSubDict(Dictionary.TYPE_USER_HISTORY); if (userHistoryDictionary != null) { - userHistoryDictionary.cancelAddingUserHistory(previousWord, committedWord); + userHistoryDictionary.removeBigramDynamically(previousWord, committedWord); } } diff --git a/java/src/com/android/inputmethod/latin/ExpandableBinaryDictionary.java b/java/src/com/android/inputmethod/latin/ExpandableBinaryDictionary.java index 89fa819c1..4077d12b3 100644 --- a/java/src/com/android/inputmethod/latin/ExpandableBinaryDictionary.java +++ b/java/src/com/android/inputmethod/latin/ExpandableBinaryDictionary.java @@ -298,7 +298,7 @@ abstract public class ExpandableBinaryDictionary extends Dictionary { /** * Dynamically adds a word unigram to the dictionary. May overwrite an existing entry. */ - protected void addWordDynamically(final String word, final int frequency, + public void addWordDynamically(final String word, final int frequency, final String shortcutTarget, final int shortcutFreq, final boolean isNotAWord, final boolean isBlacklisted, final int timestamp) { reloadDictionaryIfRequired(); @@ -325,7 +325,7 @@ abstract public class ExpandableBinaryDictionary extends Dictionary { /** * Dynamically adds a word bigram in the dictionary. May overwrite an existing entry. */ - protected void addBigramDynamically(final String word0, final String word1, + public void addBigramDynamically(final String word0, final String word1, final int frequency, final int timestamp) { reloadDictionaryIfRequired(); ExecutorUtils.getExecutor(mDictName).execute(new Runnable() { @@ -348,7 +348,7 @@ abstract public class ExpandableBinaryDictionary extends Dictionary { /** * Dynamically remove a word bigram in the dictionary. */ - protected void removeBigramDynamically(final String word0, final String word1) { + public void removeBigramDynamically(final String word0, final String word1) { reloadDictionaryIfRequired(); ExecutorUtils.getExecutor(mDictName).execute(new Runnable() { @Override @@ -634,7 +634,7 @@ abstract public class ExpandableBinaryDictionary extends Dictionary { /** * Flush binary dictionary to dictionary file. */ - protected void asyncFlushBinaryDictionary() { + public void asyncFlushBinaryDictionary() { final Runnable newTask = new Runnable() { @Override public void run() { diff --git a/java/src/com/android/inputmethod/latin/personalization/DecayingExpandableBinaryDictionaryBase.java b/java/src/com/android/inputmethod/latin/personalization/DecayingExpandableBinaryDictionaryBase.java index 46862c1c0..35b4ccd40 100644 --- a/java/src/com/android/inputmethod/latin/personalization/DecayingExpandableBinaryDictionaryBase.java +++ b/java/src/com/android/inputmethod/latin/personalization/DecayingExpandableBinaryDictionaryBase.java @@ -65,12 +65,8 @@ public abstract class DecayingExpandableBinaryDictionaryBase extends ExpandableB dumpAllWordsForDebug(); } // Flush pending writes. - flush(); - super.close(); - } - - public void flush() { asyncFlushBinaryDictionary(); + super.close(); } @Override @@ -103,33 +99,6 @@ public abstract class DecayingExpandableBinaryDictionaryBase extends ExpandableB addMultipleDictionaryEntriesDynamically(languageModelParams, callback); } - /** - * Pair will be added to the decaying dictionary. - * - * The first word may be null. That means we don't know the context, in other words, - * it's only a unigram. The first word may also be an empty string : this means start - * context, as in beginning of a sentence for example. - * The second word may not be null (a NullPointerException would be thrown). - */ - public void addToDictionary(final String word0, final String word1, final boolean isValid, - final int timestamp) { - if (word1.length() >= Constants.DICTIONARY_MAX_WORD_LENGTH || - (word0 != null && word0.length() >= Constants.DICTIONARY_MAX_WORD_LENGTH)) { - return; - } - final int frequency = isValid ? - FREQUENCY_FOR_WORDS_IN_DICTS : FREQUENCY_FOR_WORDS_NOT_IN_DICTS; - addWordDynamically(word1, frequency, null /* shortcutTarget */, 0 /* shortcutFreq */, - false /* isNotAWord */, false /* isBlacklisted */, timestamp); - // Do not insert a word as a bigram of itself - if (word1.equals(word0)) { - return; - } - if (null != word0) { - addBigramDynamically(word0, word1, frequency, timestamp); - } - } - @Override protected void loadInitialContentsLocked() { // No initial contents. diff --git a/java/src/com/android/inputmethod/latin/personalization/UserHistoryDictionary.java b/java/src/com/android/inputmethod/latin/personalization/UserHistoryDictionary.java index 504e9b2f3..8a29c354d 100644 --- a/java/src/com/android/inputmethod/latin/personalization/UserHistoryDictionary.java +++ b/java/src/com/android/inputmethod/latin/personalization/UserHistoryDictionary.java @@ -18,7 +18,9 @@ package com.android.inputmethod.latin.personalization; import android.content.Context; +import com.android.inputmethod.latin.Constants; import com.android.inputmethod.latin.Dictionary; +import com.android.inputmethod.latin.ExpandableBinaryDictionary; import java.io.File; import java.util.Locale; @@ -40,13 +42,36 @@ public class UserHistoryDictionary extends DecayingExpandableBinaryDictionaryBas dictFile); } - public void cancelAddingUserHistory(final String word0, final String word1) { - removeBigramDynamically(word0, word1); - } - @Override public boolean isValidWord(final String word) { // Strings out of this dictionary should not be considered existing words. return false; } + + /** + * Pair will be added to the user history dictionary. + * + * The first word may be null. That means we don't know the context, in other words, + * it's only a unigram. The first word may also be an empty string : this means start + * context, as in beginning of a sentence for example. + * The second word may not be null (a NullPointerException would be thrown). + */ + public static void addToDictionary(final ExpandableBinaryDictionary userHistoryDictionary, + final String word0, final String word1, final boolean isValid, final int timestamp) { + if (word1.length() >= Constants.DICTIONARY_MAX_WORD_LENGTH || + (word0 != null && word0.length() >= Constants.DICTIONARY_MAX_WORD_LENGTH)) { + return; + } + final int frequency = isValid ? + FREQUENCY_FOR_WORDS_IN_DICTS : FREQUENCY_FOR_WORDS_NOT_IN_DICTS; + userHistoryDictionary.addWordDynamically(word1, frequency, null /* shortcutTarget */, + 0 /* shortcutFreq */, false /* isNotAWord */, false /* isBlacklisted */, timestamp); + // Do not insert a word as a bigram of itself + if (word1.equals(word0)) { + return; + } + if (null != word0) { + userHistoryDictionary.addBigramDynamically(word0, word1, frequency, timestamp); + } + } } diff --git a/tests/src/com/android/inputmethod/latin/personalization/UserHistoryDictionaryTests.java b/tests/src/com/android/inputmethod/latin/personalization/UserHistoryDictionaryTests.java index e054ab68c..4399ba04f 100644 --- a/tests/src/com/android/inputmethod/latin/personalization/UserHistoryDictionaryTests.java +++ b/tests/src/com/android/inputmethod/latin/personalization/UserHistoryDictionaryTests.java @@ -111,7 +111,7 @@ public class UserHistoryDictionaryTests extends AndroidTestCase { private static void addToDict(final UserHistoryDictionary dict, final List words) { String prevWord = null; for (String word : words) { - dict.addToDictionary(prevWord, word, true, + UserHistoryDictionary.addToDictionary(dict, prevWord, word, true, (int)TimeUnit.MILLISECONDS.toSeconds(System.currentTimeMillis())); prevWord = word; } @@ -262,7 +262,7 @@ public class UserHistoryDictionaryTests extends AndroidTestCase { dict.waitAllTasksForTests(); String prevWord = null; for (final String word : words) { - dict.addToDictionary(prevWord, word, true, mCurrentTime); + UserHistoryDictionary.addToDictionary(dict, prevWord, word, true, mCurrentTime); prevWord = word; assertTrue(dict.isInUnderlyingBinaryDictionaryForTests(word)); }