From c68d1bbfafe4b2041db49523c044123f78d6635d Mon Sep 17 00:00:00 2001 From: Jean Chalard Date: Fri, 16 Mar 2012 16:16:02 +0900 Subject: [PATCH] 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 --- .../android/inputmethod/latin/LatinIME.java | 13 +--- .../latin/UserBigramDictionary.java | 62 ++++++++++++++++--- .../latin/UserUnigramDictionary.java | 2 +- 3 files changed, 57 insertions(+), 20 deletions(-) diff --git a/java/src/com/android/inputmethod/latin/LatinIME.java b/java/src/com/android/inputmethod/latin/LatinIME.java index 7c08377be..234a501de 100644 --- a/java/src/com/android/inputmethod/latin/LatinIME.java +++ b/java/src/com/android/inputmethod/latin/LatinIME.java @@ -204,7 +204,6 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar private UserDictionary mUserDictionary; private UserBigramDictionary mUserBigramDictionary; - private UserUnigramDictionary mUserUnigramDictionary; private boolean mIsUserDictionaryAvailable; private LastComposedWord mLastComposedWord = LastComposedWord.NOT_A_COMPOSED_WORD; @@ -528,12 +527,10 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar resetContactsDictionary(oldContactsDictionary); - mUserUnigramDictionary - = new UserUnigramDictionary(this, this, localeStr, Suggest.DIC_USER_UNIGRAM); - mSuggest.setUserUnigramDictionary(mUserUnigramDictionary); - + // TODO: rename UserBigramDictionary into UserHistoryDictionary mUserBigramDictionary = new UserBigramDictionary(this, this, localeStr, Suggest.DIC_USER_BIGRAM); + mSuggest.setUserUnigramDictionary(mUserBigramDictionary); mSuggest.setUserBigramDictionary(mUserBigramDictionary); LocaleUtils.setSystemLocale(res, savedLocale); @@ -776,7 +773,6 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar KeyboardView inputView = mKeyboardSwitcher.getKeyboardView(); if (inputView != null) inputView.closing(); - if (mUserUnigramDictionary != null) mUserUnigramDictionary.flushPendingWrites(); if (mUserBigramDictionary != null) mUserBigramDictionary.flushPendingWrites(); } @@ -2009,11 +2005,8 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar return; } - if (null != mUserUnigramDictionary) { - mUserUnigramDictionary.addUnigram(suggestion.toString()); - } - if (mUserBigramDictionary != null) { + mUserBigramDictionary.addUnigram(suggestion.toString()); final InputConnection ic = getCurrentInputConnection(); if (null != ic) { final CharSequence prevWord = diff --git a/java/src/com/android/inputmethod/latin/UserBigramDictionary.java b/java/src/com/android/inputmethod/latin/UserBigramDictionary.java index 52a31f2e6..42d3a70cd 100644 --- a/java/src/com/android/inputmethod/latin/UserBigramDictionary.java +++ b/java/src/com/android/inputmethod/latin/UserBigramDictionary.java @@ -24,6 +24,7 @@ import android.database.sqlite.SQLiteOpenHelper; import android.database.sqlite.SQLiteQueryBuilder; import android.os.AsyncTask; import android.provider.BaseColumns; +import android.text.TextUtils; import android.util.Log; 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 if (mIme != null && mIme.isAutoCapitalized()) { word2 = Character.toLowerCase(word2.charAt(0)) + word2.substring(1); } // Do not insert a word as a bigram of itself - if (word1.equals(word2)) { + if (word2.equals(word1)) { 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; synchronized (mPendingWritesLock) { if (freq == FREQUENCY_FOR_TYPED || mPendingWrites.isEmpty()) { @@ -225,7 +256,10 @@ public class UserBigramDictionary extends ExpandableDictionary { int frequency = cursor.getInt(frequencyIndex); // Safeguard against adding really long words. Stack may overflow due // 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); } cursor.moveToNext(); @@ -367,13 +401,23 @@ public class UserBigramDictionary extends ExpandableDictionary { // Write all the entries to the db Iterator iterator = mMap.iterator(); 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(); // find pair id - Cursor c = db.query(MAIN_TABLE_NAME, new String[] { MAIN_COLUMN_ID }, - MAIN_COLUMN_WORD1 + "=? AND " + MAIN_COLUMN_WORD2 + "=? AND " - + MAIN_COLUMN_LOCALE + "=?", - new String[] { bi.mWord1, bi.mWord2, mLocale }, null, null, null); + 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_LOCALE + "=?", + 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; if (c.moveToFirst()) { diff --git a/java/src/com/android/inputmethod/latin/UserUnigramDictionary.java b/java/src/com/android/inputmethod/latin/UserUnigramDictionary.java index 2fc395c3e..e278b2597 100644 --- a/java/src/com/android/inputmethod/latin/UserUnigramDictionary.java +++ b/java/src/com/android/inputmethod/latin/UserUnigramDictionary.java @@ -35,7 +35,7 @@ import java.util.Set; * based dictionary. It stores words that the user typed to supply a provision * for suggesting and re-ordering of candidates. */ -public class UserUnigramDictionary extends ExpandableDictionary { +class UserUnigramDictionary extends ExpandableDictionary { static final boolean ENABLE_USER_UNIGRAM_DICTIONARY = false; // Weight added to a user picking a new word from the suggestion strip