Merge "Handle user history dictionary as an ExpandableBinaryDictionary."
This commit is contained in:
commit
3d2a9af20a
5 changed files with 49 additions and 55 deletions
|
@ -74,20 +74,18 @@ public class DictionaryFacilitatorForSuggest {
|
||||||
// TODO: Remove sub dictionary members and use mSubDictMap.
|
// TODO: Remove sub dictionary members and use mSubDictMap.
|
||||||
public final ContactsBinaryDictionary mContactsDictionary;
|
public final ContactsBinaryDictionary mContactsDictionary;
|
||||||
public final UserBinaryDictionary mUserDictionary;
|
public final UserBinaryDictionary mUserDictionary;
|
||||||
public final UserHistoryDictionary mUserHistoryDictionary;
|
|
||||||
public final PersonalizationDictionary mPersonalizationDictionary;
|
public final PersonalizationDictionary mPersonalizationDictionary;
|
||||||
|
|
||||||
public Dictionaries() {
|
public Dictionaries() {
|
||||||
mLocale = null;
|
mLocale = null;
|
||||||
mContactsDictionary = null;
|
mContactsDictionary = null;
|
||||||
mUserDictionary = null;
|
mUserDictionary = null;
|
||||||
mUserHistoryDictionary = null;
|
|
||||||
mPersonalizationDictionary = null;
|
mPersonalizationDictionary = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Dictionaries(final Locale locale, final Dictionary mainDict,
|
public Dictionaries(final Locale locale, final Dictionary mainDict,
|
||||||
final ContactsBinaryDictionary contactsDict, final UserBinaryDictionary userDict,
|
final ContactsBinaryDictionary contactsDict, final UserBinaryDictionary userDict,
|
||||||
final UserHistoryDictionary userHistoryDict,
|
final ExpandableBinaryDictionary userHistoryDict,
|
||||||
final PersonalizationDictionary personalizationDict) {
|
final PersonalizationDictionary personalizationDict) {
|
||||||
mLocale = locale;
|
mLocale = locale;
|
||||||
// Main dictionary can be asynchronously loaded.
|
// Main dictionary can be asynchronously loaded.
|
||||||
|
@ -96,8 +94,7 @@ public class DictionaryFacilitatorForSuggest {
|
||||||
setSubDict(Dictionary.TYPE_CONTACTS, mContactsDictionary);
|
setSubDict(Dictionary.TYPE_CONTACTS, mContactsDictionary);
|
||||||
mUserDictionary = userDict;
|
mUserDictionary = userDict;
|
||||||
setSubDict(Dictionary.TYPE_USER, mUserDictionary);
|
setSubDict(Dictionary.TYPE_USER, mUserDictionary);
|
||||||
mUserHistoryDictionary = userHistoryDict;
|
setSubDict(Dictionary.TYPE_USER_HISTORY, userHistoryDict);
|
||||||
setSubDict(Dictionary.TYPE_USER_HISTORY, mUserHistoryDictionary);
|
|
||||||
mPersonalizationDictionary = personalizationDict;
|
mPersonalizationDictionary = personalizationDict;
|
||||||
setSubDict(Dictionary.TYPE_PERSONALIZATION, mPersonalizationDictionary);
|
setSubDict(Dictionary.TYPE_PERSONALIZATION, mPersonalizationDictionary);
|
||||||
}
|
}
|
||||||
|
@ -193,9 +190,9 @@ public class DictionaryFacilitatorForSuggest {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Open or move user history dictionary.
|
// Open or move user history dictionary.
|
||||||
final UserHistoryDictionary newUserHistoryDict;
|
final ExpandableBinaryDictionary newUserHistoryDict;
|
||||||
if (!closeUserHistoryDictionary && mDictionaries.hasDict(Dictionary.TYPE_USER_HISTORY)) {
|
if (!closeUserHistoryDictionary && mDictionaries.hasDict(Dictionary.TYPE_USER_HISTORY)) {
|
||||||
newUserHistoryDict = mDictionaries.mUserHistoryDictionary;
|
newUserHistoryDict = mDictionaries.getSubDict(Dictionary.TYPE_USER_HISTORY);
|
||||||
} else if (usePersonalizedDicts) {
|
} else if (usePersonalizedDicts) {
|
||||||
newUserHistoryDict = PersonalizationHelper.getUserHistoryDictionary(context, newLocale);
|
newUserHistoryDict = PersonalizationHelper.getUserHistoryDictionary(context, newLocale);
|
||||||
} else {
|
} else {
|
||||||
|
@ -353,7 +350,7 @@ public class DictionaryFacilitatorForSuggest {
|
||||||
final PersonalizationDictionary personalizationDict =
|
final PersonalizationDictionary personalizationDict =
|
||||||
mDictionaries.mPersonalizationDictionary;
|
mDictionaries.mPersonalizationDictionary;
|
||||||
if (personalizationDict != null) {
|
if (personalizationDict != null) {
|
||||||
personalizationDict.flush();
|
personalizationDict.asyncFlushBinaryDictionary();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -391,7 +388,9 @@ public class DictionaryFacilitatorForSuggest {
|
||||||
public void addToUserHistory(final String suggestion, final boolean wasAutoCapitalized,
|
public void addToUserHistory(final String suggestion, final boolean wasAutoCapitalized,
|
||||||
final String previousWord, final int timeStampInSeconds) {
|
final String previousWord, final int timeStampInSeconds) {
|
||||||
final Dictionaries dictionaries = mDictionaries;
|
final Dictionaries dictionaries = mDictionaries;
|
||||||
if (!dictionaries.hasDict(Dictionary.TYPE_USER_HISTORY)) {
|
final ExpandableBinaryDictionary userHistoryDictionary =
|
||||||
|
dictionaries.getSubDict(Dictionary.TYPE_USER_HISTORY);
|
||||||
|
if (userHistoryDictionary != null) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
final int maxFreq = getMaxFrequency(suggestion);
|
final int maxFreq = getMaxFrequency(suggestion);
|
||||||
|
@ -433,14 +432,15 @@ public class DictionaryFacilitatorForSuggest {
|
||||||
// We demote unrecognized words (frequency < 0, below) by specifying them as "invalid".
|
// We 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;
|
||||||
dictionaries.mUserHistoryDictionary.addToDictionary(
|
UserHistoryDictionary.addToDictionary(userHistoryDictionary, previousWord, secondWord,
|
||||||
previousWord, secondWord, isValid, timeStampInSeconds);
|
isValid, timeStampInSeconds);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void cancelAddingUserHistory(final String previousWord, final String committedWord) {
|
public void cancelAddingUserHistory(final String previousWord, final String committedWord) {
|
||||||
final UserHistoryDictionary userHistoryDictionary = mDictionaries.mUserHistoryDictionary;
|
final ExpandableBinaryDictionary userHistoryDictionary =
|
||||||
|
mDictionaries.getSubDict(Dictionary.TYPE_USER_HISTORY);
|
||||||
if (userHistoryDictionary != null) {
|
if (userHistoryDictionary != null) {
|
||||||
userHistoryDictionary.cancelAddingUserHistory(previousWord, committedWord);
|
userHistoryDictionary.removeBigramDynamically(previousWord, committedWord);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -298,7 +298,7 @@ abstract public class ExpandableBinaryDictionary extends Dictionary {
|
||||||
/**
|
/**
|
||||||
* Dynamically adds a word unigram to the dictionary. May overwrite an existing entry.
|
* Dynamically adds a word unigram to the dictionary. May overwrite an existing entry.
|
||||||
*/
|
*/
|
||||||
protected void addWordDynamically(final String word, final int frequency,
|
public void addWordDynamically(final String word, final int frequency,
|
||||||
final String shortcutTarget, final int shortcutFreq, final boolean isNotAWord,
|
final String shortcutTarget, final int shortcutFreq, final boolean isNotAWord,
|
||||||
final boolean isBlacklisted, final int timestamp) {
|
final boolean isBlacklisted, final int timestamp) {
|
||||||
reloadDictionaryIfRequired();
|
reloadDictionaryIfRequired();
|
||||||
|
@ -325,7 +325,7 @@ abstract public class ExpandableBinaryDictionary extends Dictionary {
|
||||||
/**
|
/**
|
||||||
* Dynamically adds a word bigram in the dictionary. May overwrite an existing entry.
|
* Dynamically adds a word bigram in the dictionary. May overwrite an existing entry.
|
||||||
*/
|
*/
|
||||||
protected void addBigramDynamically(final String word0, final String word1,
|
public void addBigramDynamically(final String word0, final String word1,
|
||||||
final int frequency, final int timestamp) {
|
final int frequency, final int timestamp) {
|
||||||
reloadDictionaryIfRequired();
|
reloadDictionaryIfRequired();
|
||||||
ExecutorUtils.getExecutor(mDictName).execute(new Runnable() {
|
ExecutorUtils.getExecutor(mDictName).execute(new Runnable() {
|
||||||
|
@ -348,7 +348,7 @@ abstract public class ExpandableBinaryDictionary extends Dictionary {
|
||||||
/**
|
/**
|
||||||
* Dynamically remove a word bigram in the dictionary.
|
* Dynamically remove a word bigram in the dictionary.
|
||||||
*/
|
*/
|
||||||
protected void removeBigramDynamically(final String word0, final String word1) {
|
public void removeBigramDynamically(final String word0, final String word1) {
|
||||||
reloadDictionaryIfRequired();
|
reloadDictionaryIfRequired();
|
||||||
ExecutorUtils.getExecutor(mDictName).execute(new Runnable() {
|
ExecutorUtils.getExecutor(mDictName).execute(new Runnable() {
|
||||||
@Override
|
@Override
|
||||||
|
@ -634,7 +634,7 @@ abstract public class ExpandableBinaryDictionary extends Dictionary {
|
||||||
/**
|
/**
|
||||||
* Flush binary dictionary to dictionary file.
|
* Flush binary dictionary to dictionary file.
|
||||||
*/
|
*/
|
||||||
protected void asyncFlushBinaryDictionary() {
|
public void asyncFlushBinaryDictionary() {
|
||||||
final Runnable newTask = new Runnable() {
|
final Runnable newTask = new Runnable() {
|
||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
|
|
|
@ -65,12 +65,8 @@ public abstract class DecayingExpandableBinaryDictionaryBase extends ExpandableB
|
||||||
dumpAllWordsForDebug();
|
dumpAllWordsForDebug();
|
||||||
}
|
}
|
||||||
// Flush pending writes.
|
// Flush pending writes.
|
||||||
flush();
|
|
||||||
super.close();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void flush() {
|
|
||||||
asyncFlushBinaryDictionary();
|
asyncFlushBinaryDictionary();
|
||||||
|
super.close();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -103,33 +99,6 @@ public abstract class DecayingExpandableBinaryDictionaryBase extends ExpandableB
|
||||||
addMultipleDictionaryEntriesDynamically(languageModelParams, callback);
|
addMultipleDictionaryEntriesDynamically(languageModelParams, callback);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Pair will be added to the decaying dictionary.
|
|
||||||
*
|
|
||||||
* The first word may be null. That means we don't know the context, in other words,
|
|
||||||
* it's only a unigram. The first word may also be an empty string : this means start
|
|
||||||
* context, as in beginning of a sentence for example.
|
|
||||||
* The second word may not be null (a NullPointerException would be thrown).
|
|
||||||
*/
|
|
||||||
public void addToDictionary(final String word0, final String word1, final boolean isValid,
|
|
||||||
final int timestamp) {
|
|
||||||
if (word1.length() >= Constants.DICTIONARY_MAX_WORD_LENGTH ||
|
|
||||||
(word0 != null && word0.length() >= Constants.DICTIONARY_MAX_WORD_LENGTH)) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
final int frequency = isValid ?
|
|
||||||
FREQUENCY_FOR_WORDS_IN_DICTS : FREQUENCY_FOR_WORDS_NOT_IN_DICTS;
|
|
||||||
addWordDynamically(word1, frequency, null /* shortcutTarget */, 0 /* shortcutFreq */,
|
|
||||||
false /* isNotAWord */, false /* isBlacklisted */, timestamp);
|
|
||||||
// Do not insert a word as a bigram of itself
|
|
||||||
if (word1.equals(word0)) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (null != word0) {
|
|
||||||
addBigramDynamically(word0, word1, frequency, timestamp);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void loadInitialContentsLocked() {
|
protected void loadInitialContentsLocked() {
|
||||||
// No initial contents.
|
// No initial contents.
|
||||||
|
|
|
@ -18,7 +18,9 @@ package com.android.inputmethod.latin.personalization;
|
||||||
|
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
|
|
||||||
|
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 java.io.File;
|
import java.io.File;
|
||||||
import java.util.Locale;
|
import java.util.Locale;
|
||||||
|
@ -40,13 +42,36 @@ public class UserHistoryDictionary extends DecayingExpandableBinaryDictionaryBas
|
||||||
dictFile);
|
dictFile);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void cancelAddingUserHistory(final String word0, final String word1) {
|
|
||||||
removeBigramDynamically(word0, word1);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isValidWord(final String word) {
|
public boolean isValidWord(final String word) {
|
||||||
// Strings out of this dictionary should not be considered existing words.
|
// Strings out of this dictionary should not be considered existing words.
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Pair will be added to the user history dictionary.
|
||||||
|
*
|
||||||
|
* The first word may be null. That means we don't know the context, in other words,
|
||||||
|
* it's only a unigram. The first word may also be an empty string : this means start
|
||||||
|
* context, as in beginning of a sentence for example.
|
||||||
|
* The second word may not be null (a NullPointerException would be thrown).
|
||||||
|
*/
|
||||||
|
public static void addToDictionary(final ExpandableBinaryDictionary userHistoryDictionary,
|
||||||
|
final String word0, final String word1, final boolean isValid, final int timestamp) {
|
||||||
|
if (word1.length() >= Constants.DICTIONARY_MAX_WORD_LENGTH ||
|
||||||
|
(word0 != null && word0.length() >= Constants.DICTIONARY_MAX_WORD_LENGTH)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
final int frequency = isValid ?
|
||||||
|
FREQUENCY_FOR_WORDS_IN_DICTS : FREQUENCY_FOR_WORDS_NOT_IN_DICTS;
|
||||||
|
userHistoryDictionary.addWordDynamically(word1, frequency, null /* shortcutTarget */,
|
||||||
|
0 /* shortcutFreq */, false /* isNotAWord */, false /* isBlacklisted */, timestamp);
|
||||||
|
// Do not insert a word as a bigram of itself
|
||||||
|
if (word1.equals(word0)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (null != word0) {
|
||||||
|
userHistoryDictionary.addBigramDynamically(word0, word1, frequency, timestamp);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -111,7 +111,7 @@ 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) {
|
||||||
String prevWord = null;
|
String prevWord = null;
|
||||||
for (String word : words) {
|
for (String word : words) {
|
||||||
dict.addToDictionary(prevWord, word, true,
|
UserHistoryDictionary.addToDictionary(dict, prevWord, word, true,
|
||||||
(int)TimeUnit.MILLISECONDS.toSeconds(System.currentTimeMillis()));
|
(int)TimeUnit.MILLISECONDS.toSeconds(System.currentTimeMillis()));
|
||||||
prevWord = word;
|
prevWord = word;
|
||||||
}
|
}
|
||||||
|
@ -262,7 +262,7 @@ public class UserHistoryDictionaryTests extends AndroidTestCase {
|
||||||
dict.waitAllTasksForTests();
|
dict.waitAllTasksForTests();
|
||||||
String prevWord = null;
|
String prevWord = null;
|
||||||
for (final String word : words) {
|
for (final String word : words) {
|
||||||
dict.addToDictionary(prevWord, word, true, mCurrentTime);
|
UserHistoryDictionary.addToDictionary(dict, prevWord, word, true, mCurrentTime);
|
||||||
prevWord = word;
|
prevWord = word;
|
||||||
assertTrue(dict.isInUnderlyingBinaryDictionaryForTests(word));
|
assertTrue(dict.isInUnderlyingBinaryDictionaryForTests(word));
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue