add cache for next word suggestions

This commit is contained in:
Helium314 2023-11-30 12:46:26 +01:00
parent 108ee5476a
commit 7397deac57
2 changed files with 42 additions and 15 deletions

View file

@ -660,6 +660,7 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
resetDictionaryFacilitatorIfNecessary(); resetDictionaryFacilitatorIfNecessary();
} }
refreshPersonalizationDictionarySession(currentSettingsValues); refreshPersonalizationDictionarySession(currentSettingsValues);
Suggest.nextWordSuggestionsCache.clear();
mStatsUtilsManager.onLoadSettings(this /* context */, currentSettingsValues); mStatsUtilsManager.onLoadSettings(this /* context */, currentSettingsValues);
} }

View file

@ -33,6 +33,8 @@ import static org.dslul.openboard.inputmethod.latin.define.DecoderSpecificConsta
import androidx.annotation.NonNull; import androidx.annotation.NonNull;
import kotlin.collections.CollectionsKt;
/** /**
* This class loads a dictionary and provides a list of suggestions for a given sequence of * This class loads a dictionary and provides a list of suggestions for a given sequence of
* characters. This includes corrections and completions. * characters. This includes corrections and completions.
@ -61,6 +63,9 @@ public final class Suggest {
MAXIMUM_AUTO_CORRECT_LENGTH_FOR_GERMAN); MAXIMUM_AUTO_CORRECT_LENGTH_FOR_GERMAN);
} }
// cleared whenever LatinIME.loadSettings is called, notably on changing layout and switching input fields
public static final HashMap<NgramContext, SuggestionResults> nextWordSuggestionsCache = new HashMap<>();
private float mAutoCorrectionThreshold; private float mAutoCorrectionThreshold;
private float mPlausibilityThreshold; private float mPlausibilityThreshold;
@ -144,9 +149,11 @@ public final class Suggest {
final int trailingSingleQuotesCount = final int trailingSingleQuotesCount =
StringUtils.getTrailingSingleQuotesCount(typedWordString); StringUtils.getTrailingSingleQuotesCount(typedWordString);
final SuggestionResults suggestionResults = mDictionaryFacilitator.getSuggestionResults( final SuggestionResults suggestionResults = typedWordString.isEmpty()
wordComposer.getComposedDataSnapshot(), ngramContext, keyboard, ? getNextWordSuggestions(ngramContext, keyboard, inputStyleIfNotPrediction, settingsValuesForSuggestion)
settingsValuesForSuggestion, SESSION_ID_TYPING, inputStyleIfNotPrediction); : mDictionaryFacilitator.getSuggestionResults(
wordComposer.getComposedDataSnapshot(), ngramContext, keyboard,
settingsValuesForSuggestion, SESSION_ID_TYPING, inputStyleIfNotPrediction);
final Locale locale = mDictionaryFacilitator.getLocale(); final Locale locale = mDictionaryFacilitator.getLocale();
final ArrayList<SuggestedWordInfo> suggestionsContainer = final ArrayList<SuggestedWordInfo> suggestionsContainer =
getTransformedSuggestedWordInfoList(wordComposer, suggestionResults, getTransformedSuggestedWordInfoList(wordComposer, suggestionResults,
@ -249,6 +256,8 @@ public final class Suggest {
} }
// annoyingly complicated thing to avoid getting emptyWordSuggestions more than once // annoyingly complicated thing to avoid getting emptyWordSuggestions more than once
// todo: now with the cache just remove it...
// and best convert the class to kotlin, that should make it much more readable
/** puts word infos for suggestions with an empty word in [infos], based on previously typed words */ /** puts word infos for suggestions with an empty word in [infos], based on previously typed words */
private ArrayList<SuggestedWordInfo> putEmptyWordSuggestions(ArrayList<SuggestedWordInfo> infos, NgramContext ngramContext, private ArrayList<SuggestedWordInfo> putEmptyWordSuggestions(ArrayList<SuggestedWordInfo> infos, NgramContext ngramContext,
Keyboard keyboard, SettingsValuesForSuggestion settingsValuesForSuggestion, Keyboard keyboard, SettingsValuesForSuggestion settingsValuesForSuggestion,
@ -256,17 +265,13 @@ public final class Suggest {
if (infos.size() != 0) return infos; if (infos.size() != 0) return infos;
infos.add(null); infos.add(null);
infos.add(null); infos.add(null);
final SuggestionResults emptyWordSuggestions = mDictionaryFacilitator.getSuggestionResults( final SuggestionResults emptyWordSuggestions = getNextWordSuggestions(ngramContext, keyboard, inputStyleIfNotPrediction, settingsValuesForSuggestion);
new ComposedData(new InputPointers(1), false, ""), ngramContext, final SuggestedWordInfo nextWordSuggestionInfoForFirstSuggestionInContainer =
keyboard, settingsValuesForSuggestion, SESSION_ID_TYPING, inputStyleIfNotPrediction); CollectionsKt.firstOrNull(emptyWordSuggestions, (word) -> word.mWord.equals(firstSuggestionInContainer));
for (SuggestedWordInfo info : emptyWordSuggestions) { final SuggestedWordInfo nextWordSuggestionInfoForTypedWord =
if (infos.get(1) == null && typedWordString.equals(info.getWord())) { CollectionsKt.firstOrNull(emptyWordSuggestions, (word) -> word.mWord.equals(typedWordString));
infos.set(1, info); infos.add(nextWordSuggestionInfoForFirstSuggestionInContainer);
} else if (infos.get(0) == null && firstSuggestionInContainer.equals(info.getWord())) { infos.add(nextWordSuggestionInfoForTypedWord);
infos.set(0, info);
} else if (infos.get(1) != null && infos.get(0) != null)
break;
}
return infos; return infos;
} }
@ -560,4 +565,25 @@ public final class Suggest {
wordInfo.mSourceDict, wordInfo.mIndexOfTouchPointOfSecondWord, wordInfo.mSourceDict, wordInfo.mIndexOfTouchPointOfSecondWord,
wordInfo.mAutoCommitFirstWordConfidence); wordInfo.mAutoCommitFirstWordConfidence);
} }
/** get suggestions based on the current ngram context, with an empty typed word (that's what next word suggestions do) */
// todo: integrate it into shouldBeAutoCorrected, remove putEmptySuggestions
// and make that thing more readable
private SuggestionResults getNextWordSuggestions(final NgramContext ngramContext,
final Keyboard keyboard, final int inputStyle, final SettingsValuesForSuggestion settingsValuesForSuggestion
) {
final SuggestionResults cachedResults = nextWordSuggestionsCache.get(ngramContext);
if (cachedResults != null)
return cachedResults;
final SuggestionResults newResults = mDictionaryFacilitator.getSuggestionResults(
new ComposedData(new InputPointers(1), false, ""),
ngramContext,
keyboard,
settingsValuesForSuggestion,
SESSION_ID_TYPING,
inputStyle
);
nextWordSuggestionsCache.put(ngramContext, newResults);
return newResults;
}
} }