diff options
-rw-r--r-- | java/Android.mk | 3 | ||||
-rw-r--r-- | java/res/xml/dictionary.xml | 23 | ||||
-rw-r--r-- | java/src/com/android/inputmethod/keyboard/KeyDetector.java | 3 | ||||
-rw-r--r-- | java/src/com/android/inputmethod/keyboard/KeyboardActionListener.java | 64 | ||||
-rw-r--r-- | java/src/com/android/inputmethod/keyboard/KeyboardView.java | 2 | ||||
-rw-r--r-- | java/src/com/android/inputmethod/keyboard/LatinKeyboardView.java | 4 | ||||
-rw-r--r-- | java/src/com/android/inputmethod/latin/BinaryDictionary.java | 31 | ||||
-rw-r--r-- | java/src/com/android/inputmethod/latin/InputLanguageSelection.java | 10 | ||||
-rw-r--r-- | java/src/com/android/inputmethod/latin/LatinIME.java | 66 | ||||
-rw-r--r-- | java/src/com/android/inputmethod/latin/Suggest.java | 2 | ||||
-rw-r--r-- | native/Android.mk | 17 | ||||
-rw-r--r-- | native/src/defines.h | 60 | ||||
-rw-r--r-- | native/src/unigram_dictionary.cpp | 42 |
13 files changed, 171 insertions, 156 deletions
diff --git a/java/Android.mk b/java/Android.mk index be3b0b9ad..60c321ab2 100644 --- a/java/Android.mk +++ b/java/Android.mk @@ -13,7 +13,8 @@ LOCAL_JNI_SHARED_LIBRARIES := libjni_latinime LOCAL_STATIC_JAVA_LIBRARIES := android-common -#LOCAL_AAPT_FLAGS := -0 .dict +# Do not compress dictionary files to mmap dict data runtime +LOCAL_AAPT_FLAGS := -0 .dict # Include all the resources regardless of system supported locales LOCAL_AAPT_INCLUDE_ALL_RESOURCES := true diff --git a/java/res/xml/dictionary.xml b/java/res/xml/dictionary.xml deleted file mode 100644 index 7b770a8b4..000000000 --- a/java/res/xml/dictionary.xml +++ /dev/null @@ -1,23 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<!-- -/* -** -** Copyright 2010, 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. -*/ ---> - -<dictionary> - <part name = "main" /> -</dictionary>
\ No newline at end of file diff --git a/java/src/com/android/inputmethod/keyboard/KeyDetector.java b/java/src/com/android/inputmethod/keyboard/KeyDetector.java index 777a79520..e7a9d8513 100644 --- a/java/src/com/android/inputmethod/keyboard/KeyDetector.java +++ b/java/src/com/android/inputmethod/keyboard/KeyDetector.java @@ -79,8 +79,7 @@ public abstract class KeyDetector { * * @return Allocates and returns an array that can hold all key indices returned by * {@link #getKeyIndexAndNearbyCodes} method. All elements in the returned array are - * initialized by {@link com.android.inputmethod.latin.LatinKeyboardView.NOT_A_KEY} - * value. + * initialized by {@link #NOT_A_KEY} value. */ public int[] newCodeArray() { int[] codes = new int[getMaxNearbyKeys()]; diff --git a/java/src/com/android/inputmethod/keyboard/KeyboardActionListener.java b/java/src/com/android/inputmethod/keyboard/KeyboardActionListener.java index 00f3a5153..734a55a79 100644 --- a/java/src/com/android/inputmethod/keyboard/KeyboardActionListener.java +++ b/java/src/com/android/inputmethod/keyboard/KeyboardActionListener.java @@ -19,64 +19,56 @@ package com.android.inputmethod.keyboard; public interface KeyboardActionListener { /** - * Called when the user presses a key. This is sent before the - * {@link #onCodeInput} is called. For keys that repeat, this is only - * called once. + * Called when the user presses a key. This is sent before the {@link #onCodeInput} is called. + * For keys that repeat, this is only called once. * - * @param primaryCode - * the unicode of the key being pressed. If the touch is - * not on a valid key, the value will be zero. + * @param primaryCode the unicode of the key being pressed. If the touch is not on a valid key, + * the value will be zero. */ - void onPress(int primaryCode); + public void onPress(int primaryCode); /** - * Called when the user releases a key. This is sent after the - * {@link #onCodeInput} is called. For keys that repeat, this is only - * called once. + * Called when the user releases a key. This is sent after the {@link #onCodeInput} is called. + * For keys that repeat, this is only called once. * - * @param primaryCode - * the code of the key that was released + * @param primaryCode the code of the key that was released */ - void onRelease(int primaryCode); + public void onRelease(int primaryCode); /** * Send a key code to the listener. * - * @param primaryCode - * this is the code of the key that was pressed - * @param keyCodes - * the codes for all the possible alternative keys with - * the primary code being the first. If the primary key - * code is a single character such as an alphabet or - * number or symbol, the alternatives will include other - * characters that may be on the same key or adjacent - * keys. These codes are useful to correct for - * accidental presses of a key adjacent to the intended - * key. - * @param x - * x-coordinate pixel of touched event. If {@link #onCodeInput} is not called by - * onTouchEvent, the value should be NOT_A_TOUCH_COORDINATE. - * @param y - * y-coordinate pixel of touched event. If {@link #onCodeInput} is not called by - * onTouchEvent, the value should be NOT_A_TOUCH_COORDINATE. + * @param primaryCode this is the code of the key that was pressed + * @param keyCodes the codes for all the possible alternative keys with the primary code being + * the first. If the primary key code is a single character such as an alphabet or + * number or symbol, the alternatives will include other characters that may be on + * the same key or adjacent keys. These codes are useful to correct for accidental + * presses of a key adjacent to the intended key. + * @param x x-coordinate pixel of touched event. If {@link #onCodeInput} is not called by + * {@link PointerTracker#onTouchEvent} or so, the value should be + * {@link #NOT_A_TOUCH_COORDINATE}. + * @param y y-coordinate pixel of touched event. If {@link #onCodeInput} is not called by + * {@link PointerTracker#onTouchEvent} or so, the value should be + * {@link #NOT_A_TOUCH_COORDINATE}. */ - void onCodeInput(int primaryCode, int[] keyCodes, int x, int y); + public void onCodeInput(int primaryCode, int[] keyCodes, int x, int y); + + public static final int NOT_A_TOUCH_COORDINATE = -1; /** * Sends a sequence of characters to the listener. * - * @param text - * the sequence of characters to be displayed. + * @param text the sequence of characters to be displayed. */ - void onTextInput(CharSequence text); + public void onTextInput(CharSequence text); /** * Called when user released a finger outside any key. */ - void onCancelInput(); + public void onCancelInput(); /** * Called when the user quickly moves the finger from up to down. */ - void onSwipeDown(); + public void onSwipeDown(); } diff --git a/java/src/com/android/inputmethod/keyboard/KeyboardView.java b/java/src/com/android/inputmethod/keyboard/KeyboardView.java index e0835d7ed..b259e0c03 100644 --- a/java/src/com/android/inputmethod/keyboard/KeyboardView.java +++ b/java/src/com/android/inputmethod/keyboard/KeyboardView.java @@ -79,8 +79,6 @@ public class KeyboardView extends View implements PointerTracker.UIProxy { public static final int COLOR_SCHEME_WHITE = 0; public static final int COLOR_SCHEME_BLACK = 1; - public static final int NOT_A_TOUCH_COORDINATE = -1; - // Timing constants private final int mKeyRepeatInterval; diff --git a/java/src/com/android/inputmethod/keyboard/LatinKeyboardView.java b/java/src/com/android/inputmethod/keyboard/LatinKeyboardView.java index cb3b430d5..6b052c7e7 100644 --- a/java/src/com/android/inputmethod/keyboard/LatinKeyboardView.java +++ b/java/src/com/android/inputmethod/keyboard/LatinKeyboardView.java @@ -95,8 +95,8 @@ public class LatinKeyboardView extends KeyboardView { private boolean invokeOnKey(int primaryCode) { getOnKeyboardActionListener().onCodeInput(primaryCode, null, - KeyboardView.NOT_A_TOUCH_COORDINATE, - KeyboardView.NOT_A_TOUCH_COORDINATE); + KeyboardActionListener.NOT_A_TOUCH_COORDINATE, + KeyboardActionListener.NOT_A_TOUCH_COORDINATE); return true; } diff --git a/java/src/com/android/inputmethod/latin/BinaryDictionary.java b/java/src/com/android/inputmethod/latin/BinaryDictionary.java index 961b49f02..4bb64ee90 100644 --- a/java/src/com/android/inputmethod/latin/BinaryDictionary.java +++ b/java/src/com/android/inputmethod/latin/BinaryDictionary.java @@ -71,8 +71,8 @@ public class BinaryDictionary extends Dictionary { * @param context application context for reading resources * @param resId the resource containing the raw binary dictionary */ - public BinaryDictionary(Context context, int[] resId, int dicTypeId) { - if (resId != null && resId.length > 0 && resId[0] != 0) { + public BinaryDictionary(Context context, int resId, int dicTypeId) { + if (resId != 0) { loadDictionary(context, resId); } mDicTypeId = dicTypeId; @@ -104,30 +104,21 @@ public class BinaryDictionary extends Dictionary { int fullWordMultiplier, int maxWordLength, int maxWords, int maxAlternatives); private native void closeNative(int dict); private native boolean isValidWordNative(int nativeData, char[] word, int wordLength); - private native int getSuggestionsNative(int dict, int[] inputCodes, int codesSize, + private native int getSuggestionsNative(int dict, int[] inputCodes, int codesSize, char[] outputChars, int[] frequencies, int[] nextLettersFrequencies, int nextLettersSize); private native int getBigramsNative(int dict, char[] prevWord, int prevWordLength, int[] inputCodes, int inputCodesLength, char[] outputChars, int[] frequencies, int maxWordLength, int maxBigrams, int maxAlternatives); - private final void loadDictionary(Context context, int[] resId) { - InputStream[] is = null; + private final void loadDictionary(Context context, int resId) { + InputStream is = null; try { - // merging separated dictionary into one if dictionary is separated - int total = 0; - is = new InputStream[resId.length]; - for (int i = 0; i < resId.length; i++) { - is[i] = context.getResources().openRawResource(resId[i]); - total += is[i].available(); - } - + is = context.getResources().openRawResource(resId); + final int total = is.available(); mNativeDictDirectBuffer = ByteBuffer.allocateDirect(total).order(ByteOrder.nativeOrder()); - int got = 0; - for (int i = 0; i < resId.length; i++) { - got += Channels.newChannel(is[i]).read(mNativeDictDirectBuffer); - } + final int got = Channels.newChannel(is).read(mNativeDictDirectBuffer); if (got != total) { Log.e(TAG, "Read " + got + " bytes, expected " + total); } else { @@ -140,11 +131,7 @@ public class BinaryDictionary extends Dictionary { Log.w(TAG, "No available memory for binary dictionary"); } finally { try { - if (is != null) { - for (int i = 0; i < is.length; i++) { - is[i].close(); - } - } + if (is != null) is.close(); } catch (IOException e) { Log.w(TAG, "Failed to close input stream"); } diff --git a/java/src/com/android/inputmethod/latin/InputLanguageSelection.java b/java/src/com/android/inputmethod/latin/InputLanguageSelection.java index 27e0fbe4a..faee38eda 100644 --- a/java/src/com/android/inputmethod/latin/InputLanguageSelection.java +++ b/java/src/com/android/inputmethod/latin/InputLanguageSelection.java @@ -99,15 +99,15 @@ public class InputLanguageSelection extends PreferenceActivity { } private boolean hasDictionary(Locale locale) { - Resources res = getResources(); - Configuration conf = res.getConfiguration(); - Locale saveLocale = conf.locale; + final Resources res = getResources(); + final Configuration conf = res.getConfiguration(); + final Locale saveLocale = conf.locale; boolean haveDictionary = false; conf.locale = locale; res.updateConfiguration(conf, res.getDisplayMetrics()); - int[] dictionaries = LatinIME.getDictionary(res); - BinaryDictionary bd = new BinaryDictionary(this, dictionaries, Suggest.DIC_MAIN); + int mainDicResId = LatinIME.getMainDictionaryResourceId(res); + BinaryDictionary bd = new BinaryDictionary(this, mainDicResId, Suggest.DIC_MAIN); // Is the dictionary larger than a placeholder? Arbitrarily chose a lower limit of // 4000-5000 words, whereas the LARGE_DICTIONARY is about 20000+ words. diff --git a/java/src/com/android/inputmethod/latin/LatinIME.java b/java/src/com/android/inputmethod/latin/LatinIME.java index e785eb76f..be98f4c3e 100644 --- a/java/src/com/android/inputmethod/latin/LatinIME.java +++ b/java/src/com/android/inputmethod/latin/LatinIME.java @@ -347,49 +347,19 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen } /** - * Loads a dictionary or multiple separated dictionary - * @return returns array of dictionary resource ids + * Returns a main dictionary resource id + * @return main dictionary resource id */ - public static int[] getDictionary(Resources res) { + public static int getMainDictionaryResourceId(Resources res) { + final String MAIN_DIC_NAME = "main"; String packageName = LatinIME.class.getPackage().getName(); - XmlResourceParser xrp = res.getXml(R.xml.dictionary); - ArrayList<Integer> dictionaries = new ArrayList<Integer>(); - - try { - int current = xrp.getEventType(); - while (current != XmlPullParser.END_DOCUMENT) { - if (current == XmlPullParser.START_TAG) { - String tag = xrp.getName(); - if (tag != null) { - if (tag.equals("part")) { - String dictFileName = xrp.getAttributeValue(null, "name"); - dictionaries.add(res.getIdentifier(dictFileName, "raw", packageName)); - } - } - } - xrp.next(); - current = xrp.getEventType(); - } - } catch (XmlPullParserException e) { - Log.e(TAG, "Dictionary XML parsing failure"); - } catch (IOException e) { - Log.e(TAG, "Dictionary XML IOException"); - } - - int count = dictionaries.size(); - int[] dict = new int[count]; - for (int i = 0; i < count; i++) { - dict[i] = dictionaries.get(i); - } - - return dict; + return res.getIdentifier(MAIN_DIC_NAME, "raw", packageName); } private void initSuggest() { updateAutoTextEnabled(); String locale = mSubtypeSwitcher.getInputLocaleStr(); - Resources orig = getResources(); Locale savedLocale = mSubtypeSwitcher.changeSystemLocale(new Locale(locale)); if (mSuggest != null) { mSuggest.close(); @@ -397,8 +367,9 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen final SharedPreferences prefs = mPrefs; mQuickFixes = prefs.getBoolean(Settings.PREF_QUICK_FIXES, true); - int[] dictionaries = getDictionary(orig); - mSuggest = new Suggest(this, dictionaries); + final Resources res = mResources; + int mainDicResId = getMainDictionaryResourceId(res); + mSuggest = new Suggest(this, mainDicResId); loadAndSetAutoCorrectionThreshold(prefs); if (mUserDictionary != null) mUserDictionary.close(); mUserDictionary = new UserDictionary(this, locale); @@ -418,8 +389,8 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen mSuggest.setContactsDictionary(mContactsDictionary); mSuggest.setAutoDictionary(mAutoDictionary); updateCorrectionMode(); - mWordSeparators = mResources.getString(R.string.word_separators); - mSentenceSeparators = mResources.getString(R.string.sentence_separators); + mWordSeparators = res.getString(R.string.word_separators); + mSentenceSeparators = res.getString(R.string.sentence_separators); mSubtypeSwitcher.changeSystemLocale(savedLocale); } @@ -859,10 +830,11 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen @Override public boolean onEvaluateFullscreenMode() { - DisplayMetrics dm = getResources().getDisplayMetrics(); + final Resources res = mResources; + DisplayMetrics dm = res.getDisplayMetrics(); float displayHeight = dm.heightPixels; // If the display is more than X inches high, don't go to fullscreen mode - float dimen = getResources().getDimension(R.dimen.max_height_for_fullscreen); + float dimen = res.getDimension(R.dimen.max_height_for_fullscreen); if (displayHeight > dimen) { return false; } else { @@ -1583,8 +1555,9 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen LatinImeLogger.logOnManualSuggestion( "", suggestion.toString(), index, suggestions.mWords); final char primaryCode = suggestion.charAt(0); - onCodeInput(primaryCode, new int[]{primaryCode}, KeyboardView.NOT_A_TOUCH_COORDINATE, - KeyboardView.NOT_A_TOUCH_COORDINATE); + onCodeInput(primaryCode, new int[] { primaryCode }, + KeyboardActionListener.NOT_A_TOUCH_COORDINATE, + KeyboardActionListener.NOT_A_TOUCH_COORDINATE); if (ic != null) { ic.endBatchEdit(); } @@ -1873,7 +1846,7 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen } else if (Settings.PREF_RECORRECTION_ENABLED.equals(key)) { mReCorrectionEnabled = sharedPreferences.getBoolean( Settings.PREF_RECORRECTION_ENABLED, - getResources().getBoolean(R.bool.default_recorrection_enabled)); + mResources.getBoolean(R.bool.default_recorrection_enabled)); } } @@ -2005,11 +1978,12 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen } private void updateSuggestionVisibility(SharedPreferences prefs) { + final Resources res = mResources; final String suggestionVisiblityStr = prefs.getString( Settings.PREF_SHOW_SUGGESTIONS_SETTING, - mResources.getString(R.string.prefs_suggestion_visibility_default_value)); + res.getString(R.string.prefs_suggestion_visibility_default_value)); for (int visibility : SUGGESTION_VISIBILITY_VALUE_ARRAY) { - if (suggestionVisiblityStr.equals(mResources.getString(visibility))) { + if (suggestionVisiblityStr.equals(res.getString(visibility))) { mSuggestionVisibility = visibility; break; } diff --git a/java/src/com/android/inputmethod/latin/Suggest.java b/java/src/com/android/inputmethod/latin/Suggest.java index 236590284..9f979fffd 100644 --- a/java/src/com/android/inputmethod/latin/Suggest.java +++ b/java/src/com/android/inputmethod/latin/Suggest.java @@ -103,7 +103,7 @@ public class Suggest implements Dictionary.WordCallback { private int mCorrectionMode = CORRECTION_BASIC; - public Suggest(Context context, int[] dictionaryResId) { + public Suggest(Context context, int dictionaryResId) { mMainDict = new BinaryDictionary(context, dictionaryResId, DIC_MAIN); initPool(); } diff --git a/native/Android.mk b/native/Android.mk index 2de3892db..38465acf3 100644 --- a/native/Android.mk +++ b/native/Android.mk @@ -12,13 +12,20 @@ LOCAL_SRC_FILES := \ #FLAG_DBG := true -ifneq ($(TARGET_ARCH),x86) -ifneq ($(FLAG_DBG), true) - LOCAL_NDK_VERSION := 4 +TARGETING_UNBUNDLED_FROYO := true + +ifeq ($(TARGET_ARCH), x86) + TARGETING_UNBUNDLED_FROYO := false endif -LOCAL_SDK_VERSION := 8 -endif #TARGET_ARCH = x86 +ifeq ($(FLAG_DBG), true) + TARGETING_UNBUNDLED_FROYO := false +endif + +ifeq ($(TARGETING_UNBUNDLED_FROYO), true) + LOCAL_NDK_VERSION := 4 + LOCAL_SDK_VERSION := 8 +endif LOCAL_MODULE := libjni_latinime diff --git a/native/src/defines.h b/native/src/defines.h index 73394ce36..59eaa4102 100644 --- a/native/src/defines.h +++ b/native/src/defines.h @@ -24,10 +24,56 @@ #define LOG_TAG "LatinIME: " #endif #define DEBUG_DICT true -#define DEBUG_DICT_FULL true +#define DEBUG_DICT_FULL false #define DEBUG_SHOW_FOUND_WORD DEBUG_DICT_FULL #define DEBUG_NODE DEBUG_DICT_FULL #define DEBUG_TRACE DEBUG_DICT_FULL + +// Profiler +#include <time.h> +#define PROF_BUF_SIZE 100 +static double profile_buf[PROF_BUF_SIZE]; +static double profile_old[PROF_BUF_SIZE]; +static unsigned int profile_counter[PROF_BUF_SIZE]; + +#define PROF_RESET prof_reset(); +#define PROF_COUNT(prof_buf_id) ++profile_counter[prof_buf_id]; +#define PROF_OPEN PROF_RESET;PROF_START(PROF_BUF_SIZE - 1); +#define PROF_START(prof_buf_id) PROF_COUNT(prof_buf_id);profile_old[prof_buf_id] = (clock()); +#define PROF_CLOSE PROF_END(PROF_BUF_SIZE - 1);PROF_OUTALL; +#define PROF_END(prof_buf_id) profile_buf[prof_buf_id] += ((clock()) - profile_old[prof_buf_id]); +#define PROF_CLOCKOUT(prof_buf_id) LOGI("%s : clock is %f", __FUNCTION__,\ + (clock() - profile_old[prof_buf_id])); +#define PROF_OUTALL LOGI("--- %s ---", __FUNCTION__); prof_out(); + +static void prof_reset(void){ + for(int i = 0;i < PROF_BUF_SIZE;++i){ + profile_buf[i] = 0; + profile_old[i] = 0; + profile_counter[i] = 0; + } +} + +static void prof_out(void){ + if (profile_counter[PROF_BUF_SIZE - 1] != 1) { + LOGI("Error: You must call PROF_OPEN before PROF_CLOSE."); + } + LOGI("Total time is %6.3f ms.", + profile_buf[PROF_BUF_SIZE - 1] * 1000 / (double) CLOCKS_PER_SEC); + double all = 0; + for(int i = 0; i < PROF_BUF_SIZE - 1; ++i){ + all += profile_buf[i]; + } + if(all == 0) all = 1; + for(int i = 0; i < PROF_BUF_SIZE - 1; ++i){ + if(profile_buf[i] != 0) { + LOGI("(%d): Used %4.2f%%, %8.4f ms. Called %d times.", + i, (profile_buf[i] * 100 /all), + profile_buf[i] * 1000 / (double) CLOCKS_PER_SEC, profile_counter[i]); + } + } +} + #else // FLAG_DBG #define LOGI #define DEBUG_DICT false @@ -35,6 +81,18 @@ #define DEBUG_SHOW_FOUND_WORD false #define DEBUG_NODE false #define DEBUG_TRACE false + +#define PROF_BUF_SIZE 0 +#define PROF_RESET +#define PROF_COUNT(prof_buf_id) +#define PROF_OPEN +#define PROF_START(prof_buf_id) +#define PROF_CLOSE +#define PROF_END(prof_buf_id) +#define PROF_CLOCK_OUT(prof_buf_id) +#define PROF_CLOCKOUT(prof_buf_id) +#define PROF_OUTALL + #endif // FLAG_DBG #ifndef U_SHORT_MAX diff --git a/native/src/unigram_dictionary.cpp b/native/src/unigram_dictionary.cpp index f679001cf..af2cc97fc 100644 --- a/native/src/unigram_dictionary.cpp +++ b/native/src/unigram_dictionary.cpp @@ -42,14 +42,20 @@ UnigramDictionary::UnigramDictionary(const unsigned char *dict, int typedLetterM UnigramDictionary::~UnigramDictionary() {} int UnigramDictionary::getSuggestions(int *codes, int codesSize, unsigned short *outWords, - int *frequencies, int *nextLetters, int nextLettersSize) -{ + int *frequencies, int *nextLetters, int nextLettersSize) { + PROF_OPEN; + PROF_START(0); initSuggestions(codes, codesSize, outWords, frequencies); if (DEBUG_DICT) assert(codesSize == mInputLength); const int MAX_DEPTH = min(mInputLength * MAX_DEPTH_MULTIPLIER, MAX_WORD_LENGTH); + PROF_END(0); + + PROF_START(1); getSuggestionCandidates(-1, -1, -1, nextLetters, nextLettersSize, MAX_DEPTH); + PROF_END(1); + PROF_START(2); // Suggestion with missing character if (SUGGEST_WORDS_WITH_MISSING_CHARACTER) { for (int i = 0; i < codesSize; ++i) { @@ -57,7 +63,9 @@ int UnigramDictionary::getSuggestions(int *codes, int codesSize, unsigned short getSuggestionCandidates(i, -1, -1, NULL, 0, MAX_DEPTH); } } + PROF_END(2); + PROF_START(3); // Suggestion with excessive character if (SUGGEST_WORDS_WITH_EXCESSIVE_CHARACTER && mInputLength >= MIN_USER_TYPED_LENGTH_FOR_EXCESSIVE_CHARACTER_SUGGESTION) { @@ -66,7 +74,9 @@ int UnigramDictionary::getSuggestions(int *codes, int codesSize, unsigned short getSuggestionCandidates(-1, i, -1, NULL, 0, MAX_DEPTH); } } + PROF_END(3); + PROF_START(4); // Suggestion with transposed characters // Only suggest words that length is mInputLength if (SUGGEST_WORDS_WITH_TRANSPOSED_CHARACTERS) { @@ -75,7 +85,9 @@ int UnigramDictionary::getSuggestions(int *codes, int codesSize, unsigned short getSuggestionCandidates(-1, -1, i, NULL, 0, mInputLength - 1); } } + PROF_END(4); + PROF_START(5); // Suggestions with missing space if (SUGGEST_WORDS_WITH_MISSING_SPACE_CHARACTER && mInputLength >= MIN_USER_TYPED_LENGTH_FOR_MISSING_SPACE_SUGGESTION) { @@ -84,7 +96,9 @@ int UnigramDictionary::getSuggestions(int *codes, int codesSize, unsigned short getMissingSpaceWords(mInputLength, i); } } + PROF_END(5); + PROF_START(6); // Get the word count int suggestedWordsCount = 0; while (suggestedWordsCount < MAX_WORDS && mFrequencies[suggestedWordsCount] > 0) { @@ -101,7 +115,8 @@ int UnigramDictionary::getSuggestions(int *codes, int codesSize, unsigned short } LOGI("\n"); } - + PROF_END(6); + PROF_CLOSE; return suggestedWordsCount; } @@ -254,6 +269,14 @@ void UnigramDictionary::getSuggestionCandidates(const int skipPos, } } +inline static void multiplyRate(const int rate, int *freq) { + if (rate > 1000000) { + *freq = (*freq / 100) * rate; + } else { + *freq = *freq * rate / 100; + } +} + bool UnigramDictionary::getMissingSpaceWords(const int inputLength, const int missingSpacePos) { if (missingSpacePos <= 0 || missingSpacePos >= inputLength || inputLength >= MAX_WORD_LENGTH) return false; @@ -279,7 +302,7 @@ bool UnigramDictionary::getMissingSpaceWords(const int inputLength, const int mi int pairFreq = ((firstFreq + secondFreq) / 2); for (int i = 0; i < inputLength; ++i) pairFreq *= TYPED_LETTER_MULTIPLIER; - pairFreq = pairFreq * WORDS_WITH_MISSING_SPACE_CHARACTER_DEMOTION_RATE / 100; + multiplyRate(WORDS_WITH_MISSING_SPACE_CHARACTER_DEMOTION_RATE, &pairFreq); addWord(word, newWordLength, pairFreq); return true; } @@ -330,14 +353,13 @@ inline int UnigramDictionary::calculateFinalFreq(const int inputIndex, const int const bool sameLength) { // TODO: Demote by edit distance int finalFreq = freq * snr; - if (skipPos >= 0) finalFreq = finalFreq * WORDS_WITH_MISSING_CHARACTER_DEMOTION_RATE / 100; - if (transposedPos >= 0) finalFreq = finalFreq - * WORDS_WITH_TRANSPOSED_CHARACTERS_DEMOTION_RATE / 100; + if (skipPos >= 0) multiplyRate(WORDS_WITH_MISSING_CHARACTER_DEMOTION_RATE, &finalFreq); + if (transposedPos >= 0) multiplyRate( + WORDS_WITH_TRANSPOSED_CHARACTERS_DEMOTION_RATE, &finalFreq); if (excessivePos >= 0) { - finalFreq = finalFreq * WORDS_WITH_EXCESSIVE_CHARACTER_DEMOTION_RATE / 100; + multiplyRate(WORDS_WITH_EXCESSIVE_CHARACTER_DEMOTION_RATE, &finalFreq); if (!existsAdjacentProximityChars(inputIndex, mInputLength)) { - finalFreq = finalFreq - * WORDS_WITH_EXCESSIVE_CHARACTER_OUT_OF_PROXIMITY_DEMOTION_RATE / 100; + multiplyRate(WORDS_WITH_EXCESSIVE_CHARACTER_OUT_OF_PROXIMITY_DEMOTION_RATE, &finalFreq); } } if (sameLength && skipPos < 0) finalFreq *= FULL_WORD_MULTIPLIER; |