Merge "Rename PrevWordsInfo to NgramContext."

This commit is contained in:
Keisuke Kuroyanagi 2014-09-29 03:00:54 +00:00 committed by Android (Google) Code Review
commit a4a4e9d96b
33 changed files with 341 additions and 345 deletions

View file

@ -19,6 +19,6 @@
# to preserve changing those methods' signature. # to preserve changing those methods' signature.
-keep class com.android.inputmethod.latin.AssetFileAddress -keep class com.android.inputmethod.latin.AssetFileAddress
-keep class com.android.inputmethod.latin.Dictionary -keep class com.android.inputmethod.latin.Dictionary
-keep class com.android.inputmethod.latin.PrevWordsInfo -keep class com.android.inputmethod.latin.NgramContext
-keep class com.android.inputmethod.latin.makedict.ProbabilityInfo -keep class com.android.inputmethod.latin.makedict.ProbabilityInfo
-keep class com.android.inputmethod.latin.utils.LanguageModelParam -keep class com.android.inputmethod.latin.utils.LanguageModelParam

View file

@ -255,7 +255,7 @@ public final class BinaryDictionary extends Dictionary {
@Override @Override
public ArrayList<SuggestedWordInfo> getSuggestions(final WordComposer composer, public ArrayList<SuggestedWordInfo> getSuggestions(final WordComposer composer,
final PrevWordsInfo prevWordsInfo, final ProximityInfo proximityInfo, final NgramContext ngramContext, final ProximityInfo proximityInfo,
final SettingsValuesForSuggestion settingsValuesForSuggestion, final SettingsValuesForSuggestion settingsValuesForSuggestion,
final int sessionId, final float weightForLocale, final int sessionId, final float weightForLocale,
final float[] inOutWeightOfLangModelVsSpatialModel) { final float[] inOutWeightOfLangModelVsSpatialModel) {
@ -264,7 +264,7 @@ public final class BinaryDictionary extends Dictionary {
} }
final DicTraverseSession session = getTraverseSession(sessionId); final DicTraverseSession session = getTraverseSession(sessionId);
Arrays.fill(session.mInputCodePoints, Constants.NOT_A_CODE); Arrays.fill(session.mInputCodePoints, Constants.NOT_A_CODE);
prevWordsInfo.outputToArray(session.mPrevWordCodePointArrays, ngramContext.outputToArray(session.mPrevWordCodePointArrays,
session.mIsBeginningOfSentenceArray); session.mIsBeginningOfSentenceArray);
final InputPointers inputPointers = composer.getInputPointers(); final InputPointers inputPointers = composer.getInputPointers();
final boolean isGesture = composer.isBatchMode(); final boolean isGesture = composer.isBatchMode();
@ -299,7 +299,7 @@ public final class BinaryDictionary extends Dictionary {
inputPointers.getYCoordinates(), inputPointers.getTimes(), inputPointers.getYCoordinates(), inputPointers.getTimes(),
inputPointers.getPointerIds(), session.mInputCodePoints, inputSize, inputPointers.getPointerIds(), session.mInputCodePoints, inputSize,
session.mNativeSuggestOptions.getOptions(), session.mPrevWordCodePointArrays, session.mNativeSuggestOptions.getOptions(), session.mPrevWordCodePointArrays,
session.mIsBeginningOfSentenceArray, prevWordsInfo.getPrevWordCount(), session.mIsBeginningOfSentenceArray, ngramContext.getPrevWordCount(),
session.mOutputSuggestionCount, session.mOutputCodePoints, session.mOutputScores, session.mOutputSuggestionCount, session.mOutputCodePoints, session.mOutputScores,
session.mSpaceIndices, session.mOutputTypes, session.mSpaceIndices, session.mOutputTypes,
session.mOutputAutoCommitFirstWordConfidence, session.mOutputAutoCommitFirstWordConfidence,
@ -357,17 +357,17 @@ public final class BinaryDictionary extends Dictionary {
} }
@UsedForTesting @UsedForTesting
public boolean isValidNgram(final PrevWordsInfo prevWordsInfo, final String word) { public boolean isValidNgram(final NgramContext ngramContext, final String word) {
return getNgramProbability(prevWordsInfo, word) != NOT_A_PROBABILITY; return getNgramProbability(ngramContext, word) != NOT_A_PROBABILITY;
} }
public int getNgramProbability(final PrevWordsInfo prevWordsInfo, final String word) { public int getNgramProbability(final NgramContext ngramContext, final String word) {
if (!prevWordsInfo.isValid() || TextUtils.isEmpty(word)) { if (!ngramContext.isValid() || TextUtils.isEmpty(word)) {
return NOT_A_PROBABILITY; return NOT_A_PROBABILITY;
} }
final int[][] prevWordCodePointArrays = new int[prevWordsInfo.getPrevWordCount()][]; final int[][] prevWordCodePointArrays = new int[ngramContext.getPrevWordCount()][];
final boolean[] isBeginningOfSentenceArray = new boolean[prevWordsInfo.getPrevWordCount()]; final boolean[] isBeginningOfSentenceArray = new boolean[ngramContext.getPrevWordCount()];
prevWordsInfo.outputToArray(prevWordCodePointArrays, isBeginningOfSentenceArray); ngramContext.outputToArray(prevWordCodePointArrays, isBeginningOfSentenceArray);
final int[] wordCodePoints = StringUtils.toCodePointArray(word); final int[] wordCodePoints = StringUtils.toCodePointArray(word);
return getNgramProbabilityNative(mNativeDict, prevWordCodePointArrays, return getNgramProbabilityNative(mNativeDict, prevWordCodePointArrays,
isBeginningOfSentenceArray, wordCodePoints); isBeginningOfSentenceArray, wordCodePoints);
@ -456,14 +456,14 @@ public final class BinaryDictionary extends Dictionary {
} }
// Add an n-gram entry to the binary dictionary with timestamp in native code. // Add an n-gram entry to the binary dictionary with timestamp in native code.
public boolean addNgramEntry(final PrevWordsInfo prevWordsInfo, final String word, public boolean addNgramEntry(final NgramContext ngramContext, final String word,
final int probability, final int timestamp) { final int probability, final int timestamp) {
if (!prevWordsInfo.isValid() || TextUtils.isEmpty(word)) { if (!ngramContext.isValid() || TextUtils.isEmpty(word)) {
return false; return false;
} }
final int[][] prevWordCodePointArrays = new int[prevWordsInfo.getPrevWordCount()][]; final int[][] prevWordCodePointArrays = new int[ngramContext.getPrevWordCount()][];
final boolean[] isBeginningOfSentenceArray = new boolean[prevWordsInfo.getPrevWordCount()]; final boolean[] isBeginningOfSentenceArray = new boolean[ngramContext.getPrevWordCount()];
prevWordsInfo.outputToArray(prevWordCodePointArrays, isBeginningOfSentenceArray); ngramContext.outputToArray(prevWordCodePointArrays, isBeginningOfSentenceArray);
final int[] wordCodePoints = StringUtils.toCodePointArray(word); final int[] wordCodePoints = StringUtils.toCodePointArray(word);
if (!addNgramEntryNative(mNativeDict, prevWordCodePointArrays, if (!addNgramEntryNative(mNativeDict, prevWordCodePointArrays,
isBeginningOfSentenceArray, wordCodePoints, probability, timestamp)) { isBeginningOfSentenceArray, wordCodePoints, probability, timestamp)) {
@ -474,13 +474,13 @@ public final class BinaryDictionary extends Dictionary {
} }
// Remove an n-gram entry from the binary dictionary in native code. // Remove an n-gram entry from the binary dictionary in native code.
public boolean removeNgramEntry(final PrevWordsInfo prevWordsInfo, final String word) { public boolean removeNgramEntry(final NgramContext ngramContext, final String word) {
if (!prevWordsInfo.isValid() || TextUtils.isEmpty(word)) { if (!ngramContext.isValid() || TextUtils.isEmpty(word)) {
return false; return false;
} }
final int[][] prevWordCodePointArrays = new int[prevWordsInfo.getPrevWordCount()][]; final int[][] prevWordCodePointArrays = new int[ngramContext.getPrevWordCount()][];
final boolean[] isBeginningOfSentenceArray = new boolean[prevWordsInfo.getPrevWordCount()]; final boolean[] isBeginningOfSentenceArray = new boolean[ngramContext.getPrevWordCount()];
prevWordsInfo.outputToArray(prevWordCodePointArrays, isBeginningOfSentenceArray); ngramContext.outputToArray(prevWordCodePointArrays, isBeginningOfSentenceArray);
final int[] wordCodePoints = StringUtils.toCodePointArray(word); final int[] wordCodePoints = StringUtils.toCodePointArray(word);
if (!removeNgramEntryNative(mNativeDict, prevWordCodePointArrays, if (!removeNgramEntryNative(mNativeDict, prevWordCodePointArrays,
isBeginningOfSentenceArray, wordCodePoints)) { isBeginningOfSentenceArray, wordCodePoints)) {

View file

@ -218,7 +218,7 @@ public class ContactsBinaryDictionary extends ExpandableBinaryDictionary {
*/ */
private void addNameLocked(final String name) { private void addNameLocked(final String name) {
int len = StringUtils.codePointCount(name); int len = StringUtils.codePointCount(name);
PrevWordsInfo prevWordsInfo = PrevWordsInfo.EMPTY_PREV_WORDS_INFO; NgramContext ngramContext = NgramContext.EMPTY_PREV_WORDS_INFO;
// TODO: Better tokenization for non-Latin writing systems // TODO: Better tokenization for non-Latin writing systems
for (int i = 0; i < len; i++) { for (int i = 0; i < len; i++) {
if (Character.isLetter(name.codePointAt(i))) { if (Character.isLetter(name.codePointAt(i))) {
@ -233,19 +233,19 @@ public class ContactsBinaryDictionary extends ExpandableBinaryDictionary {
final int wordLen = StringUtils.codePointCount(word); final int wordLen = StringUtils.codePointCount(word);
if (wordLen <= MAX_WORD_LENGTH && wordLen > 1) { if (wordLen <= MAX_WORD_LENGTH && wordLen > 1) {
if (DEBUG) { if (DEBUG) {
Log.d(TAG, "addName " + name + ", " + word + ", " + prevWordsInfo); Log.d(TAG, "addName " + name + ", " + word + ", " + ngramContext);
} }
runGCIfRequiredLocked(true /* mindsBlockByGC */); runGCIfRequiredLocked(true /* mindsBlockByGC */);
addUnigramLocked(word, FREQUENCY_FOR_CONTACTS, addUnigramLocked(word, FREQUENCY_FOR_CONTACTS,
null /* shortcut */, 0 /* shortcutFreq */, false /* isNotAWord */, null /* shortcut */, 0 /* shortcutFreq */, false /* isNotAWord */,
false /* isBlacklisted */, BinaryDictionary.NOT_A_VALID_TIMESTAMP); false /* isBlacklisted */, BinaryDictionary.NOT_A_VALID_TIMESTAMP);
if (!prevWordsInfo.isValid() && mUseFirstLastBigrams) { if (!ngramContext.isValid() && mUseFirstLastBigrams) {
runGCIfRequiredLocked(true /* mindsBlockByGC */); runGCIfRequiredLocked(true /* mindsBlockByGC */);
addNgramEntryLocked(prevWordsInfo, word, FREQUENCY_FOR_CONTACTS_BIGRAM, addNgramEntryLocked(ngramContext, word, FREQUENCY_FOR_CONTACTS_BIGRAM,
BinaryDictionary.NOT_A_VALID_TIMESTAMP); BinaryDictionary.NOT_A_VALID_TIMESTAMP);
} }
prevWordsInfo = prevWordsInfo.getNextPrevWordsInfo( ngramContext = ngramContext.getNextNgramContext(
new PrevWordsInfo.WordInfo(word)); new NgramContext.WordInfo(word));
} }
} }
} }

View file

@ -81,10 +81,9 @@ public abstract class Dictionary {
} }
/** /**
* Searches for suggestions for a given context. For the moment the context is only the * Searches for suggestions for a given context.
* previous word.
* @param composer the key sequence to match with coordinate info, as a WordComposer * @param composer the key sequence to match with coordinate info, as a WordComposer
* @param prevWordsInfo the information of previous words. * @param ngramContext the context for n-gram.
* @param proximityInfo the object for key proximity. May be ignored by some implementations. * @param proximityInfo the object for key proximity. May be ignored by some implementations.
* @param settingsValuesForSuggestion the settings values used for the suggestion. * @param settingsValuesForSuggestion the settings values used for the suggestion.
* @param sessionId the session id. * @param sessionId the session id.
@ -96,7 +95,7 @@ public abstract class Dictionary {
* @return the list of suggestions (possibly null if none) * @return the list of suggestions (possibly null if none)
*/ */
abstract public ArrayList<SuggestedWordInfo> getSuggestions(final WordComposer composer, abstract public ArrayList<SuggestedWordInfo> getSuggestions(final WordComposer composer,
final PrevWordsInfo prevWordsInfo, final ProximityInfo proximityInfo, final NgramContext ngramContext, final ProximityInfo proximityInfo,
final SettingsValuesForSuggestion settingsValuesForSuggestion, final SettingsValuesForSuggestion settingsValuesForSuggestion,
final int sessionId, final float weightForLocale, final int sessionId, final float weightForLocale,
final float[] inOutWeightOfLangModelVsSpatialModel); final float[] inOutWeightOfLangModelVsSpatialModel);
@ -191,7 +190,7 @@ public abstract class Dictionary {
@Override @Override
public ArrayList<SuggestedWordInfo> getSuggestions(final WordComposer composer, public ArrayList<SuggestedWordInfo> getSuggestions(final WordComposer composer,
final PrevWordsInfo prevWordsInfo, final ProximityInfo proximityInfo, final NgramContext ngramContext, final ProximityInfo proximityInfo,
final SettingsValuesForSuggestion settingsValuesForSuggestion, final SettingsValuesForSuggestion settingsValuesForSuggestion,
final int sessionId, final float weightForLocale, final int sessionId, final float weightForLocale,
final float[] inOutWeightOfLangModelVsSpatialModel) { final float[] inOutWeightOfLangModelVsSpatialModel) {

View file

@ -60,7 +60,7 @@ public final class DictionaryCollection extends Dictionary {
@Override @Override
public ArrayList<SuggestedWordInfo> getSuggestions(final WordComposer composer, public ArrayList<SuggestedWordInfo> getSuggestions(final WordComposer composer,
final PrevWordsInfo prevWordsInfo, final ProximityInfo proximityInfo, final NgramContext ngramContext, final ProximityInfo proximityInfo,
final SettingsValuesForSuggestion settingsValuesForSuggestion, final SettingsValuesForSuggestion settingsValuesForSuggestion,
final int sessionId, final float weightForLocale, final int sessionId, final float weightForLocale,
final float[] inOutWeightOfLangModelVsSpatialModel) { final float[] inOutWeightOfLangModelVsSpatialModel) {
@ -69,13 +69,13 @@ public final class DictionaryCollection extends Dictionary {
// To avoid creating unnecessary objects, we get the list out of the first // To avoid creating unnecessary objects, we get the list out of the first
// dictionary and add the rest to it if not null, hence the get(0) // dictionary and add the rest to it if not null, hence the get(0)
ArrayList<SuggestedWordInfo> suggestions = dictionaries.get(0).getSuggestions(composer, ArrayList<SuggestedWordInfo> suggestions = dictionaries.get(0).getSuggestions(composer,
prevWordsInfo, proximityInfo, settingsValuesForSuggestion, sessionId, ngramContext, proximityInfo, settingsValuesForSuggestion, sessionId,
weightForLocale, inOutWeightOfLangModelVsSpatialModel); weightForLocale, inOutWeightOfLangModelVsSpatialModel);
if (null == suggestions) suggestions = new ArrayList<>(); if (null == suggestions) suggestions = new ArrayList<>();
final int length = dictionaries.size(); final int length = dictionaries.size();
for (int i = 1; i < length; ++ i) { for (int i = 1; i < length; ++ i) {
final ArrayList<SuggestedWordInfo> sugg = dictionaries.get(i).getSuggestions(composer, final ArrayList<SuggestedWordInfo> sugg = dictionaries.get(i).getSuggestions(composer,
prevWordsInfo, proximityInfo, settingsValuesForSuggestion, sessionId, ngramContext, proximityInfo, settingsValuesForSuggestion, sessionId,
weightForLocale, inOutWeightOfLangModelVsSpatialModel); weightForLocale, inOutWeightOfLangModelVsSpatialModel);
if (null != sugg) suggestions.addAll(sugg); if (null != sugg) suggestions.addAll(sugg);
} }

View file

@ -25,7 +25,7 @@ import android.view.inputmethod.InputMethodSubtype;
import com.android.inputmethod.annotations.UsedForTesting; import com.android.inputmethod.annotations.UsedForTesting;
import com.android.inputmethod.keyboard.ProximityInfo; import com.android.inputmethod.keyboard.ProximityInfo;
import com.android.inputmethod.latin.ExpandableBinaryDictionary.AddMultipleDictionaryEntriesCallback; import com.android.inputmethod.latin.ExpandableBinaryDictionary.AddMultipleDictionaryEntriesCallback;
import com.android.inputmethod.latin.PrevWordsInfo.WordInfo; import com.android.inputmethod.latin.NgramContext.WordInfo;
import com.android.inputmethod.latin.SuggestedWords.SuggestedWordInfo; import com.android.inputmethod.latin.SuggestedWords.SuggestedWordInfo;
import com.android.inputmethod.latin.personalization.ContextualDictionary; import com.android.inputmethod.latin.personalization.ContextualDictionary;
import com.android.inputmethod.latin.personalization.PersonalizationDataChunk; import com.android.inputmethod.latin.personalization.PersonalizationDataChunk;
@ -509,23 +509,23 @@ public class DictionaryFacilitator {
} }
public void addToUserHistory(final String suggestion, final boolean wasAutoCapitalized, public void addToUserHistory(final String suggestion, final boolean wasAutoCapitalized,
final PrevWordsInfo prevWordsInfo, final int timeStampInSeconds, final NgramContext ngramContext, final int timeStampInSeconds,
final boolean blockPotentiallyOffensive) { final boolean blockPotentiallyOffensive) {
final DictionaryGroup dictionaryGroup = getDictionaryGroupForActiveLanguage(); final DictionaryGroup dictionaryGroup = getDictionaryGroupForActiveLanguage();
final String[] words = suggestion.split(Constants.WORD_SEPARATOR); final String[] words = suggestion.split(Constants.WORD_SEPARATOR);
PrevWordsInfo prevWordsInfoForCurrentWord = prevWordsInfo; NgramContext ngramContextForCurrentWord = ngramContext;
for (int i = 0; i < words.length; i++) { for (int i = 0; i < words.length; i++) {
final String currentWord = words[i]; final String currentWord = words[i];
final boolean wasCurrentWordAutoCapitalized = (i == 0) ? wasAutoCapitalized : false; final boolean wasCurrentWordAutoCapitalized = (i == 0) ? wasAutoCapitalized : false;
addWordToUserHistory(dictionaryGroup, prevWordsInfoForCurrentWord, currentWord, addWordToUserHistory(dictionaryGroup, ngramContextForCurrentWord, currentWord,
wasCurrentWordAutoCapitalized, timeStampInSeconds, blockPotentiallyOffensive); wasCurrentWordAutoCapitalized, timeStampInSeconds, blockPotentiallyOffensive);
prevWordsInfoForCurrentWord = ngramContextForCurrentWord =
prevWordsInfoForCurrentWord.getNextPrevWordsInfo(new WordInfo(currentWord)); ngramContextForCurrentWord.getNextNgramContext(new WordInfo(currentWord));
} }
} }
private void addWordToUserHistory(final DictionaryGroup dictionaryGroup, private void addWordToUserHistory(final DictionaryGroup dictionaryGroup,
final PrevWordsInfo prevWordsInfo, final String word, final boolean wasAutoCapitalized, final NgramContext ngramContext, final String word, final boolean wasAutoCapitalized,
final int timeStampInSeconds, final boolean blockPotentiallyOffensive) { final int timeStampInSeconds, final boolean blockPotentiallyOffensive) {
final ExpandableBinaryDictionary userHistoryDictionary = final ExpandableBinaryDictionary userHistoryDictionary =
dictionaryGroup.getSubDict(Dictionary.TYPE_USER_HISTORY); dictionaryGroup.getSubDict(Dictionary.TYPE_USER_HISTORY);
@ -571,7 +571,7 @@ public class DictionaryFacilitator {
// We demote unrecognized words (frequency < 0, below) by specifying them as "invalid". // 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.). // We don't add words with 0-frequency (assuming they would be profanity etc.).
final boolean isValid = maxFreq > 0; final boolean isValid = maxFreq > 0;
UserHistoryDictionary.addToDictionary(userHistoryDictionary, prevWordsInfo, secondWord, UserHistoryDictionary.addToDictionary(userHistoryDictionary, ngramContext, secondWord,
isValid, timeStampInSeconds, isValid, timeStampInSeconds,
new DistracterFilterCheckingIsInDictionary( new DistracterFilterCheckingIsInDictionary(
mDistracterFilter, userHistoryDictionary)); mDistracterFilter, userHistoryDictionary));
@ -593,11 +593,11 @@ public class DictionaryFacilitator {
// TODO: Revise the way to fusion suggestion results. // TODO: Revise the way to fusion suggestion results.
public SuggestionResults getSuggestionResults(final WordComposer composer, public SuggestionResults getSuggestionResults(final WordComposer composer,
final PrevWordsInfo prevWordsInfo, final ProximityInfo proximityInfo, final NgramContext ngramContext, final ProximityInfo proximityInfo,
final SettingsValuesForSuggestion settingsValuesForSuggestion, final int sessionId) { final SettingsValuesForSuggestion settingsValuesForSuggestion, final int sessionId) {
final DictionaryGroup[] dictionaryGroups = mDictionaryGroups; final DictionaryGroup[] dictionaryGroups = mDictionaryGroups;
final SuggestionResults suggestionResults = new SuggestionResults( final SuggestionResults suggestionResults = new SuggestionResults(
SuggestedWords.MAX_SUGGESTIONS, prevWordsInfo.isBeginningOfSentenceContext()); SuggestedWords.MAX_SUGGESTIONS, ngramContext.isBeginningOfSentenceContext());
final float[] weightOfLangModelVsSpatialModel = final float[] weightOfLangModelVsSpatialModel =
new float[] { Dictionary.NOT_A_WEIGHT_OF_LANG_MODEL_VS_SPATIAL_MODEL }; new float[] { Dictionary.NOT_A_WEIGHT_OF_LANG_MODEL_VS_SPATIAL_MODEL };
for (final DictionaryGroup dictionaryGroup : dictionaryGroups) { for (final DictionaryGroup dictionaryGroup : dictionaryGroups) {
@ -605,7 +605,7 @@ public class DictionaryFacilitator {
final Dictionary dictionary = dictionaryGroup.getDict(dictType); final Dictionary dictionary = dictionaryGroup.getDict(dictType);
if (null == dictionary) continue; if (null == dictionary) continue;
final ArrayList<SuggestedWordInfo> dictionarySuggestions = final ArrayList<SuggestedWordInfo> dictionarySuggestions =
dictionary.getSuggestions(composer, prevWordsInfo, proximityInfo, dictionary.getSuggestions(composer, ngramContext, proximityInfo,
settingsValuesForSuggestion, sessionId, settingsValuesForSuggestion, sessionId,
dictionaryGroup.mWeightForLocale, weightOfLangModelVsSpatialModel); dictionaryGroup.mWeightForLocale, weightOfLangModelVsSpatialModel);
if (null == dictionarySuggestions) continue; if (null == dictionarySuggestions) continue;
@ -719,7 +719,7 @@ public class DictionaryFacilitator {
if (contextualDict == null) { if (contextualDict == null) {
return; return;
} }
PrevWordsInfo prevWordsInfo = PrevWordsInfo.BEGINNING_OF_SENTENCE; NgramContext ngramContext = NgramContext.BEGINNING_OF_SENTENCE;
for (int i = 0; i < phrase.length; i++) { for (int i = 0; i < phrase.length; i++) {
final String[] subPhrase = Arrays.copyOfRange(phrase, i /* start */, phrase.length); final String[] subPhrase = Arrays.copyOfRange(phrase, i /* start */, phrase.length);
final String subPhraseStr = TextUtils.join(Constants.WORD_SEPARATOR, subPhrase); final String subPhraseStr = TextUtils.join(Constants.WORD_SEPARATOR, subPhrase);
@ -729,7 +729,7 @@ public class DictionaryFacilitator {
false /* isNotAWord */, false /* isBlacklisted */, false /* isNotAWord */, false /* isBlacklisted */,
BinaryDictionary.NOT_A_VALID_TIMESTAMP, BinaryDictionary.NOT_A_VALID_TIMESTAMP,
DistracterFilter.EMPTY_DISTRACTER_FILTER); DistracterFilter.EMPTY_DISTRACTER_FILTER);
contextualDict.addNgramEntry(prevWordsInfo, subPhraseStr, contextualDict.addNgramEntry(ngramContext, subPhraseStr,
bigramProbabilityForPhrases, BinaryDictionary.NOT_A_VALID_TIMESTAMP); bigramProbabilityForPhrases, BinaryDictionary.NOT_A_VALID_TIMESTAMP);
if (i < phrase.length - 1) { if (i < phrase.length - 1) {
@ -739,11 +739,11 @@ public class DictionaryFacilitator {
false /* isNotAWord */, false /* isBlacklisted */, false /* isNotAWord */, false /* isBlacklisted */,
BinaryDictionary.NOT_A_VALID_TIMESTAMP, BinaryDictionary.NOT_A_VALID_TIMESTAMP,
DistracterFilter.EMPTY_DISTRACTER_FILTER); DistracterFilter.EMPTY_DISTRACTER_FILTER);
contextualDict.addNgramEntry(prevWordsInfo, phrase[i], contextualDict.addNgramEntry(ngramContext, phrase[i],
bigramProbabilityForWords, BinaryDictionary.NOT_A_VALID_TIMESTAMP); bigramProbabilityForWords, BinaryDictionary.NOT_A_VALID_TIMESTAMP);
} }
prevWordsInfo = ngramContext =
prevWordsInfo.getNextPrevWordsInfo(new PrevWordsInfo.WordInfo(phrase[i])); ngramContext.getNextNgramContext(new NgramContext.WordInfo(phrase[i]));
} }
} }

View file

@ -305,7 +305,7 @@ abstract public class ExpandableBinaryDictionary extends Dictionary {
@Override @Override
public Boolean call() throws Exception { public Boolean call() throws Exception {
return !distracterFilter.isDistracterToWordsInDictionaries( return !distracterFilter.isDistracterToWordsInDictionaries(
PrevWordsInfo.EMPTY_PREV_WORDS_INFO, word, mLocale); NgramContext.EMPTY_PREV_WORDS_INFO, word, mLocale);
} }
}, },
new Runnable() { new Runnable() {
@ -354,7 +354,7 @@ abstract public class ExpandableBinaryDictionary extends Dictionary {
/** /**
* Adds n-gram information of a word to the dictionary. May overwrite an existing entry. * Adds n-gram information of a word to the dictionary. May overwrite an existing entry.
*/ */
public void addNgramEntry(final PrevWordsInfo prevWordsInfo, final String word, public void addNgramEntry(final NgramContext ngramContext, final String word,
final int frequency, final int timestamp) { final int frequency, final int timestamp) {
reloadDictionaryIfRequired(); reloadDictionaryIfRequired();
asyncExecuteTaskWithWriteLock(new Runnable() { asyncExecuteTaskWithWriteLock(new Runnable() {
@ -364,17 +364,17 @@ abstract public class ExpandableBinaryDictionary extends Dictionary {
return; return;
} }
runGCIfRequiredLocked(true /* mindsBlockByGC */); runGCIfRequiredLocked(true /* mindsBlockByGC */);
addNgramEntryLocked(prevWordsInfo, word, frequency, timestamp); addNgramEntryLocked(ngramContext, word, frequency, timestamp);
} }
}); });
} }
protected void addNgramEntryLocked(final PrevWordsInfo prevWordsInfo, final String word, protected void addNgramEntryLocked(final NgramContext ngramContext, final String word,
final int frequency, final int timestamp) { final int frequency, final int timestamp) {
if (!mBinaryDictionary.addNgramEntry(prevWordsInfo, word, frequency, timestamp)) { if (!mBinaryDictionary.addNgramEntry(ngramContext, word, frequency, timestamp)) {
if (DEBUG) { if (DEBUG) {
Log.i(TAG, "Cannot add n-gram entry."); Log.i(TAG, "Cannot add n-gram entry.");
Log.i(TAG, " PrevWordsInfo: " + prevWordsInfo + ", word: " + word); Log.i(TAG, " NgramContext: " + ngramContext + ", word: " + word);
} }
} }
} }
@ -383,7 +383,7 @@ abstract public class ExpandableBinaryDictionary extends Dictionary {
* Dynamically remove the n-gram entry in the dictionary. * Dynamically remove the n-gram entry in the dictionary.
*/ */
@UsedForTesting @UsedForTesting
public void removeNgramDynamically(final PrevWordsInfo prevWordsInfo, final String word) { public void removeNgramDynamically(final NgramContext ngramContext, final String word) {
reloadDictionaryIfRequired(); reloadDictionaryIfRequired();
asyncExecuteTaskWithWriteLock(new Runnable() { asyncExecuteTaskWithWriteLock(new Runnable() {
@Override @Override
@ -392,10 +392,10 @@ abstract public class ExpandableBinaryDictionary extends Dictionary {
return; return;
} }
runGCIfRequiredLocked(true /* mindsBlockByGC */); runGCIfRequiredLocked(true /* mindsBlockByGC */);
if (!mBinaryDictionary.removeNgramEntry(prevWordsInfo, word)) { if (!mBinaryDictionary.removeNgramEntry(ngramContext, word)) {
if (DEBUG) { if (DEBUG) {
Log.i(TAG, "Cannot remove n-gram entry."); Log.i(TAG, "Cannot remove n-gram entry.");
Log.i(TAG, " PrevWordsInfo: " + prevWordsInfo + ", word: " + word); Log.i(TAG, " NgramContext: " + ngramContext + ", word: " + word);
} }
} }
} }
@ -434,7 +434,7 @@ abstract public class ExpandableBinaryDictionary extends Dictionary {
@Override @Override
public ArrayList<SuggestedWordInfo> getSuggestions(final WordComposer composer, public ArrayList<SuggestedWordInfo> getSuggestions(final WordComposer composer,
final PrevWordsInfo prevWordsInfo, final ProximityInfo proximityInfo, final NgramContext ngramContext, final ProximityInfo proximityInfo,
final SettingsValuesForSuggestion settingsValuesForSuggestion, final int sessionId, final SettingsValuesForSuggestion settingsValuesForSuggestion, final int sessionId,
final float weightForLocale, final float[] inOutWeightOfLangModelVsSpatialModel) { final float weightForLocale, final float[] inOutWeightOfLangModelVsSpatialModel) {
reloadDictionaryIfRequired(); reloadDictionaryIfRequired();
@ -447,7 +447,7 @@ abstract public class ExpandableBinaryDictionary extends Dictionary {
return null; return null;
} }
final ArrayList<SuggestedWordInfo> suggestions = final ArrayList<SuggestedWordInfo> suggestions =
mBinaryDictionary.getSuggestions(composer, prevWordsInfo, proximityInfo, mBinaryDictionary.getSuggestions(composer, ngramContext, proximityInfo,
settingsValuesForSuggestion, sessionId, weightForLocale, settingsValuesForSuggestion, sessionId, weightForLocale,
inOutWeightOfLangModelVsSpatialModel); inOutWeightOfLangModelVsSpatialModel);
if (mBinaryDictionary.isCorrupted()) { if (mBinaryDictionary.isCorrupted()) {
@ -519,9 +519,9 @@ abstract public class ExpandableBinaryDictionary extends Dictionary {
} }
protected boolean isValidNgramLocked(final PrevWordsInfo prevWordsInfo, final String word) { protected boolean isValidNgramLocked(final NgramContext ngramContext, final String word) {
if (mBinaryDictionary == null) return false; if (mBinaryDictionary == null) return false;
return mBinaryDictionary.isValidNgram(prevWordsInfo, word); return mBinaryDictionary.isValidNgram(ngramContext, word);
} }
/** /**

View file

@ -48,7 +48,7 @@ public final class LastComposedWord {
public final String mTypedWord; public final String mTypedWord;
public final CharSequence mCommittedWord; public final CharSequence mCommittedWord;
public final String mSeparatorString; public final String mSeparatorString;
public final PrevWordsInfo mPrevWordsInfo; public final NgramContext mNgramContext;
public final int mCapitalizedMode; public final int mCapitalizedMode;
public final InputPointers mInputPointers = public final InputPointers mInputPointers =
new InputPointers(Constants.DICTIONARY_MAX_WORD_LENGTH); new InputPointers(Constants.DICTIONARY_MAX_WORD_LENGTH);
@ -64,7 +64,7 @@ public final class LastComposedWord {
public LastComposedWord(final ArrayList<Event> events, public LastComposedWord(final ArrayList<Event> events,
final InputPointers inputPointers, final String typedWord, final InputPointers inputPointers, final String typedWord,
final CharSequence committedWord, final String separatorString, final CharSequence committedWord, final String separatorString,
final PrevWordsInfo prevWordsInfo, final int capitalizedMode) { final NgramContext ngramContext, final int capitalizedMode) {
if (inputPointers != null) { if (inputPointers != null) {
mInputPointers.copy(inputPointers); mInputPointers.copy(inputPointers);
} }
@ -73,7 +73,7 @@ public final class LastComposedWord {
mCommittedWord = committedWord; mCommittedWord = committedWord;
mSeparatorString = separatorString; mSeparatorString = separatorString;
mActive = true; mActive = true;
mPrevWordsInfo = prevWordsInfo; mNgramContext = ngramContext;
mCapitalizedMode = capitalizedMode; mCapitalizedMode = capitalizedMode;
} }

View file

@ -27,11 +27,11 @@ import java.util.Arrays;
* Class to represent information of previous words. This class is used to add n-gram entries * Class to represent information of previous words. This class is used to add n-gram entries
* into binary dictionaries, to get predictions, and to get suggestions. * into binary dictionaries, to get predictions, and to get suggestions.
*/ */
public class PrevWordsInfo { public class NgramContext {
public static final PrevWordsInfo EMPTY_PREV_WORDS_INFO = public static final NgramContext EMPTY_PREV_WORDS_INFO =
new PrevWordsInfo(WordInfo.EMPTY_WORD_INFO); new NgramContext(WordInfo.EMPTY_WORD_INFO);
public static final PrevWordsInfo BEGINNING_OF_SENTENCE = public static final NgramContext BEGINNING_OF_SENTENCE =
new PrevWordsInfo(WordInfo.BEGINNING_OF_SENTENCE); new NgramContext(WordInfo.BEGINNING_OF_SENTENCE);
/** /**
* Word information used to represent previous words information. * Word information used to represent previous words information.
@ -91,31 +91,31 @@ public class PrevWordsInfo {
private final int mPrevWordsCount; private final int mPrevWordsCount;
// Construct from the previous word information. // Construct from the previous word information.
public PrevWordsInfo(final WordInfo... prevWordsInfo) { public NgramContext(final WordInfo... prevWordsInfo) {
mPrevWordsInfo = prevWordsInfo; mPrevWordsInfo = prevWordsInfo;
mPrevWordsCount = prevWordsInfo.length; mPrevWordsCount = prevWordsInfo.length;
} }
// Construct from WordInfo array and size. The caller shouldn't change prevWordsInfo after // Construct from WordInfo array and size. The caller shouldn't change prevWordsInfo after
// calling this method. // calling this method.
private PrevWordsInfo(final PrevWordsInfo prevWordsInfo, final int prevWordsCount) { private NgramContext(final NgramContext ngramContext, final int prevWordsCount) {
if (prevWordsInfo.mPrevWordsCount < prevWordsCount) { if (ngramContext.mPrevWordsCount < prevWordsCount) {
throw new IndexOutOfBoundsException("prevWordsInfo.mPrevWordsCount (" throw new IndexOutOfBoundsException("ngramContext.mPrevWordsCount ("
+ prevWordsInfo.mPrevWordsCount + ") is smaller than prevWordsCount (" + ngramContext.mPrevWordsCount + ") is smaller than prevWordsCount ("
+ prevWordsCount + ")"); + prevWordsCount + ")");
} }
mPrevWordsInfo = prevWordsInfo.mPrevWordsInfo; mPrevWordsInfo = ngramContext.mPrevWordsInfo;
mPrevWordsCount = prevWordsCount; mPrevWordsCount = prevWordsCount;
} }
// Create next prevWordsInfo using current prevWordsInfo. // Create next prevWordsInfo using current prevWordsInfo.
public PrevWordsInfo getNextPrevWordsInfo(final WordInfo wordInfo) { public NgramContext getNextNgramContext(final WordInfo wordInfo) {
final int nextPrevWordCount = Math.min(Constants.MAX_PREV_WORD_COUNT_FOR_N_GRAM, final int nextPrevWordCount = Math.min(Constants.MAX_PREV_WORD_COUNT_FOR_N_GRAM,
mPrevWordsCount + 1); mPrevWordsCount + 1);
final WordInfo[] prevWordsInfo = new WordInfo[nextPrevWordCount]; final WordInfo[] prevWordsInfo = new WordInfo[nextPrevWordCount];
prevWordsInfo[0] = wordInfo; prevWordsInfo[0] = wordInfo;
System.arraycopy(mPrevWordsInfo, 0, prevWordsInfo, 1, nextPrevWordCount - 1); System.arraycopy(mPrevWordsInfo, 0, prevWordsInfo, 1, nextPrevWordCount - 1);
return new PrevWordsInfo(prevWordsInfo); return new NgramContext(prevWordsInfo);
} }
public boolean isValid() { public boolean isValid() {
@ -158,9 +158,9 @@ public class PrevWordsInfo {
} }
} }
public PrevWordsInfo getTrimmedPrevWordsInfo(final int maxPrevWordCount) { public NgramContext getTrimmedNgramContext(final int maxPrevWordCount) {
final int newSize = Math.min(maxPrevWordCount, mPrevWordsCount); final int newSize = Math.min(maxPrevWordCount, mPrevWordsCount);
return new PrevWordsInfo(this /* prevWordsInfo */, newSize); return new NgramContext(this /* prevWordsInfo */, newSize);
} }
public int getPrevWordCount() { public int getPrevWordCount() {
@ -176,8 +176,8 @@ public class PrevWordsInfo {
@Override @Override
public boolean equals(Object o) { public boolean equals(Object o) {
if (this == o) return true; if (this == o) return true;
if (!(o instanceof PrevWordsInfo)) return false; if (!(o instanceof NgramContext)) return false;
final PrevWordsInfo prevWordsInfo = (PrevWordsInfo)o; final NgramContext prevWordsInfo = (NgramContext)o;
final int minLength = Math.min(mPrevWordsCount, prevWordsInfo.mPrevWordsCount); final int minLength = Math.min(mPrevWordsCount, prevWordsInfo.mPrevWordsCount);
for (int i = 0; i < minLength; i++) { for (int i = 0; i < minLength; i++) {

View file

@ -51,13 +51,13 @@ public final class ReadOnlyBinaryDictionary extends Dictionary {
@Override @Override
public ArrayList<SuggestedWordInfo> getSuggestions(final WordComposer composer, public ArrayList<SuggestedWordInfo> getSuggestions(final WordComposer composer,
final PrevWordsInfo prevWordsInfo, final ProximityInfo proximityInfo, final NgramContext ngramContext, final ProximityInfo proximityInfo,
final SettingsValuesForSuggestion settingsValuesForSuggestion, final SettingsValuesForSuggestion settingsValuesForSuggestion,
final int sessionId, final float weightForLocale, final int sessionId, final float weightForLocale,
final float[] inOutWeightOfLangModelVsSpatialModel) { final float[] inOutWeightOfLangModelVsSpatialModel) {
if (mLock.readLock().tryLock()) { if (mLock.readLock().tryLock()) {
try { try {
return mBinaryDictionary.getSuggestions(composer, prevWordsInfo, proximityInfo, return mBinaryDictionary.getSuggestions(composer, ngramContext, proximityInfo,
settingsValuesForSuggestion, sessionId, weightForLocale, settingsValuesForSuggestion, sessionId, weightForLocale,
inOutWeightOfLangModelVsSpatialModel); inOutWeightOfLangModelVsSpatialModel);
} finally { } finally {

View file

@ -36,7 +36,7 @@ import com.android.inputmethod.compat.InputConnectionCompatUtils;
import com.android.inputmethod.latin.settings.SpacingAndPunctuations; import com.android.inputmethod.latin.settings.SpacingAndPunctuations;
import com.android.inputmethod.latin.utils.CapsModeUtils; import com.android.inputmethod.latin.utils.CapsModeUtils;
import com.android.inputmethod.latin.utils.DebugLogUtils; import com.android.inputmethod.latin.utils.DebugLogUtils;
import com.android.inputmethod.latin.utils.PrevWordsInfoUtils; import com.android.inputmethod.latin.utils.NgramContextUtils;
import com.android.inputmethod.latin.utils.ScriptUtils; import com.android.inputmethod.latin.utils.ScriptUtils;
import com.android.inputmethod.latin.utils.SpannableStringUtils; import com.android.inputmethod.latin.utils.SpannableStringUtils;
import com.android.inputmethod.latin.utils.StringUtils; import com.android.inputmethod.latin.utils.StringUtils;
@ -593,11 +593,11 @@ public final class RichInputConnection {
} }
@SuppressWarnings("unused") @SuppressWarnings("unused")
public PrevWordsInfo getPrevWordsInfoFromNthPreviousWord( public NgramContext getNgramContextFromNthPreviousWord(
final SpacingAndPunctuations spacingAndPunctuations, final int n) { final SpacingAndPunctuations spacingAndPunctuations, final int n) {
mIC = mParent.getCurrentInputConnection(); mIC = mParent.getCurrentInputConnection();
if (null == mIC) { if (null == mIC) {
return PrevWordsInfo.EMPTY_PREV_WORDS_INFO; return NgramContext.EMPTY_PREV_WORDS_INFO;
} }
final CharSequence prev = getTextBeforeCursor(LOOKBACK_CHARACTER_NUM, 0); final CharSequence prev = getTextBeforeCursor(LOOKBACK_CHARACTER_NUM, 0);
if (DEBUG_PREVIOUS_TEXT && null != prev) { if (DEBUG_PREVIOUS_TEXT && null != prev) {
@ -618,7 +618,7 @@ public final class RichInputConnection {
} }
} }
} }
return PrevWordsInfoUtils.getPrevWordsInfoFromNthPreviousWord( return NgramContextUtils.getNgramContextFromNthPreviousWord(
prev, spacingAndPunctuations, n); prev, spacingAndPunctuations, n);
} }

View file

@ -68,15 +68,15 @@ public final class Suggest {
} }
public void getSuggestedWords(final WordComposer wordComposer, public void getSuggestedWords(final WordComposer wordComposer,
final PrevWordsInfo prevWordsInfo, final ProximityInfo proximityInfo, final NgramContext ngramContext, final ProximityInfo proximityInfo,
final SettingsValuesForSuggestion settingsValuesForSuggestion, final SettingsValuesForSuggestion settingsValuesForSuggestion,
final boolean isCorrectionEnabled, final int inputStyle, final int sequenceNumber, final boolean isCorrectionEnabled, final int inputStyle, final int sequenceNumber,
final OnGetSuggestedWordsCallback callback) { final OnGetSuggestedWordsCallback callback) {
if (wordComposer.isBatchMode()) { if (wordComposer.isBatchMode()) {
getSuggestedWordsForBatchInput(wordComposer, prevWordsInfo, proximityInfo, getSuggestedWordsForBatchInput(wordComposer, ngramContext, proximityInfo,
settingsValuesForSuggestion, inputStyle, sequenceNumber, callback); settingsValuesForSuggestion, inputStyle, sequenceNumber, callback);
} else { } else {
getSuggestedWordsForNonBatchInput(wordComposer, prevWordsInfo, proximityInfo, getSuggestedWordsForNonBatchInput(wordComposer, ngramContext, proximityInfo,
settingsValuesForSuggestion, inputStyle, isCorrectionEnabled, settingsValuesForSuggestion, inputStyle, isCorrectionEnabled,
sequenceNumber, callback); sequenceNumber, callback);
} }
@ -121,7 +121,7 @@ public final class Suggest {
// Retrieves suggestions for non-batch input (typing, recorrection, predictions...) // Retrieves suggestions for non-batch input (typing, recorrection, predictions...)
// and calls the callback function with the suggestions. // and calls the callback function with the suggestions.
private void getSuggestedWordsForNonBatchInput(final WordComposer wordComposer, private void getSuggestedWordsForNonBatchInput(final WordComposer wordComposer,
final PrevWordsInfo prevWordsInfo, final ProximityInfo proximityInfo, final NgramContext ngramContext, final ProximityInfo proximityInfo,
final SettingsValuesForSuggestion settingsValuesForSuggestion, final SettingsValuesForSuggestion settingsValuesForSuggestion,
final int inputStyleIfNotPrediction, final boolean isCorrectionEnabled, final int inputStyleIfNotPrediction, final boolean isCorrectionEnabled,
final int sequenceNumber, final OnGetSuggestedWordsCallback callback) { final int sequenceNumber, final OnGetSuggestedWordsCallback callback) {
@ -132,7 +132,7 @@ public final class Suggest {
: typedWord; : typedWord;
final SuggestionResults suggestionResults = mDictionaryFacilitator.getSuggestionResults( final SuggestionResults suggestionResults = mDictionaryFacilitator.getSuggestionResults(
wordComposer, prevWordsInfo, proximityInfo, settingsValuesForSuggestion, wordComposer, ngramContext, proximityInfo, settingsValuesForSuggestion,
SESSION_ID_TYPING); SESSION_ID_TYPING);
final ArrayList<SuggestedWordInfo> suggestionsContainer = final ArrayList<SuggestedWordInfo> suggestionsContainer =
getTransformedSuggestedWordInfoList(wordComposer, suggestionResults, getTransformedSuggestedWordInfoList(wordComposer, suggestionResults,
@ -209,12 +209,12 @@ public final class Suggest {
// Retrieves suggestions for the batch input // Retrieves suggestions for the batch input
// and calls the callback function with the suggestions. // and calls the callback function with the suggestions.
private void getSuggestedWordsForBatchInput(final WordComposer wordComposer, private void getSuggestedWordsForBatchInput(final WordComposer wordComposer,
final PrevWordsInfo prevWordsInfo, final ProximityInfo proximityInfo, final NgramContext ngramContext, final ProximityInfo proximityInfo,
final SettingsValuesForSuggestion settingsValuesForSuggestion, final SettingsValuesForSuggestion settingsValuesForSuggestion,
final int inputStyle, final int sequenceNumber, final int inputStyle, final int sequenceNumber,
final OnGetSuggestedWordsCallback callback) { final OnGetSuggestedWordsCallback callback) {
final SuggestionResults suggestionResults = mDictionaryFacilitator.getSuggestionResults( final SuggestionResults suggestionResults = mDictionaryFacilitator.getSuggestionResults(
wordComposer, prevWordsInfo, proximityInfo, settingsValuesForSuggestion, wordComposer, ngramContext, proximityInfo, settingsValuesForSuggestion,
SESSION_ID_GESTURE); SESSION_ID_GESTURE);
final Locale defaultLocale = mDictionaryFacilitator.getLocale(); final Locale defaultLocale = mDictionaryFacilitator.getLocale();
final ArrayList<SuggestedWordInfo> suggestionsContainer = final ArrayList<SuggestedWordInfo> suggestionsContainer =

View file

@ -448,13 +448,13 @@ public final class WordComposer {
// `type' should be one of the LastComposedWord.COMMIT_TYPE_* constants above. // `type' should be one of the LastComposedWord.COMMIT_TYPE_* constants above.
// committedWord should contain suggestion spans if applicable. // committedWord should contain suggestion spans if applicable.
public LastComposedWord commitWord(final int type, final CharSequence committedWord, public LastComposedWord commitWord(final int type, final CharSequence committedWord,
final String separatorString, final PrevWordsInfo prevWordsInfo) { final String separatorString, final NgramContext ngramContext) {
// Note: currently, we come here whenever we commit a word. If it's a MANUAL_PICK // Note: currently, we come here whenever we commit a word. If it's a MANUAL_PICK
// or a DECIDED_WORD we may cancel the commit later; otherwise, we should deactivate // or a DECIDED_WORD we may cancel the commit later; otherwise, we should deactivate
// the last composed word to ensure this does not happen. // the last composed word to ensure this does not happen.
final LastComposedWord lastComposedWord = new LastComposedWord(mEvents, final LastComposedWord lastComposedWord = new LastComposedWord(mEvents,
mInputPointers, mTypedWordCache.toString(), committedWord, separatorString, mInputPointers, mTypedWordCache.toString(), committedWord, separatorString,
prevWordsInfo, mCapitalizedMode); ngramContext, mCapitalizedMode);
mInputPointers.reset(); mInputPointers.reset();
if (type != LastComposedWord.COMMIT_TYPE_DECIDED_WORD if (type != LastComposedWord.COMMIT_TYPE_DECIDED_WORD
&& type != LastComposedWord.COMMIT_TYPE_MANUAL_PICK) { && type != LastComposedWord.COMMIT_TYPE_MANUAL_PICK) {

View file

@ -45,7 +45,7 @@ import com.android.inputmethod.latin.DictionaryFacilitator;
import com.android.inputmethod.latin.InputPointers; import com.android.inputmethod.latin.InputPointers;
import com.android.inputmethod.latin.LastComposedWord; import com.android.inputmethod.latin.LastComposedWord;
import com.android.inputmethod.latin.LatinIME; import com.android.inputmethod.latin.LatinIME;
import com.android.inputmethod.latin.PrevWordsInfo; import com.android.inputmethod.latin.NgramContext;
import com.android.inputmethod.latin.RichInputConnection; import com.android.inputmethod.latin.RichInputConnection;
import com.android.inputmethod.latin.Suggest; import com.android.inputmethod.latin.Suggest;
import com.android.inputmethod.latin.Suggest.OnGetSuggestedWordsCallback; import com.android.inputmethod.latin.Suggest.OnGetSuggestedWordsCallback;
@ -1376,7 +1376,7 @@ public final class InputLogic {
} }
private void performAdditionToUserHistoryDictionary(final SettingsValues settingsValues, private void performAdditionToUserHistoryDictionary(final SettingsValues settingsValues,
final String suggestion, final PrevWordsInfo prevWordsInfo) { final String suggestion, final NgramContext ngramContext) {
// If correction is not enabled, we don't add words to the user history dictionary. // If correction is not enabled, we don't add words to the user history dictionary.
// That's to avoid unintended additions in some sensitive fields, or fields that // That's to avoid unintended additions in some sensitive fields, or fields that
// expect to receive non-words. // expect to receive non-words.
@ -1388,7 +1388,7 @@ public final class InputLogic {
final int timeStampInSeconds = (int)TimeUnit.MILLISECONDS.toSeconds( final int timeStampInSeconds = (int)TimeUnit.MILLISECONDS.toSeconds(
System.currentTimeMillis()); System.currentTimeMillis());
mDictionaryFacilitator.addToUserHistory(suggestion, wasAutoCapitalized, mDictionaryFacilitator.addToUserHistory(suggestion, wasAutoCapitalized,
prevWordsInfo, timeStampInSeconds, settingsValues.mBlockPotentiallyOffensive); ngramContext, timeStampInSeconds, settingsValues.mBlockPotentiallyOffensive);
} }
public void performUpdateSuggestionStripSync(final SettingsValues settingsValues, public void performUpdateSuggestionStripSync(final SettingsValues settingsValues,
@ -1519,10 +1519,10 @@ public final class InputLogic {
} }
} }
final int[] codePoints = StringUtils.toCodePointArray(typedWord); final int[] codePoints = StringUtils.toCodePointArray(typedWord);
// We want the previous word for suggestion. If we have chars in the word // We want the context of preceding words for suggestion. If we have chars in the word
// before the cursor, then we want the word before that, hence 2; otherwise, // before the cursor, then we want the word before that, hence 2; otherwise,
// we want the word immediately before the cursor, hence 1. // we want the word immediately before the cursor, hence 1.
final PrevWordsInfo prevWordsInfo = getPrevWordsInfoFromNthPreviousWordForSuggestion( final NgramContext ngramContext = getNgramContextFromNthPreviousWordForSuggestion(
settingsValues.mSpacingAndPunctuations, settingsValues.mSpacingAndPunctuations,
0 == numberOfCharsInWordBeforeCursor ? 1 : 2); 0 == numberOfCharsInWordBeforeCursor ? 1 : 2);
mWordComposer.setComposingWord(codePoints, mWordComposer.setComposingWord(codePoints,
@ -1760,24 +1760,24 @@ public final class InputLogic {
} }
/** /**
* Get information fo previous words from the nth previous word before the cursor as context * Get n-gram context from the nth previous word before the cursor as context
* for the suggestion process. * for the suggestion process.
* @param spacingAndPunctuations the current spacing and punctuations settings. * @param spacingAndPunctuations the current spacing and punctuations settings.
* @param nthPreviousWord reverse index of the word to get (1-indexed) * @param nthPreviousWord reverse index of the word to get (1-indexed)
* @return the information of previous words * @return the information of previous words
*/ */
// TODO: Make this private // TODO: Make this private
public PrevWordsInfo getPrevWordsInfoFromNthPreviousWordForSuggestion( public NgramContext getNgramContextFromNthPreviousWordForSuggestion(
final SpacingAndPunctuations spacingAndPunctuations, final int nthPreviousWord) { final SpacingAndPunctuations spacingAndPunctuations, final int nthPreviousWord) {
if (spacingAndPunctuations.mCurrentLanguageHasSpaces) { if (spacingAndPunctuations.mCurrentLanguageHasSpaces) {
// If we are typing in a language with spaces we can just look up the previous // If we are typing in a language with spaces we can just look up the previous
// word information from textview. // word information from textview.
return mConnection.getPrevWordsInfoFromNthPreviousWord( return mConnection.getNgramContextFromNthPreviousWord(
spacingAndPunctuations, nthPreviousWord); spacingAndPunctuations, nthPreviousWord);
} else { } else {
return LastComposedWord.NOT_A_COMPOSED_WORD == mLastComposedWord ? return LastComposedWord.NOT_A_COMPOSED_WORD == mLastComposedWord ?
PrevWordsInfo.BEGINNING_OF_SENTENCE : NgramContext.BEGINNING_OF_SENTENCE :
new PrevWordsInfo(new PrevWordsInfo.WordInfo( new NgramContext(new NgramContext.WordInfo(
mLastComposedWord.mCommittedWord.toString())); mLastComposedWord.mCommittedWord.toString()));
} }
} }
@ -2140,20 +2140,20 @@ public final class InputLogic {
final CharSequence chosenWordWithSuggestions = final CharSequence chosenWordWithSuggestions =
SuggestionSpanUtils.getTextWithSuggestionSpan(mLatinIME, chosenWord, SuggestionSpanUtils.getTextWithSuggestionSpan(mLatinIME, chosenWord,
suggestedWords); suggestedWords);
// When we are composing word, get previous words information from the 2nd previous word // When we are composing word, get n-gram context from the 2nd previous word because the
// because the 1st previous word is the word to be committed. Otherwise get previous words // 1st previous word is the word to be committed. Otherwise get n-gram context from the 1st
// information from the 1st previous word. // previous word.
final PrevWordsInfo prevWordsInfo = mConnection.getPrevWordsInfoFromNthPreviousWord( final NgramContext ngramContext = mConnection.getNgramContextFromNthPreviousWord(
settingsValues.mSpacingAndPunctuations, mWordComposer.isComposingWord() ? 2 : 1); settingsValues.mSpacingAndPunctuations, mWordComposer.isComposingWord() ? 2 : 1);
mConnection.commitText(chosenWordWithSuggestions, 1); mConnection.commitText(chosenWordWithSuggestions, 1);
// Add the word to the user history dictionary // Add the word to the user history dictionary
performAdditionToUserHistoryDictionary(settingsValues, chosenWord, prevWordsInfo); performAdditionToUserHistoryDictionary(settingsValues, chosenWord, ngramContext);
// TODO: figure out here if this is an auto-correct or if the best word is actually // TODO: figure out here if this is an auto-correct or if the best word is actually
// what user typed. Note: currently this is done much later in // what user typed. Note: currently this is done much later in
// LastComposedWord#didCommitTypedWord by string equality of the remembered // LastComposedWord#didCommitTypedWord by string equality of the remembered
// strings. // strings.
mLastComposedWord = mWordComposer.commitWord(commitType, mLastComposedWord = mWordComposer.commitWord(commitType,
chosenWordWithSuggestions, separatorString, prevWordsInfo); chosenWordWithSuggestions, separatorString, ngramContext);
} }
/** /**
@ -2200,7 +2200,7 @@ public final class InputLogic {
mWordComposer.adviseCapitalizedModeBeforeFetchingSuggestions( mWordComposer.adviseCapitalizedModeBeforeFetchingSuggestions(
getActualCapsMode(settingsValues, keyboardShiftMode)); getActualCapsMode(settingsValues, keyboardShiftMode));
mSuggest.getSuggestedWords(mWordComposer, mSuggest.getSuggestedWords(mWordComposer,
getPrevWordsInfoFromNthPreviousWordForSuggestion( getNgramContextFromNthPreviousWordForSuggestion(
settingsValues.mSpacingAndPunctuations, settingsValues.mSpacingAndPunctuations,
// Get the word on which we should search the bigrams. If we are composing // Get the word on which we should search the bigrams. If we are composing
// a word, it's whatever is *before* the half-committed word in the buffer, // a word, it's whatever is *before* the half-committed word in the buffer,

View file

@ -23,7 +23,7 @@ import com.android.inputmethod.annotations.UsedForTesting;
import com.android.inputmethod.latin.Constants; import com.android.inputmethod.latin.Constants;
import com.android.inputmethod.latin.Dictionary; import com.android.inputmethod.latin.Dictionary;
import com.android.inputmethod.latin.ExpandableBinaryDictionary; import com.android.inputmethod.latin.ExpandableBinaryDictionary;
import com.android.inputmethod.latin.PrevWordsInfo; import com.android.inputmethod.latin.NgramContext;
import com.android.inputmethod.latin.utils.DistracterFilter; import com.android.inputmethod.latin.utils.DistracterFilter;
import java.io.File; import java.io.File;
@ -53,14 +53,14 @@ public class UserHistoryDictionary extends DecayingExpandableBinaryDictionaryBas
* Add a word to the user history dictionary. * Add a word to the user history dictionary.
* *
* @param userHistoryDictionary the user history dictionary * @param userHistoryDictionary the user history dictionary
* @param prevWordsInfo the information of previous words * @param ngramContext the n-gram context
* @param word the word the user inputted * @param word the word the user inputted
* @param isValid whether the word is valid or not * @param isValid whether the word is valid or not
* @param timestamp the timestamp when the word has been inputted * @param timestamp the timestamp when the word has been inputted
* @param distracterFilter the filter to check whether the word is a distracter * @param distracterFilter the filter to check whether the word is a distracter
*/ */
public static void addToDictionary(final ExpandableBinaryDictionary userHistoryDictionary, public static void addToDictionary(final ExpandableBinaryDictionary userHistoryDictionary,
final PrevWordsInfo prevWordsInfo, final String word, final boolean isValid, final NgramContext ngramContext, final String word, final boolean isValid,
final int timestamp, final DistracterFilter distracterFilter) { final int timestamp, final DistracterFilter distracterFilter) {
if (word.length() > Constants.DICTIONARY_MAX_WORD_LENGTH) { if (word.length() > Constants.DICTIONARY_MAX_WORD_LENGTH) {
return; return;
@ -71,11 +71,11 @@ public class UserHistoryDictionary extends DecayingExpandableBinaryDictionaryBas
null /* shortcutTarget */, 0 /* shortcutFreq */, false /* isNotAWord */, null /* shortcutTarget */, 0 /* shortcutFreq */, false /* isNotAWord */,
false /* isBlacklisted */, timestamp, distracterFilter); false /* isBlacklisted */, timestamp, distracterFilter);
final boolean isBeginningOfSentenceContext = prevWordsInfo.isBeginningOfSentenceContext(); final boolean isBeginningOfSentenceContext = ngramContext.isBeginningOfSentenceContext();
final PrevWordsInfo prevWordsInfoToBeSaved = final NgramContext ngramContextToBeSaved =
prevWordsInfo.getTrimmedPrevWordsInfo(SUPPORTED_NGRAM - 1); ngramContext.getTrimmedNgramContext(SUPPORTED_NGRAM - 1);
for (int i = 0; i < prevWordsInfoToBeSaved.getPrevWordCount(); i++) { for (int i = 0; i < ngramContextToBeSaved.getPrevWordCount(); i++) {
final CharSequence prevWord = prevWordsInfoToBeSaved.getNthPrevWord(1 /* n */); final CharSequence prevWord = ngramContextToBeSaved.getNthPrevWord(1 /* n */);
if (prevWord == null || (prevWord.length() > Constants.DICTIONARY_MAX_WORD_LENGTH)) { if (prevWord == null || (prevWord.length() > Constants.DICTIONARY_MAX_WORD_LENGTH)) {
return; return;
} }
@ -86,11 +86,11 @@ public class UserHistoryDictionary extends DecayingExpandableBinaryDictionaryBas
if (isBeginningOfSentenceContext) { if (isBeginningOfSentenceContext) {
// Beginning-of-Sentence n-gram entry is added as an n-gram entry of an OOV word. // Beginning-of-Sentence n-gram entry is added as an n-gram entry of an OOV word.
userHistoryDictionary.addNgramEntry( userHistoryDictionary.addNgramEntry(
prevWordsInfoToBeSaved.getTrimmedPrevWordsInfo(i + 1), word, ngramContextToBeSaved.getTrimmedNgramContext(i + 1), word,
FREQUENCY_FOR_WORDS_NOT_IN_DICTS, timestamp); FREQUENCY_FOR_WORDS_NOT_IN_DICTS, timestamp);
} else { } else {
userHistoryDictionary.addNgramEntry( userHistoryDictionary.addNgramEntry(
prevWordsInfoToBeSaved.getTrimmedPrevWordsInfo(i + 1), word, frequency, ngramContextToBeSaved.getTrimmedNgramContext(i + 1), word, frequency,
timestamp); timestamp);
} }
} }

View file

@ -31,7 +31,7 @@ import com.android.inputmethod.keyboard.KeyboardLayoutSet;
import com.android.inputmethod.keyboard.ProximityInfo; import com.android.inputmethod.keyboard.ProximityInfo;
import com.android.inputmethod.latin.DictionaryFacilitator; import com.android.inputmethod.latin.DictionaryFacilitator;
import com.android.inputmethod.latin.DictionaryFacilitatorLruCache; import com.android.inputmethod.latin.DictionaryFacilitatorLruCache;
import com.android.inputmethod.latin.PrevWordsInfo; import com.android.inputmethod.latin.NgramContext;
import com.android.inputmethod.latin.R; import com.android.inputmethod.latin.R;
import com.android.inputmethod.latin.RichInputMethodSubtype; import com.android.inputmethod.latin.RichInputMethodSubtype;
import com.android.inputmethod.latin.settings.SettingsValuesForSuggestion; import com.android.inputmethod.latin.settings.SettingsValuesForSuggestion;
@ -163,14 +163,14 @@ public final class AndroidSpellCheckerService extends SpellCheckerService
} }
public SuggestionResults getSuggestionResults(final Locale locale, final WordComposer composer, public SuggestionResults getSuggestionResults(final Locale locale, final WordComposer composer,
final PrevWordsInfo prevWordsInfo, final ProximityInfo proximityInfo) { final NgramContext ngramContext, final ProximityInfo proximityInfo) {
Integer sessionId = null; Integer sessionId = null;
mSemaphore.acquireUninterruptibly(); mSemaphore.acquireUninterruptibly();
try { try {
sessionId = mSessionIdPool.poll(); sessionId = mSessionIdPool.poll();
DictionaryFacilitator dictionaryFacilitatorForLocale = DictionaryFacilitator dictionaryFacilitatorForLocale =
mDictionaryFacilitatorCache.get(locale); mDictionaryFacilitatorCache.get(locale);
return dictionaryFacilitatorForLocale.getSuggestionResults(composer, prevWordsInfo, return dictionaryFacilitatorForLocale.getSuggestionResults(composer, ngramContext,
proximityInfo, mSettingsValuesForSuggestion, sessionId); proximityInfo, mSettingsValuesForSuggestion, sessionId);
} finally { } finally {
if (sessionId != null) { if (sessionId != null) {

View file

@ -25,7 +25,7 @@ import android.view.textservice.SuggestionsInfo;
import android.view.textservice.TextInfo; import android.view.textservice.TextInfo;
import com.android.inputmethod.compat.TextInfoCompatUtils; import com.android.inputmethod.compat.TextInfoCompatUtils;
import com.android.inputmethod.latin.PrevWordsInfo; import com.android.inputmethod.latin.NgramContext;
import com.android.inputmethod.latin.utils.StringUtils; import com.android.inputmethod.latin.utils.StringUtils;
import java.util.ArrayList; import java.util.ArrayList;
@ -62,8 +62,8 @@ public final class AndroidSpellCheckerSession extends AndroidWordLevelSpellCheck
final int offset = ssi.getOffsetAt(i); final int offset = ssi.getOffsetAt(i);
final int length = ssi.getLengthAt(i); final int length = ssi.getLengthAt(i);
final CharSequence subText = typedText.subSequence(offset, offset + length); final CharSequence subText = typedText.subSequence(offset, offset + length);
final PrevWordsInfo prevWordsInfo = final NgramContext ngramContext =
new PrevWordsInfo(new PrevWordsInfo.WordInfo(currentWord)); new NgramContext(new NgramContext.WordInfo(currentWord));
currentWord = subText; currentWord = subText;
if (!subText.toString().contains(AndroidSpellCheckerService.SINGLE_QUOTE)) { if (!subText.toString().contains(AndroidSpellCheckerService.SINGLE_QUOTE)) {
continue; continue;
@ -80,7 +80,7 @@ public final class AndroidSpellCheckerSession extends AndroidWordLevelSpellCheck
if (TextUtils.isEmpty(splitText)) { if (TextUtils.isEmpty(splitText)) {
continue; continue;
} }
if (mSuggestionsCache.getSuggestionsFromCache(splitText.toString(), prevWordsInfo) if (mSuggestionsCache.getSuggestionsFromCache(splitText.toString(), ngramContext)
== null) { == null) {
continue; continue;
} }
@ -208,10 +208,10 @@ public final class AndroidSpellCheckerSession extends AndroidWordLevelSpellCheck
} else { } else {
prevWord = null; prevWord = null;
} }
final PrevWordsInfo prevWordsInfo = final NgramContext ngramContext =
new PrevWordsInfo(new PrevWordsInfo.WordInfo(prevWord)); new NgramContext(new NgramContext.WordInfo(prevWord));
final TextInfo textInfo = textInfos[i]; final TextInfo textInfo = textInfos[i];
retval[i] = onGetSuggestionsInternal(textInfo, prevWordsInfo, suggestionsLimit); retval[i] = onGetSuggestionsInternal(textInfo, ngramContext, suggestionsLimit);
retval[i].setCookieAndSequence(textInfo.getCookie(), textInfo.getSequence()); retval[i].setCookieAndSequence(textInfo.getCookie(), textInfo.getSequence());
} }
return retval; return retval;

View file

@ -31,7 +31,7 @@ import com.android.inputmethod.compat.SuggestionsInfoCompatUtils;
import com.android.inputmethod.keyboard.Keyboard; import com.android.inputmethod.keyboard.Keyboard;
import com.android.inputmethod.keyboard.ProximityInfo; import com.android.inputmethod.keyboard.ProximityInfo;
import com.android.inputmethod.latin.Constants; import com.android.inputmethod.latin.Constants;
import com.android.inputmethod.latin.PrevWordsInfo; import com.android.inputmethod.latin.NgramContext;
import com.android.inputmethod.latin.SuggestedWords.SuggestedWordInfo; import com.android.inputmethod.latin.SuggestedWords.SuggestedWordInfo;
import com.android.inputmethod.latin.WordComposer; import com.android.inputmethod.latin.WordComposer;
import com.android.inputmethod.latin.utils.BinaryDictionaryUtils; import com.android.inputmethod.latin.utils.BinaryDictionaryUtils;
@ -73,27 +73,25 @@ public abstract class AndroidWordLevelSpellCheckerSession extends Session {
private final LruCache<String, SuggestionsParams> mUnigramSuggestionsInfoCache = private final LruCache<String, SuggestionsParams> mUnigramSuggestionsInfoCache =
new LruCache<>(MAX_CACHE_SIZE); new LruCache<>(MAX_CACHE_SIZE);
// TODO: Support n-gram input private static String generateKey(final String query, final NgramContext ngramContext) {
private static String generateKey(final String query, final PrevWordsInfo prevWordsInfo) { if (TextUtils.isEmpty(query) || !ngramContext.isValid()) {
if (TextUtils.isEmpty(query) || !prevWordsInfo.isValid()) {
return query; return query;
} }
return query + CHAR_DELIMITER + prevWordsInfo; return query + CHAR_DELIMITER + ngramContext;
} }
public SuggestionsParams getSuggestionsFromCache(String query, public SuggestionsParams getSuggestionsFromCache(String query,
final PrevWordsInfo prevWordsInfo) { final NgramContext ngramContext) {
return mUnigramSuggestionsInfoCache.get(generateKey(query, prevWordsInfo)); return mUnigramSuggestionsInfoCache.get(generateKey(query, ngramContext));
} }
public void putSuggestionsToCache( public void putSuggestionsToCache(final String query, final NgramContext ngramContext,
final String query, final PrevWordsInfo prevWordsInfo,
final String[] suggestions, final int flags) { final String[] suggestions, final int flags) {
if (suggestions == null || TextUtils.isEmpty(query)) { if (suggestions == null || TextUtils.isEmpty(query)) {
return; return;
} }
mUnigramSuggestionsInfoCache.put( mUnigramSuggestionsInfoCache.put(
generateKey(query, prevWordsInfo), new SuggestionsParams(suggestions, flags)); generateKey(query, ngramContext), new SuggestionsParams(suggestions, flags));
} }
public void clearCache() { public void clearCache() {
@ -223,12 +221,11 @@ public abstract class AndroidWordLevelSpellCheckerSession extends Session {
} }
protected SuggestionsInfo onGetSuggestionsInternal( protected SuggestionsInfo onGetSuggestionsInternal(
final TextInfo textInfo, final PrevWordsInfo prevWordsInfo, final TextInfo textInfo, final NgramContext ngramContext, final int suggestionsLimit) {
final int suggestionsLimit) {
try { try {
final String inText = textInfo.getText(); final String inText = textInfo.getText();
final SuggestionsParams cachedSuggestionsParams = final SuggestionsParams cachedSuggestionsParams =
mSuggestionsCache.getSuggestionsFromCache(inText, prevWordsInfo); mSuggestionsCache.getSuggestionsFromCache(inText, ngramContext);
if (cachedSuggestionsParams != null) { if (cachedSuggestionsParams != null) {
if (DBG) { if (DBG) {
Log.d(TAG, "Cache hit: " + inText + ", " + cachedSuggestionsParams.mFlags); Log.d(TAG, "Cache hit: " + inText + ", " + cachedSuggestionsParams.mFlags);
@ -283,7 +280,7 @@ public abstract class AndroidWordLevelSpellCheckerSession extends Session {
composer.setComposingWord(codePoints, coordinates); composer.setComposingWord(codePoints, coordinates);
// TODO: Don't gather suggestions if the limit is <= 0 unless necessary // TODO: Don't gather suggestions if the limit is <= 0 unless necessary
final SuggestionResults suggestionResults = mService.getSuggestionResults( final SuggestionResults suggestionResults = mService.getSuggestionResults(
mLocale, composer, prevWordsInfo, proximityInfo); mLocale, composer, ngramContext, proximityInfo);
final Result result = getResult(capitalizeType, mLocale, suggestionsLimit, final Result result = getResult(capitalizeType, mLocale, suggestionsLimit,
mService.getRecommendedThreshold(), text, suggestionResults); mService.getRecommendedThreshold(), text, suggestionResults);
isInDict = isInDictForAnyCapitalization(text, capitalizeType); isInDict = isInDictForAnyCapitalization(text, capitalizeType);
@ -308,7 +305,7 @@ public abstract class AndroidWordLevelSpellCheckerSession extends Session {
.getValueOf_RESULT_ATTR_HAS_RECOMMENDED_SUGGESTIONS() .getValueOf_RESULT_ATTR_HAS_RECOMMENDED_SUGGESTIONS()
: 0); : 0);
final SuggestionsInfo retval = new SuggestionsInfo(flags, result.mSuggestions); final SuggestionsInfo retval = new SuggestionsInfo(flags, result.mSuggestions);
mSuggestionsCache.putSuggestionsToCache(text, prevWordsInfo, result.mSuggestions, mSuggestionsCache.putSuggestionsToCache(text, ngramContext, result.mSuggestions,
flags); flags);
return retval; return retval;
} catch (RuntimeException e) { } catch (RuntimeException e) {

View file

@ -22,23 +22,23 @@ import java.util.Locale;
import android.view.inputmethod.InputMethodSubtype; import android.view.inputmethod.InputMethodSubtype;
import com.android.inputmethod.annotations.UsedForTesting; import com.android.inputmethod.annotations.UsedForTesting;
import com.android.inputmethod.latin.PrevWordsInfo; import com.android.inputmethod.latin.NgramContext;
public interface DistracterFilter { public interface DistracterFilter {
/** /**
* Determine whether a word is a distracter to words in dictionaries. * Determine whether a word is a distracter to words in dictionaries.
* *
* @param prevWordsInfo the information of previous words. * @param ngramContext the n-gram context
* @param testedWord the word that will be tested to see whether it is a distracter to words * @param testedWord the word that will be tested to see whether it is a distracter to words
* in dictionaries. * in dictionaries.
* @param locale the locale of word. * @param locale the locale of word.
* @return true if testedWord is a distracter, otherwise false. * @return true if testedWord is a distracter, otherwise false.
*/ */
public boolean isDistracterToWordsInDictionaries(final PrevWordsInfo prevWordsInfo, public boolean isDistracterToWordsInDictionaries(final NgramContext ngramContext,
final String testedWord, final Locale locale); final String testedWord, final Locale locale);
@UsedForTesting @UsedForTesting
public int getWordHandlingType(final PrevWordsInfo prevWordsInfo, final String testedWord, public int getWordHandlingType(final NgramContext ngramContext, final String testedWord,
final Locale locale); final Locale locale);
public void updateEnabledSubtypes(final List<InputMethodSubtype> enabledSubtypes); public void updateEnabledSubtypes(final List<InputMethodSubtype> enabledSubtypes);
@ -72,13 +72,13 @@ public interface DistracterFilter {
public static final DistracterFilter EMPTY_DISTRACTER_FILTER = new DistracterFilter() { public static final DistracterFilter EMPTY_DISTRACTER_FILTER = new DistracterFilter() {
@Override @Override
public boolean isDistracterToWordsInDictionaries(PrevWordsInfo prevWordsInfo, public boolean isDistracterToWordsInDictionaries(NgramContext ngramContext,
String testedWord, Locale locale) { String testedWord, Locale locale) {
return false; return false;
} }
@Override @Override
public int getWordHandlingType(final PrevWordsInfo prevWordsInfo, public int getWordHandlingType(final NgramContext ngramContext,
final String testedWord, final Locale locale) { final String testedWord, final Locale locale) {
return HandlingType.REQUIRE_NO_SPECIAL_HANDLINGS; return HandlingType.REQUIRE_NO_SPECIAL_HANDLINGS;
} }

View file

@ -36,7 +36,7 @@ import com.android.inputmethod.keyboard.KeyboardId;
import com.android.inputmethod.keyboard.KeyboardLayoutSet; import com.android.inputmethod.keyboard.KeyboardLayoutSet;
import com.android.inputmethod.latin.DictionaryFacilitator; import com.android.inputmethod.latin.DictionaryFacilitator;
import com.android.inputmethod.latin.DictionaryFacilitatorLruCache; import com.android.inputmethod.latin.DictionaryFacilitatorLruCache;
import com.android.inputmethod.latin.PrevWordsInfo; import com.android.inputmethod.latin.NgramContext;
import com.android.inputmethod.latin.RichInputMethodSubtype; import com.android.inputmethod.latin.RichInputMethodSubtype;
import com.android.inputmethod.latin.SuggestedWords.SuggestedWordInfo; import com.android.inputmethod.latin.SuggestedWords.SuggestedWordInfo;
import com.android.inputmethod.latin.WordComposer; import com.android.inputmethod.latin.WordComposer;
@ -156,14 +156,14 @@ public class DistracterFilterCheckingExactMatchesAndSuggestions implements Distr
/** /**
* Determine whether a word is a distracter to words in dictionaries. * Determine whether a word is a distracter to words in dictionaries.
* *
* @param prevWordsInfo the information of previous words. Not used for now. * @param ngramContext the n-gram context. Not used for now.
* @param testedWord the word that will be tested to see whether it is a distracter to words * @param testedWord the word that will be tested to see whether it is a distracter to words
* in dictionaries. * in dictionaries.
* @param locale the locale of word. * @param locale the locale of word.
* @return true if testedWord is a distracter, otherwise false. * @return true if testedWord is a distracter, otherwise false.
*/ */
@Override @Override
public boolean isDistracterToWordsInDictionaries(final PrevWordsInfo prevWordsInfo, public boolean isDistracterToWordsInDictionaries(final NgramContext ngramContext,
final String testedWord, final Locale locale) { final String testedWord, final Locale locale) {
if (locale == null) { if (locale == null) {
return false; return false;
@ -250,7 +250,7 @@ public class DistracterFilterCheckingExactMatchesAndSuggestions implements Distr
final SuggestionResults suggestionResults; final SuggestionResults suggestionResults;
synchronized (mLock) { synchronized (mLock) {
suggestionResults = dictionaryFacilitator.getSuggestionResults( suggestionResults = dictionaryFacilitator.getSuggestionResults(
composer, PrevWordsInfo.EMPTY_PREV_WORDS_INFO, keyboard.getProximityInfo(), composer, NgramContext.EMPTY_PREV_WORDS_INFO, keyboard.getProximityInfo(),
settingsValuesForSuggestion, 0 /* sessionId */); settingsValuesForSuggestion, 0 /* sessionId */);
} }
if (suggestionResults.isEmpty()) { if (suggestionResults.isEmpty()) {
@ -283,7 +283,7 @@ public class DistracterFilterCheckingExactMatchesAndSuggestions implements Distr
return false; return false;
} }
private boolean shouldBeLowerCased(final PrevWordsInfo prevWordsInfo, final String testedWord, private boolean shouldBeLowerCased(final NgramContext ngramContext, final String testedWord,
final Locale locale) { final Locale locale) {
final DictionaryFacilitator dictionaryFacilitator = final DictionaryFacilitator dictionaryFacilitator =
mDictionaryFacilitatorLruCache.get(locale); mDictionaryFacilitatorLruCache.get(locale);
@ -298,7 +298,7 @@ public class DistracterFilterCheckingExactMatchesAndSuggestions implements Distr
return true; return true;
} }
if (StringUtils.getCapitalizationType(testedWord) == StringUtils.CAPITALIZE_FIRST if (StringUtils.getCapitalizationType(testedWord) == StringUtils.CAPITALIZE_FIRST
&& !prevWordsInfo.isValid()) { && !ngramContext.isValid()) {
// TODO: Check beginning-of-sentence. // TODO: Check beginning-of-sentence.
return true; return true;
} }
@ -306,13 +306,13 @@ public class DistracterFilterCheckingExactMatchesAndSuggestions implements Distr
} }
@Override @Override
public int getWordHandlingType(final PrevWordsInfo prevWordsInfo, final String testedWord, public int getWordHandlingType(final NgramContext ngramContext, final String testedWord,
final Locale locale) { final Locale locale) {
// TODO: Use this method for user history dictionary. // TODO: Use this method for user history dictionary.
if (testedWord == null|| locale == null) { if (testedWord == null|| locale == null) {
return HandlingType.getHandlingType(false /* shouldBeLowerCased */, false /* isOov */); return HandlingType.getHandlingType(false /* shouldBeLowerCased */, false /* isOov */);
} }
final boolean shouldBeLowerCased = shouldBeLowerCased(prevWordsInfo, testedWord, locale); final boolean shouldBeLowerCased = shouldBeLowerCased(ngramContext, testedWord, locale);
final String caseModifiedWord = final String caseModifiedWord =
shouldBeLowerCased ? testedWord.toLowerCase(locale) : testedWord; shouldBeLowerCased ? testedWord.toLowerCase(locale) : testedWord;
final boolean isOov = !mDictionaryFacilitatorLruCache.get(locale).isValidWord( final boolean isOov = !mDictionaryFacilitatorLruCache.get(locale).isValidWord(

View file

@ -22,7 +22,7 @@ import java.util.Locale;
import android.view.inputmethod.InputMethodSubtype; import android.view.inputmethod.InputMethodSubtype;
import com.android.inputmethod.latin.Dictionary; import com.android.inputmethod.latin.Dictionary;
import com.android.inputmethod.latin.PrevWordsInfo; import com.android.inputmethod.latin.NgramContext;
public class DistracterFilterCheckingIsInDictionary implements DistracterFilter { public class DistracterFilterCheckingIsInDictionary implements DistracterFilter {
private final DistracterFilter mDistracterFilter; private final DistracterFilter mDistracterFilter;
@ -35,7 +35,7 @@ public class DistracterFilterCheckingIsInDictionary implements DistracterFilter
} }
@Override @Override
public boolean isDistracterToWordsInDictionaries(PrevWordsInfo prevWordsInfo, public boolean isDistracterToWordsInDictionaries(NgramContext ngramContext,
String testedWord, Locale locale) { String testedWord, Locale locale) {
if (mDictionary.isInDictionary(testedWord)) { if (mDictionary.isInDictionary(testedWord)) {
// This filter treats entries that are already in the dictionary as non-distracters // This filter treats entries that are already in the dictionary as non-distracters
@ -43,14 +43,14 @@ public class DistracterFilterCheckingIsInDictionary implements DistracterFilter
return false; return false;
} else { } else {
return mDistracterFilter.isDistracterToWordsInDictionaries( return mDistracterFilter.isDistracterToWordsInDictionaries(
prevWordsInfo, testedWord, locale); ngramContext, testedWord, locale);
} }
} }
@Override @Override
public int getWordHandlingType(final PrevWordsInfo prevWordsInfo, final String testedWord, public int getWordHandlingType(final NgramContext ngramContext, final String testedWord,
final Locale locale) { final Locale locale) {
return mDistracterFilter.getWordHandlingType(prevWordsInfo, testedWord, locale); return mDistracterFilter.getWordHandlingType(ngramContext, testedWord, locale);
} }
@Override @Override

View file

@ -21,7 +21,7 @@ import android.util.Log;
import com.android.inputmethod.annotations.UsedForTesting; import com.android.inputmethod.annotations.UsedForTesting;
import com.android.inputmethod.latin.Dictionary; import com.android.inputmethod.latin.Dictionary;
import com.android.inputmethod.latin.DictionaryFacilitator; import com.android.inputmethod.latin.DictionaryFacilitator;
import com.android.inputmethod.latin.PrevWordsInfo; import com.android.inputmethod.latin.NgramContext;
import com.android.inputmethod.latin.settings.SpacingAndPunctuations; import com.android.inputmethod.latin.settings.SpacingAndPunctuations;
import com.android.inputmethod.latin.utils.DistracterFilter.HandlingType; import com.android.inputmethod.latin.utils.DistracterFilter.HandlingType;
@ -89,7 +89,7 @@ public final class LanguageModelParam {
final DistracterFilter distracterFilter) { final DistracterFilter distracterFilter) {
final ArrayList<LanguageModelParam> languageModelParams = new ArrayList<>(); final ArrayList<LanguageModelParam> languageModelParams = new ArrayList<>();
final int N = tokens.size(); final int N = tokens.size();
PrevWordsInfo prevWordsInfo = PrevWordsInfo.EMPTY_PREV_WORDS_INFO; NgramContext ngramContext = NgramContext.EMPTY_PREV_WORDS_INFO;
for (int i = 0; i < N; ++i) { for (int i = 0; i < N; ++i) {
final String tempWord = tokens.get(i); final String tempWord = tokens.get(i);
if (StringUtils.isEmptyStringOrWhiteSpaces(tempWord)) { if (StringUtils.isEmptyStringOrWhiteSpaces(tempWord)) {
@ -106,7 +106,7 @@ public final class LanguageModelParam {
+ tempWord + "\""); + tempWord + "\"");
} }
// Sentence terminator found. Split. // Sentence terminator found. Split.
prevWordsInfo = PrevWordsInfo.EMPTY_PREV_WORDS_INFO; ngramContext = NgramContext.EMPTY_PREV_WORDS_INFO;
continue; continue;
} }
if (DEBUG_TOKEN) { if (DEBUG_TOKEN) {
@ -114,41 +114,41 @@ public final class LanguageModelParam {
} }
final LanguageModelParam languageModelParam = final LanguageModelParam languageModelParam =
detectWhetherVaildWordOrNotAndGetLanguageModelParam( detectWhetherVaildWordOrNotAndGetLanguageModelParam(
prevWordsInfo, tempWord, timestamp, locale, distracterFilter); ngramContext, tempWord, timestamp, locale, distracterFilter);
if (languageModelParam == null) { if (languageModelParam == null) {
continue; continue;
} }
languageModelParams.add(languageModelParam); languageModelParams.add(languageModelParam);
prevWordsInfo = prevWordsInfo.getNextPrevWordsInfo( ngramContext = ngramContext.getNextNgramContext(
new PrevWordsInfo.WordInfo(tempWord)); new NgramContext.WordInfo(tempWord));
} }
return languageModelParams; return languageModelParams;
} }
private static LanguageModelParam detectWhetherVaildWordOrNotAndGetLanguageModelParam( private static LanguageModelParam detectWhetherVaildWordOrNotAndGetLanguageModelParam(
final PrevWordsInfo prevWordsInfo, final String targetWord, final int timestamp, final NgramContext ngramContext, final String targetWord, final int timestamp,
final Locale locale, final DistracterFilter distracterFilter) { final Locale locale, final DistracterFilter distracterFilter) {
if (locale == null) { if (locale == null) {
return null; return null;
} }
final int wordHandlingType = distracterFilter.getWordHandlingType(prevWordsInfo, final int wordHandlingType = distracterFilter.getWordHandlingType(ngramContext,
targetWord, locale); targetWord, locale);
final String word = HandlingType.shouldBeLowerCased(wordHandlingType) ? final String word = HandlingType.shouldBeLowerCased(wordHandlingType) ?
targetWord.toLowerCase(locale) : targetWord; targetWord.toLowerCase(locale) : targetWord;
if (distracterFilter.isDistracterToWordsInDictionaries(prevWordsInfo, targetWord, locale)) { if (distracterFilter.isDistracterToWordsInDictionaries(ngramContext, targetWord, locale)) {
// The word is a distracter. // The word is a distracter.
return null; return null;
} }
return createAndGetLanguageModelParamOfWord(prevWordsInfo, word, timestamp, return createAndGetLanguageModelParamOfWord(ngramContext, word, timestamp,
!HandlingType.shouldBeHandledAsOov(wordHandlingType)); !HandlingType.shouldBeHandledAsOov(wordHandlingType));
} }
private static LanguageModelParam createAndGetLanguageModelParamOfWord( private static LanguageModelParam createAndGetLanguageModelParamOfWord(
final PrevWordsInfo prevWordsInfo, final String word, final int timestamp, final NgramContext ngramContext, final String word, final int timestamp,
final boolean isValidWord) { final boolean isValidWord) {
final int unigramProbability = isValidWord ? final int unigramProbability = isValidWord ?
UNIGRAM_PROBABILITY_FOR_VALID_WORD : UNIGRAM_PROBABILITY_FOR_OOV_WORD; UNIGRAM_PROBABILITY_FOR_VALID_WORD : UNIGRAM_PROBABILITY_FOR_OOV_WORD;
if (!prevWordsInfo.isValid()) { if (!ngramContext.isValid()) {
if (DEBUG) { if (DEBUG) {
Log.d(TAG, "--- add unigram: current(" Log.d(TAG, "--- add unigram: current("
+ (isValidWord ? "Valid" : "OOV") + ") = " + word); + (isValidWord ? "Valid" : "OOV") + ") = " + word);
@ -156,12 +156,12 @@ public final class LanguageModelParam {
return new LanguageModelParam(word, unigramProbability, timestamp); return new LanguageModelParam(word, unigramProbability, timestamp);
} }
if (DEBUG) { if (DEBUG) {
Log.d(TAG, "--- add bigram: prev = " + prevWordsInfo + ", current(" Log.d(TAG, "--- add bigram: prev = " + ngramContext + ", current("
+ (isValidWord ? "Valid" : "OOV") + ") = " + word); + (isValidWord ? "Valid" : "OOV") + ") = " + word);
} }
final int bigramProbability = isValidWord ? final int bigramProbability = isValidWord ?
BIGRAM_PROBABILITY_FOR_VALID_WORD : BIGRAM_PROBABILITY_FOR_OOV_WORD; BIGRAM_PROBABILITY_FOR_VALID_WORD : BIGRAM_PROBABILITY_FOR_OOV_WORD;
return new LanguageModelParam(prevWordsInfo.getNthPrevWord(1 /* n */), word, return new LanguageModelParam(ngramContext.getNthPrevWord(1 /* n */), word,
unigramProbability, bigramProbability, timestamp); unigramProbability, bigramProbability, timestamp);
} }
} }

View file

@ -20,12 +20,12 @@ import java.util.Arrays;
import java.util.regex.Pattern; import java.util.regex.Pattern;
import com.android.inputmethod.latin.Constants; import com.android.inputmethod.latin.Constants;
import com.android.inputmethod.latin.PrevWordsInfo; import com.android.inputmethod.latin.NgramContext;
import com.android.inputmethod.latin.PrevWordsInfo.WordInfo; import com.android.inputmethod.latin.NgramContext.WordInfo;
import com.android.inputmethod.latin.settings.SpacingAndPunctuations; import com.android.inputmethod.latin.settings.SpacingAndPunctuations;
public final class PrevWordsInfoUtils { public final class NgramContextUtils {
private PrevWordsInfoUtils() { private NgramContextUtils() {
// Intentional empty constructor for utility class. // Intentional empty constructor for utility class.
} }
@ -44,7 +44,7 @@ public final class PrevWordsInfoUtils {
// (n = 2) "abc def|" -> beginning-of-sentence, abc // (n = 2) "abc def|" -> beginning-of-sentence, abc
// (n = 2) "abc def |" -> beginning-of-sentence, abc // (n = 2) "abc def |" -> beginning-of-sentence, abc
// (n = 2) "abc 'def|" -> empty. The context is different from "abc def", but we cannot // (n = 2) "abc 'def|" -> empty. The context is different from "abc def", but we cannot
// represent this situation using PrevWordsInfo. See TODO in the method. // represent this situation using NgramContext. See TODO in the method.
// TODO: The next example's result should be "abc, def". This have to be fixed before we // TODO: The next example's result should be "abc, def". This have to be fixed before we
// retrieve the prior context of Beginning-of-Sentence. // retrieve the prior context of Beginning-of-Sentence.
// (n = 2) "abc def. |" -> beginning-of-sentence, abc // (n = 2) "abc def. |" -> beginning-of-sentence, abc
@ -52,9 +52,9 @@ public final class PrevWordsInfoUtils {
// (n = 2) "abc|" -> beginning-of-sentence // (n = 2) "abc|" -> beginning-of-sentence
// (n = 2) "abc |" -> beginning-of-sentence // (n = 2) "abc |" -> beginning-of-sentence
// (n = 2) "abc. def|" -> beginning-of-sentence // (n = 2) "abc. def|" -> beginning-of-sentence
public static PrevWordsInfo getPrevWordsInfoFromNthPreviousWord(final CharSequence prev, public static NgramContext getNgramContextFromNthPreviousWord(final CharSequence prev,
final SpacingAndPunctuations spacingAndPunctuations, final int n) { final SpacingAndPunctuations spacingAndPunctuations, final int n) {
if (prev == null) return PrevWordsInfo.EMPTY_PREV_WORDS_INFO; if (prev == null) return NgramContext.EMPTY_PREV_WORDS_INFO;
final String[] w = SPACE_REGEX.split(prev); final String[] w = SPACE_REGEX.split(prev);
final WordInfo[] prevWordsInfo = new WordInfo[Constants.MAX_PREV_WORD_COUNT_FOR_N_GRAM]; final WordInfo[] prevWordsInfo = new WordInfo[Constants.MAX_PREV_WORD_COUNT_FOR_N_GRAM];
Arrays.fill(prevWordsInfo, WordInfo.EMPTY_WORD_INFO); Arrays.fill(prevWordsInfo, WordInfo.EMPTY_WORD_INFO);
@ -98,6 +98,6 @@ public final class PrevWordsInfoUtils {
} }
prevWordsInfo[i] = new WordInfo(focusedWord); prevWordsInfo[i] = new WordInfo(focusedWord);
} }
return new PrevWordsInfo(prevWordsInfo); return new NgramContext(prevWordsInfo);
} }
} }

View file

@ -31,7 +31,7 @@ import java.util.TreeSet;
public final class SuggestionResults extends TreeSet<SuggestedWordInfo> { public final class SuggestionResults extends TreeSet<SuggestedWordInfo> {
public final ArrayList<SuggestedWordInfo> mRawSuggestions; public final ArrayList<SuggestedWordInfo> mRawSuggestions;
// TODO: Instead of a boolean , we may want to include the context of this suggestion results, // TODO: Instead of a boolean , we may want to include the context of this suggestion results,
// such as {@link PrevWordsInfo}. // such as {@link NgramContext}.
public final boolean mIsBeginningOfSentence; public final boolean mIsBeginningOfSentence;
private final int mCapacity; private final int mCapacity;

View file

@ -20,7 +20,7 @@ import android.test.AndroidTestCase;
import android.test.suitebuilder.annotation.LargeTest; import android.test.suitebuilder.annotation.LargeTest;
import android.util.Pair; import android.util.Pair;
import com.android.inputmethod.latin.PrevWordsInfo.WordInfo; import com.android.inputmethod.latin.NgramContext.WordInfo;
import com.android.inputmethod.latin.makedict.BinaryDictIOUtils; import com.android.inputmethod.latin.makedict.BinaryDictIOUtils;
import com.android.inputmethod.latin.makedict.CodePointUtils; import com.android.inputmethod.latin.makedict.CodePointUtils;
import com.android.inputmethod.latin.makedict.DictDecoder; import com.android.inputmethod.latin.makedict.DictDecoder;
@ -78,13 +78,13 @@ public class BinaryDictionaryDecayingTests extends AndroidTestCase {
private void addBigramWords(final BinaryDictionary binaryDictionary, final String word0, private void addBigramWords(final BinaryDictionary binaryDictionary, final String word0,
final String word1, final int probability) { final String word1, final int probability) {
binaryDictionary.addNgramEntry(new PrevWordsInfo(new WordInfo(word0)), word1, probability, binaryDictionary.addNgramEntry(new NgramContext(new WordInfo(word0)), word1, probability,
mCurrentTime /* timestamp */); mCurrentTime /* timestamp */);
} }
private static boolean isValidBigram(final BinaryDictionary binaryDictionary, private static boolean isValidBigram(final BinaryDictionary binaryDictionary,
final String word0, final String word1) { final String word0, final String word1) {
return binaryDictionary.isValidNgram(new PrevWordsInfo(new WordInfo(word0)), word1); return binaryDictionary.isValidNgram(new NgramContext(new WordInfo(word0)), word1);
} }
private void forcePassingShortTime(final BinaryDictionary binaryDictionary) { private void forcePassingShortTime(final BinaryDictionary binaryDictionary) {
@ -661,31 +661,31 @@ public class BinaryDictionaryDecayingTests extends AndroidTestCase {
BinaryDictionary.NOT_A_PROBABILITY /* shortcutProbability */, BinaryDictionary.NOT_A_PROBABILITY /* shortcutProbability */,
true /* isBeginningOfSentence */, true /* isNotAWord */, false /* isBlacklisted */, true /* isBeginningOfSentence */, true /* isNotAWord */, false /* isBlacklisted */,
mCurrentTime); mCurrentTime);
final PrevWordsInfo prevWordsInfoStartOfSentence = PrevWordsInfo.BEGINNING_OF_SENTENCE; final NgramContext beginningOfSentenceContext = NgramContext.BEGINNING_OF_SENTENCE;
addUnigramWord(binaryDictionary, "aaa", DUMMY_PROBABILITY); addUnigramWord(binaryDictionary, "aaa", DUMMY_PROBABILITY);
binaryDictionary.addNgramEntry(prevWordsInfoStartOfSentence, "aaa", DUMMY_PROBABILITY, binaryDictionary.addNgramEntry(beginningOfSentenceContext, "aaa", DUMMY_PROBABILITY,
mCurrentTime); mCurrentTime);
assertTrue(binaryDictionary.isValidNgram(prevWordsInfoStartOfSentence, "aaa")); assertTrue(binaryDictionary.isValidNgram(beginningOfSentenceContext, "aaa"));
binaryDictionary.addNgramEntry(prevWordsInfoStartOfSentence, "aaa", DUMMY_PROBABILITY, binaryDictionary.addNgramEntry(beginningOfSentenceContext, "aaa", DUMMY_PROBABILITY,
mCurrentTime); mCurrentTime);
addUnigramWord(binaryDictionary, "bbb", DUMMY_PROBABILITY); addUnigramWord(binaryDictionary, "bbb", DUMMY_PROBABILITY);
binaryDictionary.addNgramEntry(prevWordsInfoStartOfSentence, "bbb", DUMMY_PROBABILITY, binaryDictionary.addNgramEntry(beginningOfSentenceContext, "bbb", DUMMY_PROBABILITY,
mCurrentTime); mCurrentTime);
assertTrue(binaryDictionary.isValidNgram(prevWordsInfoStartOfSentence, "aaa")); assertTrue(binaryDictionary.isValidNgram(beginningOfSentenceContext, "aaa"));
assertTrue(binaryDictionary.isValidNgram(prevWordsInfoStartOfSentence, "bbb")); assertTrue(binaryDictionary.isValidNgram(beginningOfSentenceContext, "bbb"));
forcePassingLongTime(binaryDictionary); forcePassingLongTime(binaryDictionary);
assertFalse(binaryDictionary.isValidNgram(prevWordsInfoStartOfSentence, "aaa")); assertFalse(binaryDictionary.isValidNgram(beginningOfSentenceContext, "aaa"));
assertFalse(binaryDictionary.isValidNgram(prevWordsInfoStartOfSentence, "bbb")); assertFalse(binaryDictionary.isValidNgram(beginningOfSentenceContext, "bbb"));
addUnigramWord(binaryDictionary, "aaa", DUMMY_PROBABILITY); addUnigramWord(binaryDictionary, "aaa", DUMMY_PROBABILITY);
binaryDictionary.addNgramEntry(prevWordsInfoStartOfSentence, "aaa", DUMMY_PROBABILITY, binaryDictionary.addNgramEntry(beginningOfSentenceContext, "aaa", DUMMY_PROBABILITY,
mCurrentTime); mCurrentTime);
addUnigramWord(binaryDictionary, "bbb", DUMMY_PROBABILITY); addUnigramWord(binaryDictionary, "bbb", DUMMY_PROBABILITY);
binaryDictionary.addNgramEntry(prevWordsInfoStartOfSentence, "bbb", DUMMY_PROBABILITY, binaryDictionary.addNgramEntry(beginningOfSentenceContext, "bbb", DUMMY_PROBABILITY,
mCurrentTime); mCurrentTime);
assertTrue(binaryDictionary.isValidNgram(prevWordsInfoStartOfSentence, "aaa")); assertTrue(binaryDictionary.isValidNgram(beginningOfSentenceContext, "aaa"));
assertTrue(binaryDictionary.isValidNgram(prevWordsInfoStartOfSentence, "bbb")); assertTrue(binaryDictionary.isValidNgram(beginningOfSentenceContext, "bbb"));
binaryDictionary.close(); binaryDictionary.close();
dictFile.delete(); dictFile.delete();
} }

View file

@ -21,7 +21,7 @@ import android.test.suitebuilder.annotation.LargeTest;
import android.text.TextUtils; import android.text.TextUtils;
import android.util.Pair; import android.util.Pair;
import com.android.inputmethod.latin.PrevWordsInfo.WordInfo; import com.android.inputmethod.latin.NgramContext.WordInfo;
import com.android.inputmethod.latin.makedict.CodePointUtils; import com.android.inputmethod.latin.makedict.CodePointUtils;
import com.android.inputmethod.latin.makedict.FormatSpec; import com.android.inputmethod.latin.makedict.FormatSpec;
import com.android.inputmethod.latin.makedict.WeightedString; import com.android.inputmethod.latin.makedict.WeightedString;
@ -208,45 +208,45 @@ public class BinaryDictionaryTests extends AndroidTestCase {
private static void addBigramWords(final BinaryDictionary binaryDictionary, final String word0, private static void addBigramWords(final BinaryDictionary binaryDictionary, final String word0,
final String word1, final int probability) { final String word1, final int probability) {
binaryDictionary.addNgramEntry(new PrevWordsInfo(new WordInfo(word0)), word1, probability, binaryDictionary.addNgramEntry(new NgramContext(new WordInfo(word0)), word1, probability,
BinaryDictionary.NOT_A_VALID_TIMESTAMP /* timestamp */); BinaryDictionary.NOT_A_VALID_TIMESTAMP /* timestamp */);
} }
private static void addTrigramEntry(final BinaryDictionary binaryDictionary, final String word0, private static void addTrigramEntry(final BinaryDictionary binaryDictionary, final String word0,
final String word1, final String word2, final int probability) { final String word1, final String word2, final int probability) {
final PrevWordsInfo prevWordsInfo = final NgramContext ngramContext =
new PrevWordsInfo(new WordInfo[] { new WordInfo(word1), new WordInfo(word0) } ); new NgramContext(new WordInfo[] { new WordInfo(word1), new WordInfo(word0) } );
binaryDictionary.addNgramEntry(prevWordsInfo, word2, probability, binaryDictionary.addNgramEntry(ngramContext, word2, probability,
BinaryDictionary.NOT_A_VALID_TIMESTAMP /* timestamp */); BinaryDictionary.NOT_A_VALID_TIMESTAMP /* timestamp */);
} }
private static boolean isValidBigram(final BinaryDictionary binaryDictionary, private static boolean isValidBigram(final BinaryDictionary binaryDictionary,
final String word0, final String word1) { final String word0, final String word1) {
return binaryDictionary.isValidNgram(new PrevWordsInfo(new WordInfo(word0)), word1); return binaryDictionary.isValidNgram(new NgramContext(new WordInfo(word0)), word1);
} }
private static void removeBigramEntry(final BinaryDictionary binaryDictionary, private static void removeBigramEntry(final BinaryDictionary binaryDictionary,
final String word0, final String word1) { final String word0, final String word1) {
binaryDictionary.removeNgramEntry(new PrevWordsInfo(new WordInfo(word0)), word1); binaryDictionary.removeNgramEntry(new NgramContext(new WordInfo(word0)), word1);
} }
private static void removeTrigramEntry(final BinaryDictionary binaryDictionary, private static void removeTrigramEntry(final BinaryDictionary binaryDictionary,
final String word0, final String word1, final String word2) { final String word0, final String word1, final String word2) {
final PrevWordsInfo prevWordsInfo = final NgramContext ngramContext =
new PrevWordsInfo(new WordInfo[] { new WordInfo(word1), new WordInfo(word0) } ); new NgramContext(new WordInfo[] { new WordInfo(word1), new WordInfo(word0) } );
binaryDictionary.removeNgramEntry(prevWordsInfo, word2); binaryDictionary.removeNgramEntry(ngramContext, word2);
} }
private static int getBigramProbability(final BinaryDictionary binaryDictionary, private static int getBigramProbability(final BinaryDictionary binaryDictionary,
final String word0, final String word1) { final String word0, final String word1) {
return binaryDictionary.getNgramProbability(new PrevWordsInfo(new WordInfo(word0)), word1); return binaryDictionary.getNgramProbability(new NgramContext(new WordInfo(word0)), word1);
} }
private static int getTrigramProbability(final BinaryDictionary binaryDictionary, private static int getTrigramProbability(final BinaryDictionary binaryDictionary,
final String word0, final String word1, final String word2) { final String word0, final String word1, final String word2) {
final PrevWordsInfo prevWordsInfo = final NgramContext ngramContext =
new PrevWordsInfo(new WordInfo[] { new WordInfo(word1), new WordInfo(word0) } ); new NgramContext(new WordInfo[] { new WordInfo(word1), new WordInfo(word0) } );
return binaryDictionary.getNgramProbability(prevWordsInfo, word2); return binaryDictionary.getNgramProbability(ngramContext, word2);
} }
public void testAddUnigramWord() { public void testAddUnigramWord() {
@ -1422,7 +1422,7 @@ public class BinaryDictionaryTests extends AndroidTestCase {
binaryDictionary.addUnigramEntry("ddd", unigramProbability, null /* shortcutTarget */, binaryDictionary.addUnigramEntry("ddd", unigramProbability, null /* shortcutTarget */,
Dictionary.NOT_A_PROBABILITY, false /* isBeginningOfSentence */, Dictionary.NOT_A_PROBABILITY, false /* isBeginningOfSentence */,
true /* isNotAWord */, true /* isBlacklisted */, 0 /* timestamp */); true /* isNotAWord */, true /* isBlacklisted */, 0 /* timestamp */);
binaryDictionary.addNgramEntry(PrevWordsInfo.BEGINNING_OF_SENTENCE, binaryDictionary.addNgramEntry(NgramContext.BEGINNING_OF_SENTENCE,
"aaa", bigramProbability, 0 /* timestamp */); "aaa", bigramProbability, 0 /* timestamp */);
assertEquals(unigramProbability, binaryDictionary.getFrequency("aaa")); assertEquals(unigramProbability, binaryDictionary.getFrequency("aaa"));
assertEquals(unigramProbability, binaryDictionary.getFrequency("bbb")); assertEquals(unigramProbability, binaryDictionary.getFrequency("bbb"));
@ -1436,7 +1436,7 @@ public class BinaryDictionaryTests extends AndroidTestCase {
if (canCheckBigramProbability(toFormatVersion)) { if (canCheckBigramProbability(toFormatVersion)) {
assertEquals(bigramProbability, getBigramProbability(binaryDictionary, "aaa", "bbb")); assertEquals(bigramProbability, getBigramProbability(binaryDictionary, "aaa", "bbb"));
assertEquals(bigramProbability, binaryDictionary.getNgramProbability( assertEquals(bigramProbability, binaryDictionary.getNgramProbability(
PrevWordsInfo.BEGINNING_OF_SENTENCE, "aaa")); NgramContext.BEGINNING_OF_SENTENCE, "aaa"));
} }
assertTrue(isValidBigram(binaryDictionary, "aaa", "bbb")); assertTrue(isValidBigram(binaryDictionary, "aaa", "bbb"));
WordProperty wordProperty = binaryDictionary.getWordProperty("ccc", WordProperty wordProperty = binaryDictionary.getWordProperty("ccc",
@ -1546,23 +1546,23 @@ public class BinaryDictionaryTests extends AndroidTestCase {
0 /* offset */, dictFile.length(), true /* useFullEditDistance */, 0 /* offset */, dictFile.length(), true /* useFullEditDistance */,
Locale.getDefault(), TEST_LOCALE, true /* isUpdatable */); Locale.getDefault(), TEST_LOCALE, true /* isUpdatable */);
final int dummyProbability = 0; final int dummyProbability = 0;
final PrevWordsInfo prevWordsInfoBeginningOfSentence = PrevWordsInfo.BEGINNING_OF_SENTENCE; final NgramContext beginningOfSentenceContext = NgramContext.BEGINNING_OF_SENTENCE;
final int bigramProbability = 200; final int bigramProbability = 200;
addUnigramWord(binaryDictionary, "aaa", dummyProbability); addUnigramWord(binaryDictionary, "aaa", dummyProbability);
binaryDictionary.addNgramEntry(prevWordsInfoBeginningOfSentence, "aaa", bigramProbability, binaryDictionary.addNgramEntry(beginningOfSentenceContext, "aaa", bigramProbability,
BinaryDictionary.NOT_A_VALID_TIMESTAMP /* timestamp */); BinaryDictionary.NOT_A_VALID_TIMESTAMP /* timestamp */);
assertEquals(bigramProbability, assertEquals(bigramProbability,
binaryDictionary.getNgramProbability(prevWordsInfoBeginningOfSentence, "aaa")); binaryDictionary.getNgramProbability(beginningOfSentenceContext, "aaa"));
binaryDictionary.addNgramEntry(prevWordsInfoBeginningOfSentence, "aaa", bigramProbability, binaryDictionary.addNgramEntry(beginningOfSentenceContext, "aaa", bigramProbability,
BinaryDictionary.NOT_A_VALID_TIMESTAMP /* timestamp */); BinaryDictionary.NOT_A_VALID_TIMESTAMP /* timestamp */);
addUnigramWord(binaryDictionary, "bbb", dummyProbability); addUnigramWord(binaryDictionary, "bbb", dummyProbability);
binaryDictionary.addNgramEntry(prevWordsInfoBeginningOfSentence, "bbb", bigramProbability, binaryDictionary.addNgramEntry(beginningOfSentenceContext, "bbb", bigramProbability,
BinaryDictionary.NOT_A_VALID_TIMESTAMP /* timestamp */); BinaryDictionary.NOT_A_VALID_TIMESTAMP /* timestamp */);
binaryDictionary.flushWithGC(); binaryDictionary.flushWithGC();
assertEquals(bigramProbability, assertEquals(bigramProbability,
binaryDictionary.getNgramProbability(prevWordsInfoBeginningOfSentence, "aaa")); binaryDictionary.getNgramProbability(beginningOfSentenceContext, "aaa"));
assertEquals(bigramProbability, assertEquals(bigramProbability,
binaryDictionary.getNgramProbability(prevWordsInfoBeginningOfSentence, "bbb")); binaryDictionary.getNgramProbability(beginningOfSentenceContext, "bbb"));
} }
public void testGetMaxFrequencyOfExactMatches() { public void testGetMaxFrequencyOfExactMatches() {

View file

@ -0,0 +1,66 @@
/*
* Copyright (C) 2014 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.android.inputmethod.latin;
import com.android.inputmethod.latin.NgramContext.WordInfo;
import android.test.AndroidTestCase;
import android.test.suitebuilder.annotation.SmallTest;
@SmallTest
public class NgramContextTests extends AndroidTestCase {
public void testConstruct() {
assertEquals(new NgramContext(new WordInfo("a")), new NgramContext(new WordInfo("a")));
assertEquals(new NgramContext(WordInfo.BEGINNING_OF_SENTENCE),
new NgramContext(WordInfo.BEGINNING_OF_SENTENCE));
assertEquals(new NgramContext(WordInfo.EMPTY_WORD_INFO),
new NgramContext(WordInfo.EMPTY_WORD_INFO));
assertEquals(new NgramContext(WordInfo.EMPTY_WORD_INFO),
new NgramContext(WordInfo.EMPTY_WORD_INFO));
}
public void testIsBeginningOfSentenceContext() {
assertFalse(new NgramContext().isBeginningOfSentenceContext());
assertTrue(new NgramContext(WordInfo.BEGINNING_OF_SENTENCE)
.isBeginningOfSentenceContext());
assertTrue(NgramContext.BEGINNING_OF_SENTENCE.isBeginningOfSentenceContext());
assertFalse(new NgramContext(new WordInfo("a")).isBeginningOfSentenceContext());
assertFalse(new NgramContext(new WordInfo("")).isBeginningOfSentenceContext());
assertFalse(new NgramContext(WordInfo.EMPTY_WORD_INFO).isBeginningOfSentenceContext());
assertTrue(new NgramContext(WordInfo.BEGINNING_OF_SENTENCE, new WordInfo("a"))
.isBeginningOfSentenceContext());
assertFalse(new NgramContext(new WordInfo("a"), WordInfo.BEGINNING_OF_SENTENCE)
.isBeginningOfSentenceContext());
assertFalse(new NgramContext(WordInfo.EMPTY_WORD_INFO, WordInfo.BEGINNING_OF_SENTENCE)
.isBeginningOfSentenceContext());
}
public void testGetNextNgramContext() {
final NgramContext ngramContext_a = new NgramContext(new WordInfo("a"));
final NgramContext ngramContext_b_a =
ngramContext_a.getNextNgramContext(new WordInfo("b"));
assertEquals("b", ngramContext_b_a.getNthPrevWord(1));
assertEquals("a", ngramContext_b_a.getNthPrevWord(2));
final NgramContext ngramContext_bos_b =
ngramContext_b_a.getNextNgramContext(WordInfo.BEGINNING_OF_SENTENCE);
assertTrue(ngramContext_bos_b.isBeginningOfSentenceContext());
assertEquals("b", ngramContext_bos_b.getNthPrevWord(2));
final NgramContext ngramContext_c_bos =
ngramContext_b_a.getNextNgramContext(new WordInfo("c"));
assertEquals("c", ngramContext_c_bos.getNthPrevWord(1));
}
}

View file

@ -1,66 +0,0 @@
/*
* Copyright (C) 2014 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.android.inputmethod.latin;
import com.android.inputmethod.latin.PrevWordsInfo.WordInfo;
import android.test.AndroidTestCase;
import android.test.suitebuilder.annotation.SmallTest;
@SmallTest
public class PrevWordsInfoTests extends AndroidTestCase {
public void testConstruct() {
assertEquals(new PrevWordsInfo(new WordInfo("a")), new PrevWordsInfo(new WordInfo("a")));
assertEquals(new PrevWordsInfo(WordInfo.BEGINNING_OF_SENTENCE),
new PrevWordsInfo(WordInfo.BEGINNING_OF_SENTENCE));
assertEquals(new PrevWordsInfo(WordInfo.EMPTY_WORD_INFO),
new PrevWordsInfo(WordInfo.EMPTY_WORD_INFO));
assertEquals(new PrevWordsInfo(WordInfo.EMPTY_WORD_INFO),
new PrevWordsInfo(WordInfo.EMPTY_WORD_INFO));
}
public void testIsBeginningOfSentenceContext() {
assertFalse(new PrevWordsInfo().isBeginningOfSentenceContext());
assertTrue(new PrevWordsInfo(WordInfo.BEGINNING_OF_SENTENCE)
.isBeginningOfSentenceContext());
assertTrue(PrevWordsInfo.BEGINNING_OF_SENTENCE.isBeginningOfSentenceContext());
assertFalse(new PrevWordsInfo(new WordInfo("a")).isBeginningOfSentenceContext());
assertFalse(new PrevWordsInfo(new WordInfo("")).isBeginningOfSentenceContext());
assertFalse(new PrevWordsInfo(WordInfo.EMPTY_WORD_INFO).isBeginningOfSentenceContext());
assertTrue(new PrevWordsInfo(WordInfo.BEGINNING_OF_SENTENCE, new WordInfo("a"))
.isBeginningOfSentenceContext());
assertFalse(new PrevWordsInfo(new WordInfo("a"), WordInfo.BEGINNING_OF_SENTENCE)
.isBeginningOfSentenceContext());
assertFalse(new PrevWordsInfo(WordInfo.EMPTY_WORD_INFO, WordInfo.BEGINNING_OF_SENTENCE)
.isBeginningOfSentenceContext());
}
public void testGetNextPrevWordsInfo() {
final PrevWordsInfo prevWordsInfo_a = new PrevWordsInfo(new WordInfo("a"));
final PrevWordsInfo prevWordsInfo_b_a =
prevWordsInfo_a.getNextPrevWordsInfo(new WordInfo("b"));
assertEquals("b", prevWordsInfo_b_a.getNthPrevWord(1));
assertEquals("a", prevWordsInfo_b_a.getNthPrevWord(2));
final PrevWordsInfo prevWordsInfo_bos_b =
prevWordsInfo_b_a.getNextPrevWordsInfo(WordInfo.BEGINNING_OF_SENTENCE);
assertTrue(prevWordsInfo_bos_b.isBeginningOfSentenceContext());
assertEquals("b", prevWordsInfo_bos_b.getNthPrevWord(2));
final PrevWordsInfo prevWordsInfo_c_bos =
prevWordsInfo_b_a.getNextPrevWordsInfo(new WordInfo("c"));
assertEquals("c", prevWordsInfo_c_bos.getNthPrevWord(1));
}
}

View file

@ -31,7 +31,7 @@ import android.view.inputmethod.InputConnection;
import android.view.inputmethod.InputConnectionWrapper; import android.view.inputmethod.InputConnectionWrapper;
import com.android.inputmethod.latin.settings.SpacingAndPunctuations; import com.android.inputmethod.latin.settings.SpacingAndPunctuations;
import com.android.inputmethod.latin.utils.PrevWordsInfoUtils; import com.android.inputmethod.latin.utils.NgramContextUtils;
import com.android.inputmethod.latin.utils.RunInLocale; import com.android.inputmethod.latin.utils.RunInLocale;
import com.android.inputmethod.latin.utils.ScriptUtils; import com.android.inputmethod.latin.utils.ScriptUtils;
import com.android.inputmethod.latin.utils.StringUtils; import com.android.inputmethod.latin.utils.StringUtils;
@ -157,24 +157,24 @@ public class RichInputConnectionAndTextRangeTests extends AndroidTestCase {
*/ */
public void testGetPreviousWord() { public void testGetPreviousWord() {
// If one of the following cases breaks, the bigram suggestions won't work. // If one of the following cases breaks, the bigram suggestions won't work.
assertEquals(PrevWordsInfoUtils.getPrevWordsInfoFromNthPreviousWord( assertEquals(NgramContextUtils.getNgramContextFromNthPreviousWord(
"abc def", mSpacingAndPunctuations, 2).getNthPrevWord(1), "abc"); "abc def", mSpacingAndPunctuations, 2).getNthPrevWord(1), "abc");
assertEquals(PrevWordsInfoUtils.getPrevWordsInfoFromNthPreviousWord( assertEquals(NgramContextUtils.getNgramContextFromNthPreviousWord(
"abc", mSpacingAndPunctuations, 2), PrevWordsInfo.BEGINNING_OF_SENTENCE); "abc", mSpacingAndPunctuations, 2), NgramContext.BEGINNING_OF_SENTENCE);
assertEquals(PrevWordsInfoUtils.getPrevWordsInfoFromNthPreviousWord( assertEquals(NgramContextUtils.getNgramContextFromNthPreviousWord(
"abc. def", mSpacingAndPunctuations, 2), PrevWordsInfo.BEGINNING_OF_SENTENCE); "abc. def", mSpacingAndPunctuations, 2), NgramContext.BEGINNING_OF_SENTENCE);
assertFalse(PrevWordsInfoUtils.getPrevWordsInfoFromNthPreviousWord( assertFalse(NgramContextUtils.getNgramContextFromNthPreviousWord(
"abc def", mSpacingAndPunctuations, 2).isBeginningOfSentenceContext()); "abc def", mSpacingAndPunctuations, 2).isBeginningOfSentenceContext());
assertTrue(PrevWordsInfoUtils.getPrevWordsInfoFromNthPreviousWord( assertTrue(NgramContextUtils.getNgramContextFromNthPreviousWord(
"abc", mSpacingAndPunctuations, 2).isBeginningOfSentenceContext()); "abc", mSpacingAndPunctuations, 2).isBeginningOfSentenceContext());
// For n-gram // For n-gram
assertEquals(PrevWordsInfoUtils.getPrevWordsInfoFromNthPreviousWord( assertEquals(NgramContextUtils.getNgramContextFromNthPreviousWord(
"abc def", mSpacingAndPunctuations, 1).getNthPrevWord(1), "def"); "abc def", mSpacingAndPunctuations, 1).getNthPrevWord(1), "def");
assertEquals(PrevWordsInfoUtils.getPrevWordsInfoFromNthPreviousWord( assertEquals(NgramContextUtils.getNgramContextFromNthPreviousWord(
"abc def", mSpacingAndPunctuations, 1).getNthPrevWord(2), "abc"); "abc def", mSpacingAndPunctuations, 1).getNthPrevWord(2), "abc");
assertTrue(PrevWordsInfoUtils.getPrevWordsInfoFromNthPreviousWord( assertTrue(NgramContextUtils.getNgramContextFromNthPreviousWord(
"abc def", mSpacingAndPunctuations, 2).isNthPrevWordBeginningOfSontence(2)); "abc def", mSpacingAndPunctuations, 2).isNthPrevWordBeginningOfSontence(2));
// The following tests reflect the current behavior of the function // The following tests reflect the current behavior of the function
@ -184,33 +184,33 @@ public class RichInputConnectionAndTextRangeTests extends AndroidTestCase {
// this function if needed - especially since it does not seem very // this function if needed - especially since it does not seem very
// logical. These tests are just there to catch any unintentional // logical. These tests are just there to catch any unintentional
// changes in the behavior of the RichInputConnection#getPreviousWord method. // changes in the behavior of the RichInputConnection#getPreviousWord method.
assertEquals(PrevWordsInfoUtils.getPrevWordsInfoFromNthPreviousWord( assertEquals(NgramContextUtils.getNgramContextFromNthPreviousWord(
"abc def ", mSpacingAndPunctuations, 2).getNthPrevWord(1), "abc"); "abc def ", mSpacingAndPunctuations, 2).getNthPrevWord(1), "abc");
assertEquals(PrevWordsInfoUtils.getPrevWordsInfoFromNthPreviousWord( assertEquals(NgramContextUtils.getNgramContextFromNthPreviousWord(
"abc def.", mSpacingAndPunctuations, 2).getNthPrevWord(1), "abc"); "abc def.", mSpacingAndPunctuations, 2).getNthPrevWord(1), "abc");
assertEquals(PrevWordsInfoUtils.getPrevWordsInfoFromNthPreviousWord( assertEquals(NgramContextUtils.getNgramContextFromNthPreviousWord(
"abc def .", mSpacingAndPunctuations, 2).getNthPrevWord(1), "def"); "abc def .", mSpacingAndPunctuations, 2).getNthPrevWord(1), "def");
assertTrue(PrevWordsInfoUtils.getPrevWordsInfoFromNthPreviousWord( assertTrue(NgramContextUtils.getNgramContextFromNthPreviousWord(
"abc ", mSpacingAndPunctuations, 2).isBeginningOfSentenceContext()); "abc ", mSpacingAndPunctuations, 2).isBeginningOfSentenceContext());
assertEquals(PrevWordsInfoUtils.getPrevWordsInfoFromNthPreviousWord( assertEquals(NgramContextUtils.getNgramContextFromNthPreviousWord(
"abc def", mSpacingAndPunctuations, 1).getNthPrevWord(1), "def"); "abc def", mSpacingAndPunctuations, 1).getNthPrevWord(1), "def");
assertEquals(PrevWordsInfoUtils.getPrevWordsInfoFromNthPreviousWord( assertEquals(NgramContextUtils.getNgramContextFromNthPreviousWord(
"abc def ", mSpacingAndPunctuations, 1).getNthPrevWord(1), "def"); "abc def ", mSpacingAndPunctuations, 1).getNthPrevWord(1), "def");
assertEquals(PrevWordsInfoUtils.getPrevWordsInfoFromNthPreviousWord( assertEquals(NgramContextUtils.getNgramContextFromNthPreviousWord(
"abc 'def", mSpacingAndPunctuations, 1).getNthPrevWord(1), "'def"); "abc 'def", mSpacingAndPunctuations, 1).getNthPrevWord(1), "'def");
assertEquals(PrevWordsInfoUtils.getPrevWordsInfoFromNthPreviousWord( assertEquals(NgramContextUtils.getNgramContextFromNthPreviousWord(
"abc def.", mSpacingAndPunctuations, 1), PrevWordsInfo.BEGINNING_OF_SENTENCE); "abc def.", mSpacingAndPunctuations, 1), NgramContext.BEGINNING_OF_SENTENCE);
assertEquals(PrevWordsInfoUtils.getPrevWordsInfoFromNthPreviousWord( assertEquals(NgramContextUtils.getNgramContextFromNthPreviousWord(
"abc def .", mSpacingAndPunctuations, 1), PrevWordsInfo.BEGINNING_OF_SENTENCE); "abc def .", mSpacingAndPunctuations, 1), NgramContext.BEGINNING_OF_SENTENCE);
assertEquals(PrevWordsInfoUtils.getPrevWordsInfoFromNthPreviousWord( assertEquals(NgramContextUtils.getNgramContextFromNthPreviousWord(
"abc, def", mSpacingAndPunctuations, 2), PrevWordsInfo.EMPTY_PREV_WORDS_INFO); "abc, def", mSpacingAndPunctuations, 2), NgramContext.EMPTY_PREV_WORDS_INFO);
assertEquals(PrevWordsInfoUtils.getPrevWordsInfoFromNthPreviousWord( assertEquals(NgramContextUtils.getNgramContextFromNthPreviousWord(
"abc? def", mSpacingAndPunctuations, 2), PrevWordsInfo.EMPTY_PREV_WORDS_INFO); "abc? def", mSpacingAndPunctuations, 2), NgramContext.EMPTY_PREV_WORDS_INFO);
assertEquals(PrevWordsInfoUtils.getPrevWordsInfoFromNthPreviousWord( assertEquals(NgramContextUtils.getNgramContextFromNthPreviousWord(
"abc! def", mSpacingAndPunctuations, 2), PrevWordsInfo.EMPTY_PREV_WORDS_INFO); "abc! def", mSpacingAndPunctuations, 2), NgramContext.EMPTY_PREV_WORDS_INFO);
assertEquals(PrevWordsInfoUtils.getPrevWordsInfoFromNthPreviousWord( assertEquals(NgramContextUtils.getNgramContextFromNthPreviousWord(
"abc 'def", mSpacingAndPunctuations, 2), PrevWordsInfo.EMPTY_PREV_WORDS_INFO); "abc 'def", mSpacingAndPunctuations, 2), NgramContext.EMPTY_PREV_WORDS_INFO);
} }
public void testGetWordRangeAtCursor() { public void testGetWordRangeAtCursor() {

View file

@ -19,7 +19,7 @@ package com.android.inputmethod.latin.makedict;
import com.android.inputmethod.annotations.UsedForTesting; import com.android.inputmethod.annotations.UsedForTesting;
import com.android.inputmethod.latin.BinaryDictionary; import com.android.inputmethod.latin.BinaryDictionary;
import com.android.inputmethod.latin.Dictionary; import com.android.inputmethod.latin.Dictionary;
import com.android.inputmethod.latin.PrevWordsInfo; import com.android.inputmethod.latin.NgramContext;
import com.android.inputmethod.latin.makedict.FormatSpec.FormatOptions; import com.android.inputmethod.latin.makedict.FormatSpec.FormatOptions;
import com.android.inputmethod.latin.makedict.FusionDictionary.PtNode; import com.android.inputmethod.latin.makedict.FusionDictionary.PtNode;
import com.android.inputmethod.latin.utils.BinaryDictionaryUtils; import com.android.inputmethod.latin.utils.BinaryDictionaryUtils;
@ -104,12 +104,12 @@ public class Ver4DictEncoder implements DictEncoder {
for (final WordProperty word0Property : dict) { for (final WordProperty word0Property : dict) {
if (null == word0Property.mBigrams) continue; if (null == word0Property.mBigrams) continue;
for (final WeightedString word1 : word0Property.mBigrams) { for (final WeightedString word1 : word0Property.mBigrams) {
final PrevWordsInfo prevWordsInfo = final NgramContext ngramContext =
new PrevWordsInfo(new PrevWordsInfo.WordInfo(word0Property.mWord)); new NgramContext(new NgramContext.WordInfo(word0Property.mWord));
if (!binaryDict.addNgramEntry(prevWordsInfo, word1.mWord, if (!binaryDict.addNgramEntry(ngramContext, word1.mWord,
word1.getProbability(), 0 /* timestamp */)) { word1.getProbability(), 0 /* timestamp */)) {
MakedictLog.e("Cannot add n-gram entry for " MakedictLog.e("Cannot add n-gram entry for "
+ prevWordsInfo + " -> " + word1.mWord); + ngramContext + " -> " + word1.mWord);
return; return;
} }
if (binaryDict.needsToRunGC(true /* mindsBlockByGC */)) { if (binaryDict.needsToRunGC(true /* mindsBlockByGC */)) {

View file

@ -21,8 +21,8 @@ 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.ExpandableBinaryDictionary;
import com.android.inputmethod.latin.PrevWordsInfo; import com.android.inputmethod.latin.NgramContext;
import com.android.inputmethod.latin.PrevWordsInfo.WordInfo; import com.android.inputmethod.latin.NgramContext.WordInfo;
import com.android.inputmethod.latin.utils.BinaryDictionaryUtils; import com.android.inputmethod.latin.utils.BinaryDictionaryUtils;
import com.android.inputmethod.latin.utils.DistracterFilter; import com.android.inputmethod.latin.utils.DistracterFilter;
import com.android.inputmethod.latin.utils.FileUtils; import com.android.inputmethod.latin.utils.FileUtils;
@ -160,12 +160,12 @@ public class UserHistoryDictionaryTests extends AndroidTestCase {
} }
private static void addToDict(final UserHistoryDictionary dict, final List<String> words) { private static void addToDict(final UserHistoryDictionary dict, final List<String> words) {
PrevWordsInfo prevWordsInfo = PrevWordsInfo.EMPTY_PREV_WORDS_INFO; NgramContext ngramContext = NgramContext.EMPTY_PREV_WORDS_INFO;
for (String word : words) { for (String word : words) {
UserHistoryDictionary.addToDictionary(dict, prevWordsInfo, word, true, UserHistoryDictionary.addToDictionary(dict, ngramContext, word, true,
(int)TimeUnit.MILLISECONDS.toSeconds(System.currentTimeMillis()), (int)TimeUnit.MILLISECONDS.toSeconds(System.currentTimeMillis()),
DistracterFilter.EMPTY_DISTRACTER_FILTER); DistracterFilter.EMPTY_DISTRACTER_FILTER);
prevWordsInfo = prevWordsInfo.getNextPrevWordsInfo(new WordInfo(word)); ngramContext = ngramContext.getNextNgramContext(new WordInfo(word));
} }
} }
@ -288,11 +288,11 @@ public class UserHistoryDictionaryTests extends AndroidTestCase {
clearHistory(dict); clearHistory(dict);
final List<String> words = generateWords(numberOfWords, random); final List<String> words = generateWords(numberOfWords, random);
dict.waitAllTasksForTests(); dict.waitAllTasksForTests();
PrevWordsInfo prevWordsInfo = PrevWordsInfo.EMPTY_PREV_WORDS_INFO; NgramContext ngramContext = NgramContext.EMPTY_PREV_WORDS_INFO;
for (final String word : words) { for (final String word : words) {
UserHistoryDictionary.addToDictionary(dict, prevWordsInfo, word, true, mCurrentTime, UserHistoryDictionary.addToDictionary(dict, ngramContext, word, true, mCurrentTime,
DistracterFilter.EMPTY_DISTRACTER_FILTER); DistracterFilter.EMPTY_DISTRACTER_FILTER);
prevWordsInfo = prevWordsInfo.getNextPrevWordsInfo(new WordInfo(word)); ngramContext = ngramContext.getNextNgramContext(new WordInfo(word));
dict.waitAllTasksForTests(); dict.waitAllTasksForTests();
assertTrue(dict.isInDictionary(word)); assertTrue(dict.isInDictionary(word));
} }

View file

@ -24,7 +24,7 @@ import android.test.AndroidTestCase;
import android.test.suitebuilder.annotation.LargeTest; import android.test.suitebuilder.annotation.LargeTest;
import android.view.inputmethod.InputMethodSubtype; import android.view.inputmethod.InputMethodSubtype;
import com.android.inputmethod.latin.PrevWordsInfo; import com.android.inputmethod.latin.NgramContext;
import com.android.inputmethod.latin.RichInputMethodManager; import com.android.inputmethod.latin.RichInputMethodManager;
import com.android.inputmethod.latin.utils.DistracterFilter.HandlingType; import com.android.inputmethod.latin.utils.DistracterFilter.HandlingType;
@ -58,7 +58,7 @@ public class DistracterFilterTest extends AndroidTestCase {
} }
public void testIsDistracterToWordsInDictionaries() { public void testIsDistracterToWordsInDictionaries() {
final PrevWordsInfo EMPTY_PREV_WORDS_INFO = PrevWordsInfo.EMPTY_PREV_WORDS_INFO; final NgramContext EMPTY_PREV_WORDS_INFO = NgramContext.EMPTY_PREV_WORDS_INFO;
final Locale localeEnUs = new Locale("en", "US"); final Locale localeEnUs = new Locale("en", "US");
String typedWord; String typedWord;
@ -204,7 +204,7 @@ public class DistracterFilterTest extends AndroidTestCase {
public void testGetWordHandlingType() { public void testGetWordHandlingType() {
final Locale localeEnUs = new Locale("en", "US"); final Locale localeEnUs = new Locale("en", "US");
final PrevWordsInfo EMPTY_PREV_WORDS_INFO = PrevWordsInfo.EMPTY_PREV_WORDS_INFO; final NgramContext EMPTY_PREV_WORDS_INFO = NgramContext.EMPTY_PREV_WORDS_INFO;
int handlingType = 0; int handlingType = 0;
handlingType = mDistracterFilter.getWordHandlingType(EMPTY_PREV_WORDS_INFO, handlingType = mDistracterFilter.getWordHandlingType(EMPTY_PREV_WORDS_INFO,

View file

@ -50,7 +50,7 @@ LATINIME_SRC_FILES_FOR_DICTTOOL := \
latin/Dictionary.java \ latin/Dictionary.java \
latin/InputPointers.java \ latin/InputPointers.java \
latin/LastComposedWord.java \ latin/LastComposedWord.java \
latin/PrevWordsInfo.java \ latin/NgramContext.java \
latin/SuggestedWords.java \ latin/SuggestedWords.java \
latin/WordComposer.java \ latin/WordComposer.java \
latin/settings/NativeSuggestOptions.java \ latin/settings/NativeSuggestOptions.java \