diff options
-rw-r--r-- | java/src/com/android/inputmethod/latin/BinaryDictionaryGetter.java | 4 | ||||
-rw-r--r-- | java/src/com/android/inputmethod/latin/DictionaryInfoUtils.java | 85 | ||||
-rw-r--r-- | java/src/com/android/inputmethod/latin/ExternalDictionaryGetterForDebug.java | 10 | ||||
-rw-r--r-- | java/src/com/android/inputmethod/latin/makedict/BinaryDictIOUtils.java | 21 | ||||
-rw-r--r-- | java/src/com/android/inputmethod/latin/makedict/FormatSpec.java | 12 | ||||
-rw-r--r-- | native/jni/src/correction.h | 13 | ||||
-rw-r--r-- | native/jni/src/defines.h | 27 | ||||
-rw-r--r-- | native/jni/src/proximity_info_params.cpp | 14 | ||||
-rw-r--r-- | native/jni/src/proximity_info_params.h | 20 | ||||
-rw-r--r-- | native/jni/src/proximity_info_state.cpp | 5 | ||||
-rw-r--r-- | native/jni/src/proximity_info_state.h | 2 | ||||
-rw-r--r-- | native/jni/src/proximity_info_state_utils.cpp | 77 | ||||
-rw-r--r-- | native/jni/src/words_priority_queue.h | 5 |
13 files changed, 192 insertions, 103 deletions
diff --git a/java/src/com/android/inputmethod/latin/BinaryDictionaryGetter.java b/java/src/com/android/inputmethod/latin/BinaryDictionaryGetter.java index 5da0f1be8..1cdc3b564 100644 --- a/java/src/com/android/inputmethod/latin/BinaryDictionaryGetter.java +++ b/java/src/com/android/inputmethod/latin/BinaryDictionaryGetter.java @@ -76,7 +76,7 @@ final class BinaryDictionaryGetter { /** * Returns a file address from a resource, or null if it cannot be opened. */ - private static AssetFileAddress loadFallbackResource(final Context context, + public static AssetFileAddress loadFallbackResource(final Context context, final int fallbackResId) { final AssetFileDescriptor afd = context.getResources().openRawResourceFd(fallbackResId); if (afd == null) { @@ -149,7 +149,7 @@ final class BinaryDictionaryGetter { * @param context the context on which to open the files upon. * @return an array of binary dictionary files, which may be empty but may not be null. */ - private static File[] getCachedWordLists(final String locale, final Context context) { + public static File[] getCachedWordLists(final String locale, final Context context) { final File[] directoryList = DictionaryInfoUtils.getCachedDirectoryList(context); if (null == directoryList) return EMPTY_FILE_ARRAY; final HashMap<String, FileAndMatchLevel> cacheFiles = CollectionUtils.newHashMap(); diff --git a/java/src/com/android/inputmethod/latin/DictionaryInfoUtils.java b/java/src/com/android/inputmethod/latin/DictionaryInfoUtils.java index c676bf1b9..8f16a8e4d 100644 --- a/java/src/com/android/inputmethod/latin/DictionaryInfoUtils.java +++ b/java/src/com/android/inputmethod/latin/DictionaryInfoUtils.java @@ -17,6 +17,7 @@ package com.android.inputmethod.latin; import android.content.Context; +import android.content.res.AssetManager; import android.content.res.Resources; import android.util.Log; @@ -26,6 +27,7 @@ import com.android.inputmethod.latin.makedict.UnsupportedFormatException; import java.io.File; import java.io.IOException; +import java.util.ArrayList; import java.util.Locale; /** @@ -41,6 +43,18 @@ public class DictionaryInfoUtils { // 6 digits - unicode is limited to 21 bits private static final int MAX_HEX_DIGITS_FOR_CODEPOINT = 6; + public static class DictionaryInfo { + public final Locale mLocale; + public final AssetFileAddress mFileAddress; + public final int mVersion; + public DictionaryInfo(final Locale locale, final AssetFileAddress fileAddress, + final int version) { + mLocale = locale; + mFileAddress = fileAddress; + mVersion = version; + } + } + private DictionaryInfoUtils() { // Private constructor to forbid instantation of this helper class. } @@ -234,12 +248,79 @@ public class DictionaryInfoUtils { public static FileHeader getDictionaryFileHeaderOrNull(final File file) { try { - final FileHeader header = BinaryDictIOUtils.getDictionaryFileHeader(file); - return header; + return BinaryDictIOUtils.getDictionaryFileHeader(file, 0, file.length()); } catch (UnsupportedFormatException e) { return null; } catch (IOException e) { return null; } } + + private static DictionaryInfo createDictionaryInfoFromFileAddress( + final AssetFileAddress fileAddress) { + final FileHeader header = BinaryDictIOUtils.getDictionaryFileHeaderOrNull( + new File(fileAddress.mFilename), fileAddress.mOffset, fileAddress.mLength); + final Locale locale = LocaleUtils.constructLocaleFromString(header.getLocaleString()); + final String version = header.getVersion(); + return new DictionaryInfo(locale, fileAddress, Integer.parseInt(version)); + } + + private static void addOrUpdateDictInfo(final ArrayList<DictionaryInfo> dictList, + final DictionaryInfo newElement) { + for (final DictionaryInfo info : dictList) { + if (info.mLocale.equals(newElement.mLocale)) { + if (newElement.mVersion <= info.mVersion) { + return; + } + dictList.remove(info); + } + } + dictList.add(newElement); + } + + public static ArrayList<DictionaryInfo> getCurrentDictionaryFileNameAndVersionInfo( + final Context context) { + final ArrayList<DictionaryInfo> dictList = CollectionUtils.newArrayList(); + + // Retrieve downloaded dictionaries + final File[] directoryList = getCachedDirectoryList(context); + for (final File directory : directoryList) { + final String localeString = getWordListIdFromFileName(directory.getName()); + File[] dicts = BinaryDictionaryGetter.getCachedWordLists(localeString, context); + for (final File dict : dicts) { + final String wordListId = getWordListIdFromFileName(dict.getName()); + if (!DictionaryInfoUtils.isMainWordListId(wordListId)) continue; + final Locale locale = LocaleUtils.constructLocaleFromString(localeString); + final AssetFileAddress fileAddress = AssetFileAddress.makeFromFile(dict); + final DictionaryInfo dictionaryInfo = + createDictionaryInfoFromFileAddress(fileAddress); + // Protect against cases of a less-specific dictionary being found, like an + // en dictionary being used for an en_US locale. In this case, the en dictionary + // should be used for en_US but discounted for listing purposes. + if (!dictionaryInfo.mLocale.equals(locale)) continue; + addOrUpdateDictInfo(dictList, dictionaryInfo); + } + } + + // Retrieve files from assets + final Resources resources = context.getResources(); + final AssetManager assets = resources.getAssets(); + for (final String localeString : assets.getLocales()) { + final Locale locale = LocaleUtils.constructLocaleFromString(localeString); + final int resourceId = + DictionaryInfoUtils.getMainDictionaryResourceIdIfAvailableForLocale( + context.getResources(), locale); + if (0 == resourceId) continue; + final AssetFileAddress fileAddress = + BinaryDictionaryGetter.loadFallbackResource(context, resourceId); + final DictionaryInfo dictionaryInfo = createDictionaryInfoFromFileAddress(fileAddress); + // Protect against cases of a less-specific dictionary being found, like an + // en dictionary being used for an en_US locale. In this case, the en dictionary + // should be used for en_US but discounted for listing purposes. + if (!dictionaryInfo.mLocale.equals(locale)) continue; + addOrUpdateDictInfo(dictList, dictionaryInfo); + } + + return dictList; + } } diff --git a/java/src/com/android/inputmethod/latin/ExternalDictionaryGetterForDebug.java b/java/src/com/android/inputmethod/latin/ExternalDictionaryGetterForDebug.java index d9e4bb63d..9f91639a2 100644 --- a/java/src/com/android/inputmethod/latin/ExternalDictionaryGetterForDebug.java +++ b/java/src/com/android/inputmethod/latin/ExternalDictionaryGetterForDebug.java @@ -39,7 +39,6 @@ import java.util.Locale; public class ExternalDictionaryGetterForDebug { private static final String SOURCE_FOLDER = Environment.getExternalStorageDirectory().getPath() + "/Download"; - private static final String DICTIONARY_LOCALE_ATTRIBUTE = "locale"; private static String[] findDictionariesInTheDownloadedFolder() { final File[] files = new File(SOURCE_FOLDER).listFiles(); @@ -90,8 +89,7 @@ public class ExternalDictionaryGetterForDebug { final File file = new File(SOURCE_FOLDER, fileName.toString()); final FileHeader header = DictionaryInfoUtils.getDictionaryFileHeaderOrNull(file); final StringBuilder message = new StringBuilder(); - final String locale = - header.mDictionaryOptions.mAttributes.get(DICTIONARY_LOCALE_ATTRIBUTE); + final String locale = header.getLocaleString(); for (String key : header.mDictionaryOptions.mAttributes.keySet()) { message.append(key + " = " + header.mDictionaryOptions.mAttributes.get(key)); message.append("\n"); @@ -123,13 +121,11 @@ public class ExternalDictionaryGetterForDebug { BufferedOutputStream outputStream = null; File tempFile = null; try { - final String locale = - header.mDictionaryOptions.mAttributes.get(DICTIONARY_LOCALE_ATTRIBUTE); + final String locale = header.getLocaleString(); // Create the id for a main dictionary for this locale final String id = BinaryDictionaryGetter.MAIN_DICTIONARY_CATEGORY + BinaryDictionaryGetter.ID_CATEGORY_SEPARATOR + locale; - final String finalFileName = - DictionaryInfoUtils.getCacheFileName(id, locale, context); + final String finalFileName = DictionaryInfoUtils.getCacheFileName(id, locale, context); final String tempFileName = BinaryDictionaryGetter.getTempFileName(id, context); tempFile = new File(tempFileName); tempFile.delete(); diff --git a/java/src/com/android/inputmethod/latin/makedict/BinaryDictIOUtils.java b/java/src/com/android/inputmethod/latin/makedict/BinaryDictIOUtils.java index 9e1f7517d..c87a9254d 100644 --- a/java/src/com/android/inputmethod/latin/makedict/BinaryDictIOUtils.java +++ b/java/src/com/android/inputmethod/latin/makedict/BinaryDictIOUtils.java @@ -988,20 +988,35 @@ public final class BinaryDictIOUtils { * This is quite resource intensive - don't call when performance is critical. * * @param file The file to read. + * @param offset The offset in the file where to start reading the data. + * @param length The length of the data file. */ private static final int HEADER_READING_BUFFER_SIZE = 16384; - public static FileHeader getDictionaryFileHeader(final File file) - throws FileNotFoundException, IOException, UnsupportedFormatException { + public static FileHeader getDictionaryFileHeader( + final File file, final long offset, final long length) + throws FileNotFoundException, IOException, UnsupportedFormatException { final byte[] buffer = new byte[HEADER_READING_BUFFER_SIZE]; final FileInputStream inStream = new FileInputStream(file); try { inStream.read(buffer); final BinaryDictInputOutput.ByteBufferWrapper wrapper = new BinaryDictInputOutput.ByteBufferWrapper(inStream.getChannel().map( - FileChannel.MapMode.READ_ONLY, 0, file.length())); + FileChannel.MapMode.READ_ONLY, offset, length)); return BinaryDictInputOutput.readHeader(wrapper); } finally { inStream.close(); } } + + public static FileHeader getDictionaryFileHeaderOrNull(final File file, final long offset, + final long length) { + try { + final FileHeader header = getDictionaryFileHeader(file, offset, length); + return header; + } catch (UnsupportedFormatException e) { + return null; + } catch (IOException e) { + return null; + } + } } diff --git a/java/src/com/android/inputmethod/latin/makedict/FormatSpec.java b/java/src/com/android/inputmethod/latin/makedict/FormatSpec.java index c22ea3ba1..83acca874 100644 --- a/java/src/com/android/inputmethod/latin/makedict/FormatSpec.java +++ b/java/src/com/android/inputmethod/latin/makedict/FormatSpec.java @@ -256,12 +256,24 @@ public final class FormatSpec { public final int mHeaderSize; public final DictionaryOptions mDictionaryOptions; public final FormatOptions mFormatOptions; + private static final String DICTIONARY_VERSION_ATTRIBUTE = "version"; + private static final String DICTIONARY_LOCALE_ATTRIBUTE = "locale"; public FileHeader(final int headerSize, final DictionaryOptions dictionaryOptions, final FormatOptions formatOptions) { mHeaderSize = headerSize; mDictionaryOptions = dictionaryOptions; mFormatOptions = formatOptions; } + + // Helper method to get the locale as a String + public String getLocaleString() { + return mDictionaryOptions.mAttributes.get(FileHeader.DICTIONARY_LOCALE_ATTRIBUTE); + } + + // Helper method to get the version String + public String getVersion() { + return mDictionaryOptions.mAttributes.get(FileHeader.DICTIONARY_VERSION_ATTRIBUTE); + } } private FormatSpec() { diff --git a/native/jni/src/correction.h b/native/jni/src/correction.h index 0873daef3..34f794d84 100644 --- a/native/jni/src/correction.h +++ b/native/jni/src/correction.h @@ -170,11 +170,10 @@ class Correction { if (n <= 0) return 1; if (base == 2) { return n < 31 ? 1 << n : S_INT_MAX; - } else { - int ret = base; - for (int i = 1; i < n; ++i) multiplyIntCapped(base, &ret); - return ret; } + int ret = base; + for (int i = 1; i < n; ++i) multiplyIntCapped(base, &ret); + return ret; } AK_FORCE_INLINE static void multiplyRate(const int rate, int *freq) { @@ -318,13 +317,11 @@ AK_FORCE_INLINE Correction::CorrectionType Correction::processSkipChar(const int addCharToCurrentWord(c); mTerminalInputIndex = mInputIndex - (inputIndexIncremented ? 1 : 0); mTerminalOutputIndex = mOutputIndex; + incrementOutputIndex(); if (mNeedsToTraverseAllNodes && isTerminal) { - incrementOutputIndex(); return TRAVERSE_ALL_ON_TERMINAL; - } else { - incrementOutputIndex(); - return TRAVERSE_ALL_NOT_ON_TERMINAL; } + return TRAVERSE_ALL_NOT_ON_TERMINAL; } inline Correction::CorrectionType Correction::processUnrelatedCorrectionType() { diff --git a/native/jni/src/defines.h b/native/jni/src/defines.h index 9883168fe..a1fdae7a4 100644 --- a/native/jni/src/defines.h +++ b/native/jni/src/defines.h @@ -267,21 +267,6 @@ static inline void prof_out(void) { // loading time, and acceptable even for several initial lookups which involve page faults. #define USE_MMAP_FOR_DICTIONARY -// 22-bit address = ~4MB dictionary size limit, which on average would be about 200k-300k words -#define ADDRESS_MASK 0x3FFFFF - -// The bit that decides if an address follows in the next 22 bits -#define FLAG_ADDRESS_MASK 0x40 -// The bit that decides if this is a terminal node for a word. The node could still have children, -// if the word has other endings. -#define FLAG_TERMINAL_MASK 0x80 - -#define FLAG_BIGRAM_READ 0x80 -#define FLAG_BIGRAM_CHILDEXIST 0x40 -#define FLAG_BIGRAM_CONTINUED 0x80 -#define FLAG_BIGRAM_FREQ 0x7F - -#define DICTIONARY_VERSION_MIN 200 #define NOT_VALID_WORD (-99) #define NOT_A_CODE_POINT (-1) #define NOT_A_DISTANCE (-1) @@ -297,10 +282,6 @@ static inline void prof_out(void) { #define KEYCODE_HYPHEN_MINUS '-' #define CALIBRATE_SCORE_BY_TOUCH_COORDINATES true - -#define SUGGEST_WORDS_WITH_MISSING_CHARACTER true -#define SUGGEST_WORDS_WITH_EXCESSIVE_CHARACTER true -#define SUGGEST_WORDS_WITH_TRANSPOSED_CHARACTERS true #define SUGGEST_MULTIPLE_WORDS true // The following "rate"s are used as a multiplier before dividing by 100, so they are in percent. @@ -366,7 +347,6 @@ static inline void prof_out(void) { #define DEFAULT_MAX_DIGRAPH_SEARCH_DEPTH 5 #define MIN_USER_TYPED_LENGTH_FOR_MULTIPLE_WORD_SUGGESTION 3 -#define MIN_USER_TYPED_LENGTH_FOR_EXCESSIVE_CHARACTER_SUGGESTION 3 // TODO: Remove #define MAX_POINTER_COUNT 1 @@ -390,14 +370,11 @@ static inline void prof_out(void) { #error "BIGRAM_FILTER_MODULO is larger than BIGRAM_FILTER_BYTE_SIZE" #endif -template<typename T> inline T min(T a, T b) { return a < b ? a : b; } -template<typename T> inline T max(T a, T b) { return a > b ? a : b; } +template<typename T> AK_FORCE_INLINE const T &min(const T &a, const T &b) { return a < b ? a : b; } +template<typename T> AK_FORCE_INLINE const T &max(const T &a, const T &b) { return a > b ? a : b; } #define NELEMS(x) (sizeof(x) / sizeof((x)[0])) -// The ratio of neutral area radius to sweet spot radius. -#define NEUTRAL_AREA_RADIUS_RATIO 1.3f - // DEBUG #define INPUTLENGTH_FOR_DEBUG (-1) #define MIN_OUTPUT_INDEX_FOR_DEBUG (-1) diff --git a/native/jni/src/proximity_info_params.cpp b/native/jni/src/proximity_info_params.cpp index 5a51f62d9..f7b3d4d71 100644 --- a/native/jni/src/proximity_info_params.cpp +++ b/native/jni/src/proximity_info_params.cpp @@ -25,6 +25,20 @@ const int ProximityInfoParams::NORMALIZED_SQUARED_DISTANCE_SCALING_FACTOR_LOG_2 const int ProximityInfoParams::NORMALIZED_SQUARED_DISTANCE_SCALING_FACTOR = 1 << NORMALIZED_SQUARED_DISTANCE_SCALING_FACTOR_LOG_2; const float ProximityInfoParams::NOT_A_DISTANCE_FLOAT = -1.0f; + +// Per method constants +const float ProximityInfoParams::NEAR_KEY_NORMALIZED_SQUARED_THRESHOLD = 4.0f; +const float ProximityInfoParams::NEAR_KEY_THRESHOLD_FOR_DISTANCE = 2.0f; +const float ProximityInfoParams::MARGIN_FOR_PREV_LOCAL_MIN = 0.01f; +const int ProximityInfoParams::DISTANCE_BASE_SCALE = 100; +const float ProximityInfoParams::NEAR_KEY_THRESHOLD_FOR_POINT_SCORE = 0.6f; +const int ProximityInfoParams::CORNER_CHECK_DISTANCE_THRESHOLD_SCALE = 25; +const float ProximityInfoParams::NOT_LOCALMIN_DISTANCE_SCORE = -1.0f; +const float ProximityInfoParams::LOCALMIN_DISTANCE_AND_NEAR_TO_KEY_SCORE = 1.0f; +const float ProximityInfoParams::CORNER_ANGLE_THRESHOLD_FOR_POINT_SCORE = M_PI_F * 2.0f / 3.0f; +const float ProximityInfoParams::CORNER_SUM_ANGLE_THRESHOLD = M_PI_F / 4.0f; +const float ProximityInfoParams::CORNER_SCORE = 1.0f; + // TODO: Investigate if this is required const float ProximityInfoParams::SEARCH_KEY_RADIUS_RATIO = 0.95f; } // namespace latinime diff --git a/native/jni/src/proximity_info_params.h b/native/jni/src/proximity_info_params.h index b941fec0b..978b99917 100644 --- a/native/jni/src/proximity_info_params.h +++ b/native/jni/src/proximity_info_params.h @@ -30,6 +30,26 @@ class ProximityInfoParams { static const int NORMALIZED_SQUARED_DISTANCE_SCALING_FACTOR; static const float NOT_A_DISTANCE_FLOAT; static const float SEARCH_KEY_RADIUS_RATIO; + + // Used by ProximityInfoStateUtils::initGeometricDistanceInfos() + static const float NEAR_KEY_NORMALIZED_SQUARED_THRESHOLD; + + // Used by ProximityInfoStateUtils::updateNearKeysDistances() + static const float NEAR_KEY_THRESHOLD_FOR_DISTANCE; + + // Used by ProximityInfoStateUtils::isPrevLocalMin() + static const float MARGIN_FOR_PREV_LOCAL_MIN; + + // Used by ProximityInfoStateUtils::getPointScore() + static const int DISTANCE_BASE_SCALE; + static const float NEAR_KEY_THRESHOLD_FOR_POINT_SCORE; + static const int CORNER_CHECK_DISTANCE_THRESHOLD_SCALE; + static const float NOT_LOCALMIN_DISTANCE_SCORE; + static const float LOCALMIN_DISTANCE_AND_NEAR_TO_KEY_SCORE; + static const float CORNER_ANGLE_THRESHOLD_FOR_POINT_SCORE; + static const float CORNER_SUM_ANGLE_THRESHOLD; + static const float CORNER_SCORE; + private: DISALLOW_IMPLICIT_CONSTRUCTORS(ProximityInfoParams); static const int NORMALIZED_SQUARED_DISTANCE_SCALING_FACTOR_LOG_2; diff --git a/native/jni/src/proximity_info_state.cpp b/native/jni/src/proximity_info_state.cpp index 141be2688..fbdc2c816 100644 --- a/native/jni/src/proximity_info_state.cpp +++ b/native/jni/src/proximity_info_state.cpp @@ -246,11 +246,6 @@ ProximityType ProximityInfoState::getMatchedProximityId(const int index, const i return UNRELATED_CHAR; } -int ProximityInfoState::getSpaceY() const { - const int keyId = mProximityInfo->getKeyIndexOf(KEYCODE_SPACE); - return mProximityInfo->getKeyCenterYOfKeyIdG(keyId); -} - // Puts possible characters into filter and returns new filter size. int ProximityInfoState::getAllPossibleChars( const size_t index, int *const filter, const int filterSize) const { diff --git a/native/jni/src/proximity_info_state.h b/native/jni/src/proximity_info_state.h index ff1b35089..0386450bd 100644 --- a/native/jni/src/proximity_info_state.h +++ b/native/jni/src/proximity_info_state.h @@ -155,8 +155,6 @@ class ProximityInfoState { ProximityType getMatchedProximityId(const int index, const int c, const bool checkProximityChars, int *proximityIndex = 0) const; - int getSpaceY() const; - int getAllPossibleChars(const size_t startIndex, int *const filter, const int filterSize) const; float getSpeedRate(const int index) const { diff --git a/native/jni/src/proximity_info_state_utils.cpp b/native/jni/src/proximity_info_state_utils.cpp index ac74a4e91..da3f03deb 100644 --- a/native/jni/src/proximity_info_state_utils.cpp +++ b/native/jni/src/proximity_info_state_utils.cpp @@ -138,13 +138,13 @@ namespace latinime { return inputProximities + (index * MAX_PROXIMITY_CHARS_SIZE); } -/* static */ int ProximityInfoStateUtils::getPrimaryCodePointAt( - const int *const inputProximities, const int index) { +/* static */ int ProximityInfoStateUtils::getPrimaryCodePointAt(const int *const inputProximities, + const int index) { return getProximityCodePointsAt(inputProximities, index)[0]; } -/* static */ void ProximityInfoStateUtils::initPrimaryInputWord( - const int inputSize, const int *const inputProximities, int *primaryInputWord) { +/* static */ void ProximityInfoStateUtils::initPrimaryInputWord(const int inputSize, + const int *const inputProximities, int *primaryInputWord) { memset(primaryInputWord, 0, sizeof(primaryInputWord[0]) * MAX_WORD_LENGTH); for (int i = 0; i < inputSize; ++i) { primaryInputWord[i] = getPrimaryCodePointAt(inputProximities, i); @@ -153,8 +153,7 @@ namespace latinime { /* static */ float ProximityInfoStateUtils::calculateSquaredDistanceFromSweetSpotCenter( const ProximityInfo *const proximityInfo, const std::vector<int> *const sampledInputXs, - const std::vector<int> *const sampledInputYs, const int keyIndex, - const int inputIndex) { + const std::vector<int> *const sampledInputYs, const int keyIndex, const int inputIndex) { const float sweetSpotCenterX = proximityInfo->getSweetSpotCenterXAt(keyIndex); const float sweetSpotCenterY = proximityInfo->getSweetSpotCenterYAt(keyIndex); const float inputX = static_cast<float>((*sampledInputXs)[inputIndex]); @@ -164,8 +163,7 @@ namespace latinime { /* static */ float ProximityInfoStateUtils::calculateNormalizedSquaredDistance( const ProximityInfo *const proximityInfo, const std::vector<int> *const sampledInputXs, - const std::vector<int> *const sampledInputYs, - const int keyIndex, const int inputIndex) { + const std::vector<int> *const sampledInputYs, const int keyIndex, const int inputIndex) { if (keyIndex == NOT_AN_INDEX) { return ProximityInfoParams::NOT_A_DISTANCE_FLOAT; } @@ -182,11 +180,9 @@ namespace latinime { } /* static */ void ProximityInfoStateUtils::initNormalizedSquaredDistances( - const ProximityInfo *const proximityInfo, const int inputSize, - const int *inputXCoordinates, const int *inputYCoordinates, - const int *const inputProximities, - const std::vector<int> *const sampledInputXs, - const std::vector<int> *const sampledInputYs, + const ProximityInfo *const proximityInfo, const int inputSize, const int *inputXCoordinates, + const int *inputYCoordinates, const int *const inputProximities, + const std::vector<int> *const sampledInputXs, const std::vector<int> *const sampledInputYs, int *normalizedSquaredDistances) { memset(normalizedSquaredDistances, NOT_A_DISTANCE, sizeof(normalizedSquaredDistances[0]) * MAX_PROXIMITY_CHARS_SIZE * MAX_WORD_LENGTH); @@ -201,8 +197,7 @@ namespace latinime { a += 0; AKLOGI("--- Primary = %c, x = %d, y = %d", primaryKey, x, y); } - for (int j = 0; j < MAX_PROXIMITY_CHARS_SIZE && proximityCodePoints[j] > 0; - ++j) { + for (int j = 0; j < MAX_PROXIMITY_CHARS_SIZE && proximityCodePoints[j] > 0; ++j) { const int currentCodePoint = proximityCodePoints[j]; const float squaredDistance = hasInputCoordinates ? calculateNormalizedSquaredDistance( @@ -227,9 +222,8 @@ namespace latinime { } /* static */ void ProximityInfoStateUtils::initGeometricDistanceInfos( - const ProximityInfo *const proximityInfo, const int keyCount, - const int sampledInputSize, const int lastSavedInputSize, - const std::vector<int> *const sampledInputXs, + const ProximityInfo *const proximityInfo, const int keyCount, const int sampledInputSize, + const int lastSavedInputSize, const std::vector<int> *const sampledInputXs, const std::vector<int> *const sampledInputYs, std::vector<NearKeycodesSet> *SampledNearKeysVector, std::vector<float> *SampledDistanceCache_G) { @@ -237,7 +231,6 @@ namespace latinime { SampledDistanceCache_G->resize(sampledInputSize * keyCount); for (int i = lastSavedInputSize; i < sampledInputSize; ++i) { (*SampledNearKeysVector)[i].reset(); - static const float NEAR_KEY_NORMALIZED_SQUARED_THRESHOLD = 4.0f; for (int k = 0; k < keyCount; ++k) { const int index = i * keyCount + k; const int x = (*sampledInputXs)[i]; @@ -245,7 +238,8 @@ namespace latinime { const float normalizedSquaredDistance = proximityInfo->getNormalizedSquaredDistanceFromCenterFloatG(k, x, y); (*SampledDistanceCache_G)[index] = normalizedSquaredDistance; - if (normalizedSquaredDistance < NEAR_KEY_NORMALIZED_SQUARED_THRESHOLD) { + if (normalizedSquaredDistance + < ProximityInfoParams::NEAR_KEY_NORMALIZED_SQUARED_THRESHOLD) { (*SampledNearKeysVector)[i][k] = true; } } @@ -265,8 +259,7 @@ namespace latinime { /* static */ float ProximityInfoStateUtils::refreshSpeedRates(const int inputSize, const int *const xCoordinates, const int *const yCoordinates, const int *const times, const int lastSavedInputSize, const int sampledInputSize, - const std::vector<int> *const sampledInputXs, - const std::vector<int> *const sampledInputYs, + const std::vector<int> *const sampledInputXs, const std::vector<int> *const sampledInputYs, const std::vector<int> *const sampledInputTimes, const std::vector<int> *const sampledLengthCache, const std::vector<int> *const sampledInputIndice, std::vector<float> *sampledSpeedRates, @@ -359,14 +352,12 @@ namespace latinime { /* static */ float ProximityInfoStateUtils::updateNearKeysDistances( const ProximityInfo *const proximityInfo, const float maxPointToKeyLength, const int x, const int y, NearKeysDistanceMap *const currentNearKeysDistances) { - static const float NEAR_KEY_THRESHOLD = 2.0f; - currentNearKeysDistances->clear(); const int keyCount = proximityInfo->getKeyCount(); float nearestKeyDistance = maxPointToKeyLength; for (int k = 0; k < keyCount; ++k) { const float dist = proximityInfo->getNormalizedSquaredDistanceFromCenterFloatG(k, x, y); - if (dist < NEAR_KEY_THRESHOLD) { + if (dist < ProximityInfoParams::NEAR_KEY_THRESHOLD_FOR_DISTANCE) { currentNearKeysDistances->insert(std::pair<int, float>(k, dist)); } if (nearestKeyDistance > dist) { @@ -381,14 +372,15 @@ namespace latinime { const NearKeysDistanceMap *const currentNearKeysDistances, const NearKeysDistanceMap *const prevNearKeysDistances, const NearKeysDistanceMap *const prevPrevNearKeysDistances) { - static const float MARGIN = 0.01f; - for (NearKeysDistanceMap::const_iterator it = prevNearKeysDistances->begin(); it != prevNearKeysDistances->end(); ++it) { NearKeysDistanceMap::const_iterator itPP = prevPrevNearKeysDistances->find(it->first); NearKeysDistanceMap::const_iterator itC = currentNearKeysDistances->find(it->first); - if ((itPP == prevPrevNearKeysDistances->end() || itPP->second > it->second + MARGIN) - && (itC == currentNearKeysDistances->end() || itC->second > it->second + MARGIN)) { + const bool isPrevPrevNear = (itPP == prevPrevNearKeysDistances->end() + || itPP->second > it->second + ProximityInfoParams::MARGIN_FOR_PREV_LOCAL_MIN); + const bool isCurrentNear = (itC == currentNearKeysDistances->end() + || itC->second > it->second + ProximityInfoParams::MARGIN_FOR_PREV_LOCAL_MIN); + if (isPrevPrevNear && isCurrentNear) { return true; } } @@ -402,15 +394,6 @@ namespace latinime { const NearKeysDistanceMap *const prevNearKeysDistances, const NearKeysDistanceMap *const prevPrevNearKeysDistances, std::vector<int> *sampledInputXs, std::vector<int> *sampledInputYs) { - static const int DISTANCE_BASE_SCALE = 100; - static const float NEAR_KEY_THRESHOLD = 0.6f; - static const int CORNER_CHECK_DISTANCE_THRESHOLD_SCALE = 25; - static const float NOT_LOCALMIN_DISTANCE_SCORE = -1.0f; - static const float LOCALMIN_DISTANCE_AND_NEAR_TO_KEY_SCORE = 1.0f; - static const float CORNER_ANGLE_THRESHOLD = M_PI_F * 2.0f / 3.0f; - static const float CORNER_SUM_ANGLE_THRESHOLD = M_PI_F / 4.0f; - static const float CORNER_SCORE = 1.0f; - const size_t size = sampledInputXs->size(); // If there is only one point, add this point. Besides, if the previous point's distance map // is empty, we re-compute nearby keys distances from the current point. @@ -422,16 +405,17 @@ namespace latinime { const int baseSampleRate = mostCommonKeyWidth; const int distPrev = getDistanceInt(sampledInputXs->back(), sampledInputYs->back(), - (*sampledInputXs)[size - 2], (*sampledInputYs)[size - 2]) * DISTANCE_BASE_SCALE; + (*sampledInputXs)[size - 2], (*sampledInputYs)[size - 2]) + * ProximityInfoParams::DISTANCE_BASE_SCALE; float score = 0.0f; // Location if (!isPrevLocalMin(currentNearKeysDistances, prevNearKeysDistances, prevPrevNearKeysDistances)) { - score += NOT_LOCALMIN_DISTANCE_SCORE; - } else if (nearest < NEAR_KEY_THRESHOLD) { + score += ProximityInfoParams::NOT_LOCALMIN_DISTANCE_SCORE; + } else if (nearest < ProximityInfoParams::NEAR_KEY_THRESHOLD_FOR_POINT_SCORE) { // Promote points nearby keys - score += LOCALMIN_DISTANCE_AND_NEAR_TO_KEY_SCORE; + score += ProximityInfoParams::LOCALMIN_DISTANCE_AND_NEAR_TO_KEY_SCORE; } // Angle const float angle1 = getAngle(x, y, sampledInputXs->back(), sampledInputYs->back()); @@ -440,9 +424,10 @@ namespace latinime { const float angleDiff = getAngleDiff(angle1, angle2); // Save corner - if (distPrev > baseSampleRate * CORNER_CHECK_DISTANCE_THRESHOLD_SCALE - && (sumAngle > CORNER_SUM_ANGLE_THRESHOLD || angleDiff > CORNER_ANGLE_THRESHOLD)) { - score += CORNER_SCORE; + if (distPrev > baseSampleRate * ProximityInfoParams::CORNER_CHECK_DISTANCE_THRESHOLD_SCALE + && (sumAngle > ProximityInfoParams::CORNER_SUM_ANGLE_THRESHOLD + || angleDiff > ProximityInfoParams::CORNER_ANGLE_THRESHOLD_FOR_POINT_SCORE)) { + score += ProximityInfoParams::CORNER_SCORE; } return score; } @@ -1033,7 +1018,7 @@ namespace latinime { const ProximityInfo *const proximityInfo, const int sampledInputSize, const std::vector<hash_map_compat<int, float> > *const charProbabilities, int *const codePointBuf) { - ASSERT(charProbabilities->size() >= 0 && sampledInputSize >= 0); + ASSERT(sampledInputSize >= 0); memset(codePointBuf, 0, sizeof(codePointBuf[0]) * MAX_WORD_LENGTH); static const float DEMOTION_LOG_PROBABILITY = 0.3f; int index = 0; diff --git a/native/jni/src/words_priority_queue.h b/native/jni/src/words_priority_queue.h index 8a22f051a..54e8007a2 100644 --- a/native/jni/src/words_priority_queue.h +++ b/native/jni/src/words_priority_queue.h @@ -63,10 +63,9 @@ class WordsPriorityQueue { const int minScore = sw->mScore; if (minScore >= score) { return; - } else { - sw->mUsed = false; - mSuggestions.pop(); } + sw->mUsed = false; + mSuggestions.pop(); } if (sw == 0) { sw = getFreeSuggestedWord(score, word, wordLength, type); |