Loading java/src/com/android/inputmethod/latin/DictionaryFacilitator.java +13 −0 Original line number Diff line number Diff line Loading @@ -17,6 +17,7 @@ package com.android.inputmethod.latin; import android.content.Context; import android.util.LruCache; import com.android.inputmethod.annotations.UsedForTesting; import com.android.inputmethod.keyboard.Keyboard; Loading Loading @@ -54,6 +55,18 @@ public interface DictionaryFacilitator { Dictionary.TYPE_USER_HISTORY, Dictionary.TYPE_USER}; /** * The facilitator will put words into the cache whenever it decodes them. * @param cache */ void setValidSpellingWordReadCache(final LruCache<String, Boolean> cache); /** * The facilitator will get words from the cache whenever it needs to check their spelling. * @param cache */ void setValidSpellingWordWriteCache(final LruCache<String, Boolean> cache); /** * Returns whether this facilitator is exactly for this locale. * Loading java/src/com/android/inputmethod/latin/DictionaryFacilitatorImpl.java +40 −0 Original line number Diff line number Diff line Loading @@ -19,6 +19,7 @@ package com.android.inputmethod.latin; import android.content.Context; import android.text.TextUtils; import android.util.Log; import android.util.LruCache; import com.android.inputmethod.annotations.UsedForTesting; import com.android.inputmethod.keyboard.Keyboard; Loading Loading @@ -82,6 +83,19 @@ public class DictionaryFacilitatorImpl implements DictionaryFacilitator { private static final Class<?>[] DICT_FACTORY_METHOD_ARG_TYPES = new Class[] { Context.class, Locale.class, File.class, String.class, String.class }; private LruCache<String, Boolean> mValidSpellingWordReadCache; private LruCache<String, Boolean> mValidSpellingWordWriteCache; @Override public void setValidSpellingWordReadCache(final LruCache<String, Boolean> cache) { mValidSpellingWordReadCache = cache; } @Override public void setValidSpellingWordWriteCache(final LruCache<String, Boolean> cache) { mValidSpellingWordWriteCache = cache; } @Override public boolean isForLocale(final Locale locale) { return locale != null && locale.equals(mDictionaryGroup.mLocale); Loading Loading @@ -341,6 +355,10 @@ public class DictionaryFacilitatorImpl implements DictionaryFacilitator { dictionarySetToCleanup.closeDict(dictType); } } if (mValidSpellingWordWriteCache != null) { mValidSpellingWordWriteCache.evictAll(); } } private void asyncReloadUninitializedMainDictionaries(final Context context, Loading Loading @@ -464,6 +482,10 @@ public class DictionaryFacilitatorImpl implements DictionaryFacilitator { public void addToUserHistory(final String suggestion, final boolean wasAutoCapitalized, @Nonnull final NgramContext ngramContext, final long timeStampInSeconds, final boolean blockPotentiallyOffensive) { // Update the spelling cache before learning. Words that are not yet added to user history // and appear in no other language model are not considered valid. putWordIntoValidSpellingWordCache("addToUserHistory", suggestion); final String[] words = suggestion.split(Constants.WORD_SEPARATOR); NgramContext ngramContextForCurrentWord = ngramContext; for (int i = 0; i < words.length; i++) { Loading @@ -477,6 +499,12 @@ public class DictionaryFacilitatorImpl implements DictionaryFacilitator { } } private void putWordIntoValidSpellingWordCache(final String caller, final String word) { final String spellingWord = word.toLowerCase(getLocale()); final boolean isValid = isValidSpellingWord(spellingWord); mValidSpellingWordWriteCache.put(spellingWord, isValid); } private void addWordToUserHistory(final DictionaryGroup dictionaryGroup, final NgramContext ngramContext, final String word, final boolean wasAutoCapitalized, final int timeStampInSeconds, final boolean blockPotentiallyOffensive) { Loading Loading @@ -543,6 +571,10 @@ public class DictionaryFacilitatorImpl implements DictionaryFacilitator { if (eventType != Constants.EVENT_BACKSPACE) { removeWord(Dictionary.TYPE_USER_HISTORY, word); } // Update the spelling cache after unlearning. Words that are removed from user history // and appear in no other language model are not considered valid. putWordIntoValidSpellingWordCache("unlearnFromUserHistory", word.toLowerCase()); } // TODO: Revise the way to fusion suggestion results. Loading Loading @@ -577,6 +609,14 @@ public class DictionaryFacilitatorImpl implements DictionaryFacilitator { } public boolean isValidSpellingWord(final String word) { if (mValidSpellingWordReadCache != null) { final String spellingWord = word.toLowerCase(getLocale()); final Boolean cachedValue = mValidSpellingWordReadCache.get(spellingWord); if (cachedValue != null) { return cachedValue; } } return isValidWord(word, ALL_DICTIONARY_TYPES); } Loading java/src/com/android/inputmethod/latin/spellcheck/AndroidSpellCheckerSession.java +1 −2 Original line number Diff line number Diff line Loading @@ -84,8 +84,7 @@ public final class AndroidSpellCheckerSession extends AndroidWordLevelSpellCheck if (TextUtils.isEmpty(splitText)) { continue; } if (mSuggestionsCache.getSuggestionsFromCache(splitText.toString(), ngramContext) == null) { if (mSuggestionsCache.getSuggestionsFromCache(splitText.toString()) == null) { continue; } final int newLength = splitText.length(); Loading java/src/com/android/inputmethod/latin/spellcheck/AndroidWordLevelSpellCheckerSession.java +9 −23 Original line number Diff line number Diff line Loading @@ -71,30 +71,26 @@ public abstract class AndroidWordLevelSpellCheckerSession extends Session { } protected static final class SuggestionsCache { private static final char CHAR_DELIMITER = '\uFFFC'; private static final int MAX_CACHE_SIZE = 50; private final LruCache<String, SuggestionsParams> mUnigramSuggestionsInfoCache = new LruCache<>(MAX_CACHE_SIZE); private static String generateKey(final String query, final NgramContext ngramContext) { if (TextUtils.isEmpty(query) || !ngramContext.isValid()) { return query; } return query + CHAR_DELIMITER + ngramContext; private static String generateKey(final String query) { return query + ""; } public SuggestionsParams getSuggestionsFromCache(String query, final NgramContext ngramContext) { return mUnigramSuggestionsInfoCache.get(generateKey(query, ngramContext)); public SuggestionsParams getSuggestionsFromCache(final String query) { return mUnigramSuggestionsInfoCache.get(query); } public void putSuggestionsToCache(final String query, final NgramContext ngramContext, final String[] suggestions, final int flags) { public void putSuggestionsToCache( final String query, final String[] suggestions, final int flags) { if (suggestions == null || TextUtils.isEmpty(query)) { return; } mUnigramSuggestionsInfoCache.put( generateKey(query, ngramContext), new SuggestionsParams(suggestions, flags)); generateKey(query), new SuggestionsParams(suggestions, flags)); } public void clearCache() { Loading Loading @@ -232,16 +228,7 @@ public abstract class AndroidWordLevelSpellCheckerSession extends Session { AndroidSpellCheckerService.SINGLE_QUOTE). replaceAll("^" + quotesRegexp, ""). replaceAll(quotesRegexp + "$", ""); final SuggestionsParams cachedSuggestionsParams = mSuggestionsCache.getSuggestionsFromCache(text, ngramContext); if (cachedSuggestionsParams != null) { Log.d(TAG, "onGetSuggestionsInternal() : Cache hit for [" + text + "]"); return new SuggestionsInfo( cachedSuggestionsParams.mFlags, cachedSuggestionsParams.mSuggestions); } // If spell checking is impossible, return early. if (!mService.hasMainDictionaryForLocale(mLocale)) { return AndroidSpellCheckerService.getNotInDictEmptySuggestions( false /* reportAsTypo */); Loading Loading @@ -329,8 +316,7 @@ public abstract class AndroidWordLevelSpellCheckerSession extends Session { .getValueOf_RESULT_ATTR_HAS_RECOMMENDED_SUGGESTIONS() : 0); final SuggestionsInfo retval = new SuggestionsInfo(flags, result.mSuggestions); mSuggestionsCache.putSuggestionsToCache(text, ngramContext, result.mSuggestions, flags); mSuggestionsCache.putSuggestionsToCache(text, result.mSuggestions, flags); return retval; } catch (RuntimeException e) { // Don't kill the keyboard if there is a bug in the spell checker Loading Loading
java/src/com/android/inputmethod/latin/DictionaryFacilitator.java +13 −0 Original line number Diff line number Diff line Loading @@ -17,6 +17,7 @@ package com.android.inputmethod.latin; import android.content.Context; import android.util.LruCache; import com.android.inputmethod.annotations.UsedForTesting; import com.android.inputmethod.keyboard.Keyboard; Loading Loading @@ -54,6 +55,18 @@ public interface DictionaryFacilitator { Dictionary.TYPE_USER_HISTORY, Dictionary.TYPE_USER}; /** * The facilitator will put words into the cache whenever it decodes them. * @param cache */ void setValidSpellingWordReadCache(final LruCache<String, Boolean> cache); /** * The facilitator will get words from the cache whenever it needs to check their spelling. * @param cache */ void setValidSpellingWordWriteCache(final LruCache<String, Boolean> cache); /** * Returns whether this facilitator is exactly for this locale. * Loading
java/src/com/android/inputmethod/latin/DictionaryFacilitatorImpl.java +40 −0 Original line number Diff line number Diff line Loading @@ -19,6 +19,7 @@ package com.android.inputmethod.latin; import android.content.Context; import android.text.TextUtils; import android.util.Log; import android.util.LruCache; import com.android.inputmethod.annotations.UsedForTesting; import com.android.inputmethod.keyboard.Keyboard; Loading Loading @@ -82,6 +83,19 @@ public class DictionaryFacilitatorImpl implements DictionaryFacilitator { private static final Class<?>[] DICT_FACTORY_METHOD_ARG_TYPES = new Class[] { Context.class, Locale.class, File.class, String.class, String.class }; private LruCache<String, Boolean> mValidSpellingWordReadCache; private LruCache<String, Boolean> mValidSpellingWordWriteCache; @Override public void setValidSpellingWordReadCache(final LruCache<String, Boolean> cache) { mValidSpellingWordReadCache = cache; } @Override public void setValidSpellingWordWriteCache(final LruCache<String, Boolean> cache) { mValidSpellingWordWriteCache = cache; } @Override public boolean isForLocale(final Locale locale) { return locale != null && locale.equals(mDictionaryGroup.mLocale); Loading Loading @@ -341,6 +355,10 @@ public class DictionaryFacilitatorImpl implements DictionaryFacilitator { dictionarySetToCleanup.closeDict(dictType); } } if (mValidSpellingWordWriteCache != null) { mValidSpellingWordWriteCache.evictAll(); } } private void asyncReloadUninitializedMainDictionaries(final Context context, Loading Loading @@ -464,6 +482,10 @@ public class DictionaryFacilitatorImpl implements DictionaryFacilitator { public void addToUserHistory(final String suggestion, final boolean wasAutoCapitalized, @Nonnull final NgramContext ngramContext, final long timeStampInSeconds, final boolean blockPotentiallyOffensive) { // Update the spelling cache before learning. Words that are not yet added to user history // and appear in no other language model are not considered valid. putWordIntoValidSpellingWordCache("addToUserHistory", suggestion); final String[] words = suggestion.split(Constants.WORD_SEPARATOR); NgramContext ngramContextForCurrentWord = ngramContext; for (int i = 0; i < words.length; i++) { Loading @@ -477,6 +499,12 @@ public class DictionaryFacilitatorImpl implements DictionaryFacilitator { } } private void putWordIntoValidSpellingWordCache(final String caller, final String word) { final String spellingWord = word.toLowerCase(getLocale()); final boolean isValid = isValidSpellingWord(spellingWord); mValidSpellingWordWriteCache.put(spellingWord, isValid); } private void addWordToUserHistory(final DictionaryGroup dictionaryGroup, final NgramContext ngramContext, final String word, final boolean wasAutoCapitalized, final int timeStampInSeconds, final boolean blockPotentiallyOffensive) { Loading Loading @@ -543,6 +571,10 @@ public class DictionaryFacilitatorImpl implements DictionaryFacilitator { if (eventType != Constants.EVENT_BACKSPACE) { removeWord(Dictionary.TYPE_USER_HISTORY, word); } // Update the spelling cache after unlearning. Words that are removed from user history // and appear in no other language model are not considered valid. putWordIntoValidSpellingWordCache("unlearnFromUserHistory", word.toLowerCase()); } // TODO: Revise the way to fusion suggestion results. Loading Loading @@ -577,6 +609,14 @@ public class DictionaryFacilitatorImpl implements DictionaryFacilitator { } public boolean isValidSpellingWord(final String word) { if (mValidSpellingWordReadCache != null) { final String spellingWord = word.toLowerCase(getLocale()); final Boolean cachedValue = mValidSpellingWordReadCache.get(spellingWord); if (cachedValue != null) { return cachedValue; } } return isValidWord(word, ALL_DICTIONARY_TYPES); } Loading
java/src/com/android/inputmethod/latin/spellcheck/AndroidSpellCheckerSession.java +1 −2 Original line number Diff line number Diff line Loading @@ -84,8 +84,7 @@ public final class AndroidSpellCheckerSession extends AndroidWordLevelSpellCheck if (TextUtils.isEmpty(splitText)) { continue; } if (mSuggestionsCache.getSuggestionsFromCache(splitText.toString(), ngramContext) == null) { if (mSuggestionsCache.getSuggestionsFromCache(splitText.toString()) == null) { continue; } final int newLength = splitText.length(); Loading
java/src/com/android/inputmethod/latin/spellcheck/AndroidWordLevelSpellCheckerSession.java +9 −23 Original line number Diff line number Diff line Loading @@ -71,30 +71,26 @@ public abstract class AndroidWordLevelSpellCheckerSession extends Session { } protected static final class SuggestionsCache { private static final char CHAR_DELIMITER = '\uFFFC'; private static final int MAX_CACHE_SIZE = 50; private final LruCache<String, SuggestionsParams> mUnigramSuggestionsInfoCache = new LruCache<>(MAX_CACHE_SIZE); private static String generateKey(final String query, final NgramContext ngramContext) { if (TextUtils.isEmpty(query) || !ngramContext.isValid()) { return query; } return query + CHAR_DELIMITER + ngramContext; private static String generateKey(final String query) { return query + ""; } public SuggestionsParams getSuggestionsFromCache(String query, final NgramContext ngramContext) { return mUnigramSuggestionsInfoCache.get(generateKey(query, ngramContext)); public SuggestionsParams getSuggestionsFromCache(final String query) { return mUnigramSuggestionsInfoCache.get(query); } public void putSuggestionsToCache(final String query, final NgramContext ngramContext, final String[] suggestions, final int flags) { public void putSuggestionsToCache( final String query, final String[] suggestions, final int flags) { if (suggestions == null || TextUtils.isEmpty(query)) { return; } mUnigramSuggestionsInfoCache.put( generateKey(query, ngramContext), new SuggestionsParams(suggestions, flags)); generateKey(query), new SuggestionsParams(suggestions, flags)); } public void clearCache() { Loading Loading @@ -232,16 +228,7 @@ public abstract class AndroidWordLevelSpellCheckerSession extends Session { AndroidSpellCheckerService.SINGLE_QUOTE). replaceAll("^" + quotesRegexp, ""). replaceAll(quotesRegexp + "$", ""); final SuggestionsParams cachedSuggestionsParams = mSuggestionsCache.getSuggestionsFromCache(text, ngramContext); if (cachedSuggestionsParams != null) { Log.d(TAG, "onGetSuggestionsInternal() : Cache hit for [" + text + "]"); return new SuggestionsInfo( cachedSuggestionsParams.mFlags, cachedSuggestionsParams.mSuggestions); } // If spell checking is impossible, return early. if (!mService.hasMainDictionaryForLocale(mLocale)) { return AndroidSpellCheckerService.getNotInDictEmptySuggestions( false /* reportAsTypo */); Loading Loading @@ -329,8 +316,7 @@ public abstract class AndroidWordLevelSpellCheckerSession extends Session { .getValueOf_RESULT_ATTR_HAS_RECOMMENDED_SUGGESTIONS() : 0); final SuggestionsInfo retval = new SuggestionsInfo(flags, result.mSuggestions); mSuggestionsCache.putSuggestionsToCache(text, ngramContext, result.mSuggestions, flags); mSuggestionsCache.putSuggestionsToCache(text, result.mSuggestions, flags); return retval; } catch (RuntimeException e) { // Don't kill the keyboard if there is a bug in the spell checker Loading