Move the UserUnigramDictionary functionality over

UserBigramDictionary now assumes both functionalities. It will
be renamed to UserHistoryDictionary in a future change.

There are several reasons to do this. First, there is a lot of
duplicate code in User{Unigram,Bigram}Dictionaries that are
factored by the few lines of code in this change. Also, other
dictionaries like BinaryDictionary or ContactsDictionary all
assume both responsibilities, as should be the case
theoretically.

It is also possible to do this because previous versions don't
write any unigram data that we'd want to reuse. For even older
versions that do write data, we can't really make any sense out
of it. Bigram data however can be useful, and this allows us to
reuse it easily.

Change-Id: I755525f92744e1536eaef097527e8151b7859a30
main
Jean Chalard 2012-03-16 16:16:02 +09:00
parent c24f66e180
commit c68d1bbfaf
3 changed files with 57 additions and 20 deletions

View File

@ -204,7 +204,6 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar
private UserDictionary mUserDictionary; private UserDictionary mUserDictionary;
private UserBigramDictionary mUserBigramDictionary; private UserBigramDictionary mUserBigramDictionary;
private UserUnigramDictionary mUserUnigramDictionary;
private boolean mIsUserDictionaryAvailable; private boolean mIsUserDictionaryAvailable;
private LastComposedWord mLastComposedWord = LastComposedWord.NOT_A_COMPOSED_WORD; private LastComposedWord mLastComposedWord = LastComposedWord.NOT_A_COMPOSED_WORD;
@ -528,12 +527,10 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar
resetContactsDictionary(oldContactsDictionary); resetContactsDictionary(oldContactsDictionary);
mUserUnigramDictionary // TODO: rename UserBigramDictionary into UserHistoryDictionary
= new UserUnigramDictionary(this, this, localeStr, Suggest.DIC_USER_UNIGRAM);
mSuggest.setUserUnigramDictionary(mUserUnigramDictionary);
mUserBigramDictionary mUserBigramDictionary
= new UserBigramDictionary(this, this, localeStr, Suggest.DIC_USER_BIGRAM); = new UserBigramDictionary(this, this, localeStr, Suggest.DIC_USER_BIGRAM);
mSuggest.setUserUnigramDictionary(mUserBigramDictionary);
mSuggest.setUserBigramDictionary(mUserBigramDictionary); mSuggest.setUserBigramDictionary(mUserBigramDictionary);
LocaleUtils.setSystemLocale(res, savedLocale); LocaleUtils.setSystemLocale(res, savedLocale);
@ -776,7 +773,6 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar
KeyboardView inputView = mKeyboardSwitcher.getKeyboardView(); KeyboardView inputView = mKeyboardSwitcher.getKeyboardView();
if (inputView != null) inputView.closing(); if (inputView != null) inputView.closing();
if (mUserUnigramDictionary != null) mUserUnigramDictionary.flushPendingWrites();
if (mUserBigramDictionary != null) mUserBigramDictionary.flushPendingWrites(); if (mUserBigramDictionary != null) mUserBigramDictionary.flushPendingWrites();
} }
@ -2009,11 +2005,8 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar
return; return;
} }
if (null != mUserUnigramDictionary) {
mUserUnigramDictionary.addUnigram(suggestion.toString());
}
if (mUserBigramDictionary != null) { if (mUserBigramDictionary != null) {
mUserBigramDictionary.addUnigram(suggestion.toString());
final InputConnection ic = getCurrentInputConnection(); final InputConnection ic = getCurrentInputConnection();
if (null != ic) { if (null != ic) {
final CharSequence prevWord = final CharSequence prevWord =

View File

@ -24,6 +24,7 @@ import android.database.sqlite.SQLiteOpenHelper;
import android.database.sqlite.SQLiteQueryBuilder; import android.database.sqlite.SQLiteQueryBuilder;
import android.os.AsyncTask; import android.os.AsyncTask;
import android.provider.BaseColumns; import android.provider.BaseColumns;
import android.text.TextUtils;
import android.util.Log; import android.util.Log;
import java.util.HashMap; import java.util.HashMap;
@ -155,19 +156,49 @@ public class UserBigramDictionary extends ExpandableDictionary {
} }
/** /**
* Pair will be added to the userbigram database. * Return whether the passed charsequence is in the dictionary.
*/ */
public int addBigramPair(String word1, String word2) { @Override
public boolean isValidWord(final CharSequence word) {
// TODO: figure out what is the correct thing to do here.
return false;
}
/**
* Add a single word without context.
*
* This is a temporary method to match the interface to UserUnigramDictionary. In the end
* this should be merged with addBigramPair.
*/
public void addUnigram(final String newWord) {
addBigramPair(null, newWord);
}
/**
* 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 int addBigramPair(final String word1, String word2) {
// remove caps if second word is autocapitalized // remove caps if second word is autocapitalized
if (mIme != null && mIme.isAutoCapitalized()) { if (mIme != null && mIme.isAutoCapitalized()) {
word2 = Character.toLowerCase(word2.charAt(0)) + word2.substring(1); word2 = Character.toLowerCase(word2.charAt(0)) + word2.substring(1);
} }
// Do not insert a word as a bigram of itself // Do not insert a word as a bigram of itself
if (word1.equals(word2)) { if (word2.equals(word1)) {
return 0; return 0;
} }
int freq = super.addBigram(word1, word2, FREQUENCY_FOR_TYPED); int freq;
if (null == word1) {
freq = FREQUENCY_FOR_TYPED;
super.addWord(word2, FREQUENCY_FOR_TYPED);
} else {
freq = super.addBigram(word1, word2, FREQUENCY_FOR_TYPED);
}
if (freq > FREQUENCY_MAX) freq = FREQUENCY_MAX; if (freq > FREQUENCY_MAX) freq = FREQUENCY_MAX;
synchronized (mPendingWritesLock) { synchronized (mPendingWritesLock) {
if (freq == FREQUENCY_FOR_TYPED || mPendingWrites.isEmpty()) { if (freq == FREQUENCY_FOR_TYPED || mPendingWrites.isEmpty()) {
@ -225,7 +256,10 @@ public class UserBigramDictionary extends ExpandableDictionary {
int frequency = cursor.getInt(frequencyIndex); int frequency = cursor.getInt(frequencyIndex);
// Safeguard against adding really long words. Stack may overflow due // Safeguard against adding really long words. Stack may overflow due
// to recursive lookup // to recursive lookup
if (word1.length() < MAX_WORD_LENGTH && word2.length() < MAX_WORD_LENGTH) { if (null == word1) {
super.addWord(word2, frequency);
} else if (word1.length() < MAX_WORD_LENGTH
&& word2.length() < MAX_WORD_LENGTH) {
super.setBigram(word1, word2, frequency); super.setBigram(word1, word2, frequency);
} }
cursor.moveToNext(); cursor.moveToNext();
@ -367,13 +401,23 @@ public class UserBigramDictionary extends ExpandableDictionary {
// Write all the entries to the db // Write all the entries to the db
Iterator<Bigram> iterator = mMap.iterator(); Iterator<Bigram> iterator = mMap.iterator();
while (iterator.hasNext()) { while (iterator.hasNext()) {
// TODO: this process of making a text search for each pair each time
// is terribly inefficient. Optimize this.
Bigram bi = iterator.next(); Bigram bi = iterator.next();
// find pair id // find pair id
Cursor c = db.query(MAIN_TABLE_NAME, new String[] { MAIN_COLUMN_ID }, final Cursor c;
if (null != bi.mWord1) {
c = db.query(MAIN_TABLE_NAME, new String[] { MAIN_COLUMN_ID },
MAIN_COLUMN_WORD1 + "=? AND " + MAIN_COLUMN_WORD2 + "=? AND " MAIN_COLUMN_WORD1 + "=? AND " + MAIN_COLUMN_WORD2 + "=? AND "
+ MAIN_COLUMN_LOCALE + "=?", + MAIN_COLUMN_LOCALE + "=?",
new String[] { bi.mWord1, bi.mWord2, mLocale }, null, null, null); new String[] { bi.mWord1, bi.mWord2, mLocale }, null, null, null);
} else {
c = db.query(MAIN_TABLE_NAME, new String[] { MAIN_COLUMN_ID },
MAIN_COLUMN_WORD1 + " IS NULL AND " + MAIN_COLUMN_WORD2 + "=? AND "
+ MAIN_COLUMN_LOCALE + "=?",
new String[] { bi.mWord2, mLocale }, null, null, null);
}
int pairId; int pairId;
if (c.moveToFirst()) { if (c.moveToFirst()) {

View File

@ -35,7 +35,7 @@ import java.util.Set;
* based dictionary. It stores words that the user typed to supply a provision * based dictionary. It stores words that the user typed to supply a provision
* for suggesting and re-ordering of candidates. * for suggesting and re-ordering of candidates.
*/ */
public class UserUnigramDictionary extends ExpandableDictionary { class UserUnigramDictionary extends ExpandableDictionary {
static final boolean ENABLE_USER_UNIGRAM_DICTIONARY = false; static final boolean ENABLE_USER_UNIGRAM_DICTIONARY = false;
// Weight added to a user picking a new word from the suggestion strip // Weight added to a user picking a new word from the suggestion strip