13107b467c91c471ce4e00c5d8de559f7b0da2cd6Satoshi Kataoka/* 23107b467c91c471ce4e00c5d8de559f7b0da2cd6Satoshi Kataoka * Copyright (C) 2012 The Android Open Source Project 33107b467c91c471ce4e00c5d8de559f7b0da2cd6Satoshi Kataoka * 43107b467c91c471ce4e00c5d8de559f7b0da2cd6Satoshi Kataoka * Licensed under the Apache License, Version 2.0 (the "License"); 53107b467c91c471ce4e00c5d8de559f7b0da2cd6Satoshi Kataoka * you may not use this file except in compliance with the License. 63107b467c91c471ce4e00c5d8de559f7b0da2cd6Satoshi Kataoka * You may obtain a copy of the License at 73107b467c91c471ce4e00c5d8de559f7b0da2cd6Satoshi Kataoka * 83107b467c91c471ce4e00c5d8de559f7b0da2cd6Satoshi Kataoka * http://www.apache.org/licenses/LICENSE-2.0 93107b467c91c471ce4e00c5d8de559f7b0da2cd6Satoshi Kataoka * 103107b467c91c471ce4e00c5d8de559f7b0da2cd6Satoshi Kataoka * Unless required by applicable law or agreed to in writing, software 113107b467c91c471ce4e00c5d8de559f7b0da2cd6Satoshi Kataoka * distributed under the License is distributed on an "AS IS" BASIS, 123107b467c91c471ce4e00c5d8de559f7b0da2cd6Satoshi Kataoka * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 133107b467c91c471ce4e00c5d8de559f7b0da2cd6Satoshi Kataoka * See the License for the specific language governing permissions and 143107b467c91c471ce4e00c5d8de559f7b0da2cd6Satoshi Kataoka * limitations under the License. 153107b467c91c471ce4e00c5d8de559f7b0da2cd6Satoshi Kataoka */ 163107b467c91c471ce4e00c5d8de559f7b0da2cd6Satoshi Kataoka 173107b467c91c471ce4e00c5d8de559f7b0da2cd6Satoshi Kataoka#ifndef LATINIME_DIC_TRAVERSE_SESSION_H 183107b467c91c471ce4e00c5d8de559f7b0da2cd6Satoshi Kataoka#define LATINIME_DIC_TRAVERSE_SESSION_H 193107b467c91c471ce4e00c5d8de559f7b0da2cd6Satoshi Kataoka 203107b467c91c471ce4e00c5d8de559f7b0da2cd6Satoshi Kataoka#include <stdint.h> 213107b467c91c471ce4e00c5d8de559f7b0da2cd6Satoshi Kataoka#include <vector> 223107b467c91c471ce4e00c5d8de559f7b0da2cd6Satoshi Kataoka 233107b467c91c471ce4e00c5d8de559f7b0da2cd6Satoshi Kataoka#include "defines.h" 243107b467c91c471ce4e00c5d8de559f7b0da2cd6Satoshi Kataoka#include "jni.h" 259559dd2e30de288a9ff7069bfc59f8500b949a88Tom Ouyang#include "multi_bigram_map.h" 263107b467c91c471ce4e00c5d8de559f7b0da2cd6Satoshi Kataoka#include "proximity_info_state.h" 27b68e73448104714e8f12f89a1e00fb10b5fd14c4Ken Wakasa#include "suggest/core/dicnode/dic_nodes_cache.h" 283107b467c91c471ce4e00c5d8de559f7b0da2cd6Satoshi Kataoka 293107b467c91c471ce4e00c5d8de559f7b0da2cd6Satoshi Kataokanamespace latinime { 303107b467c91c471ce4e00c5d8de559f7b0da2cd6Satoshi Kataoka 313107b467c91c471ce4e00c5d8de559f7b0da2cd6Satoshi Kataokaclass Dictionary; 323107b467c91c471ce4e00c5d8de559f7b0da2cd6Satoshi Kataokaclass ProximityInfo; 333107b467c91c471ce4e00c5d8de559f7b0da2cd6Satoshi Kataoka 343107b467c91c471ce4e00c5d8de559f7b0da2cd6Satoshi Kataokaclass DicTraverseSession { 353107b467c91c471ce4e00c5d8de559f7b0da2cd6Satoshi Kataoka public: 363107b467c91c471ce4e00c5d8de559f7b0da2cd6Satoshi Kataoka AK_FORCE_INLINE DicTraverseSession(JNIEnv *env, jstring localeStr) 373107b467c91c471ce4e00c5d8de559f7b0da2cd6Satoshi Kataoka : mPrevWordPos(NOT_VALID_WORD), mProximityInfo(0), 389559dd2e30de288a9ff7069bfc59f8500b949a88Tom Ouyang mDictionary(0), mDicNodesCache(), mMultiBigramMap(), 39252412d7eb4573f91588b06b0fe49ef9f0ac38acSatoshi Kataoka mInputSize(0), mPartiallyCommited(false), mMaxPointerCount(1), 40252412d7eb4573f91588b06b0fe49ef9f0ac38acSatoshi Kataoka mMultiWordCostMultiplier(1.0f) { 413107b467c91c471ce4e00c5d8de559f7b0da2cd6Satoshi Kataoka // NOTE: mProximityInfoStates is an array of instances. 423107b467c91c471ce4e00c5d8de559f7b0da2cd6Satoshi Kataoka // No need to initialize it explicitly here. 433107b467c91c471ce4e00c5d8de559f7b0da2cd6Satoshi Kataoka } 443107b467c91c471ce4e00c5d8de559f7b0da2cd6Satoshi Kataoka 453107b467c91c471ce4e00c5d8de559f7b0da2cd6Satoshi Kataoka // Non virtual inline destructor -- never inherit this class 463107b467c91c471ce4e00c5d8de559f7b0da2cd6Satoshi Kataoka AK_FORCE_INLINE ~DicTraverseSession() {} 473107b467c91c471ce4e00c5d8de559f7b0da2cd6Satoshi Kataoka 483107b467c91c471ce4e00c5d8de559f7b0da2cd6Satoshi Kataoka void init(const Dictionary *dictionary, const int *prevWord, int prevWordLength); 493107b467c91c471ce4e00c5d8de559f7b0da2cd6Satoshi Kataoka // TODO: Remove and merge into init 503107b467c91c471ce4e00c5d8de559f7b0da2cd6Satoshi Kataoka void setupForGetSuggestions(const ProximityInfo *pInfo, const int *inputCodePoints, 513107b467c91c471ce4e00c5d8de559f7b0da2cd6Satoshi Kataoka const int inputSize, const int *const inputXs, const int *const inputYs, 523107b467c91c471ce4e00c5d8de559f7b0da2cd6Satoshi Kataoka const int *const times, const int *const pointerIds, const float maxSpatialDistance, 533107b467c91c471ce4e00c5d8de559f7b0da2cd6Satoshi Kataoka const int maxPointerCount); 543107b467c91c471ce4e00c5d8de559f7b0da2cd6Satoshi Kataoka void resetCache(const int nextActiveCacheSize, const int maxWords); 553107b467c91c471ce4e00c5d8de559f7b0da2cd6Satoshi Kataoka 56252412d7eb4573f91588b06b0fe49ef9f0ac38acSatoshi Kataoka // TODO: Remove 573107b467c91c471ce4e00c5d8de559f7b0da2cd6Satoshi Kataoka const uint8_t *getOffsetDict() const; 58ede2333640accecc066de328cb4f93e03e4bc5d7Tom Ouyang int getDictFlags() const; 593107b467c91c471ce4e00c5d8de559f7b0da2cd6Satoshi Kataoka 603107b467c91c471ce4e00c5d8de559f7b0da2cd6Satoshi Kataoka //-------------------- 613107b467c91c471ce4e00c5d8de559f7b0da2cd6Satoshi Kataoka // getters and setters 623107b467c91c471ce4e00c5d8de559f7b0da2cd6Satoshi Kataoka //-------------------- 633107b467c91c471ce4e00c5d8de559f7b0da2cd6Satoshi Kataoka const ProximityInfo *getProximityInfo() const { return mProximityInfo; } 643107b467c91c471ce4e00c5d8de559f7b0da2cd6Satoshi Kataoka int getPrevWordPos() const { return mPrevWordPos; } 653107b467c91c471ce4e00c5d8de559f7b0da2cd6Satoshi Kataoka // TODO: REMOVE 663107b467c91c471ce4e00c5d8de559f7b0da2cd6Satoshi Kataoka void setPrevWordPos(int pos) { mPrevWordPos = pos; } 673107b467c91c471ce4e00c5d8de559f7b0da2cd6Satoshi Kataoka // TODO: Use proper parameter when changed 683107b467c91c471ce4e00c5d8de559f7b0da2cd6Satoshi Kataoka int getDicRootPos() const { return 0; } 693107b467c91c471ce4e00c5d8de559f7b0da2cd6Satoshi Kataoka DicNodesCache *getDicTraverseCache() { return &mDicNodesCache; } 709559dd2e30de288a9ff7069bfc59f8500b949a88Tom Ouyang MultiBigramMap *getMultiBigramMap() { return &mMultiBigramMap; } 713107b467c91c471ce4e00c5d8de559f7b0da2cd6Satoshi Kataoka const ProximityInfoState *getProximityInfoState(int id) const { 723107b467c91c471ce4e00c5d8de559f7b0da2cd6Satoshi Kataoka return &mProximityInfoStates[id]; 733107b467c91c471ce4e00c5d8de559f7b0da2cd6Satoshi Kataoka } 743107b467c91c471ce4e00c5d8de559f7b0da2cd6Satoshi Kataoka int getInputSize() const { return mInputSize; } 753107b467c91c471ce4e00c5d8de559f7b0da2cd6Satoshi Kataoka void setPartiallyCommited() { mPartiallyCommited = true; } 763107b467c91c471ce4e00c5d8de559f7b0da2cd6Satoshi Kataoka bool isPartiallyCommited() const { return mPartiallyCommited; } 773107b467c91c471ce4e00c5d8de559f7b0da2cd6Satoshi Kataoka 783107b467c91c471ce4e00c5d8de559f7b0da2cd6Satoshi Kataoka bool isOnlyOnePointerUsed(int *pointerId) const { 793107b467c91c471ce4e00c5d8de559f7b0da2cd6Satoshi Kataoka // Not in the dictionary word 803107b467c91c471ce4e00c5d8de559f7b0da2cd6Satoshi Kataoka int usedPointerCount = 0; 813107b467c91c471ce4e00c5d8de559f7b0da2cd6Satoshi Kataoka int usedPointerId = 0; 823107b467c91c471ce4e00c5d8de559f7b0da2cd6Satoshi Kataoka for (int i = 0; i < mMaxPointerCount; ++i) { 833107b467c91c471ce4e00c5d8de559f7b0da2cd6Satoshi Kataoka if (mProximityInfoStates[i].isUsed()) { 843107b467c91c471ce4e00c5d8de559f7b0da2cd6Satoshi Kataoka ++usedPointerCount; 853107b467c91c471ce4e00c5d8de559f7b0da2cd6Satoshi Kataoka usedPointerId = i; 863107b467c91c471ce4e00c5d8de559f7b0da2cd6Satoshi Kataoka } 873107b467c91c471ce4e00c5d8de559f7b0da2cd6Satoshi Kataoka } 883107b467c91c471ce4e00c5d8de559f7b0da2cd6Satoshi Kataoka if (usedPointerCount != 1) { 893107b467c91c471ce4e00c5d8de559f7b0da2cd6Satoshi Kataoka return false; 903107b467c91c471ce4e00c5d8de559f7b0da2cd6Satoshi Kataoka } 913107b467c91c471ce4e00c5d8de559f7b0da2cd6Satoshi Kataoka *pointerId = usedPointerId; 923107b467c91c471ce4e00c5d8de559f7b0da2cd6Satoshi Kataoka return true; 933107b467c91c471ce4e00c5d8de559f7b0da2cd6Satoshi Kataoka } 943107b467c91c471ce4e00c5d8de559f7b0da2cd6Satoshi Kataoka 953107b467c91c471ce4e00c5d8de559f7b0da2cd6Satoshi Kataoka void getSearchKeys(const DicNode *node, std::vector<int> *const outputSearchKeyVector) const { 963107b467c91c471ce4e00c5d8de559f7b0da2cd6Satoshi Kataoka for (int i = 0; i < MAX_POINTER_COUNT_G; ++i) { 973107b467c91c471ce4e00c5d8de559f7b0da2cd6Satoshi Kataoka if (!mProximityInfoStates[i].isUsed()) { 983107b467c91c471ce4e00c5d8de559f7b0da2cd6Satoshi Kataoka continue; 993107b467c91c471ce4e00c5d8de559f7b0da2cd6Satoshi Kataoka } 1003107b467c91c471ce4e00c5d8de559f7b0da2cd6Satoshi Kataoka const int pointerId = node->getInputIndex(i); 1013107b467c91c471ce4e00c5d8de559f7b0da2cd6Satoshi Kataoka const std::vector<int> *const searchKeyVector = 1023107b467c91c471ce4e00c5d8de559f7b0da2cd6Satoshi Kataoka mProximityInfoStates[i].getSearchKeyVector(pointerId); 1033107b467c91c471ce4e00c5d8de559f7b0da2cd6Satoshi Kataoka outputSearchKeyVector->insert(outputSearchKeyVector->end(), searchKeyVector->begin(), 1043107b467c91c471ce4e00c5d8de559f7b0da2cd6Satoshi Kataoka searchKeyVector->end()); 1053107b467c91c471ce4e00c5d8de559f7b0da2cd6Satoshi Kataoka } 1063107b467c91c471ce4e00c5d8de559f7b0da2cd6Satoshi Kataoka } 1073107b467c91c471ce4e00c5d8de559f7b0da2cd6Satoshi Kataoka 1083107b467c91c471ce4e00c5d8de559f7b0da2cd6Satoshi Kataoka ProximityType getProximityTypeG(const DicNode *const node, const int childCodePoint) const { 1093107b467c91c471ce4e00c5d8de559f7b0da2cd6Satoshi Kataoka ProximityType proximityType = UNRELATED_CHAR; 1103107b467c91c471ce4e00c5d8de559f7b0da2cd6Satoshi Kataoka for (int i = 0; i < MAX_POINTER_COUNT_G; ++i) { 1113107b467c91c471ce4e00c5d8de559f7b0da2cd6Satoshi Kataoka if (!mProximityInfoStates[i].isUsed()) { 1123107b467c91c471ce4e00c5d8de559f7b0da2cd6Satoshi Kataoka continue; 1133107b467c91c471ce4e00c5d8de559f7b0da2cd6Satoshi Kataoka } 1143107b467c91c471ce4e00c5d8de559f7b0da2cd6Satoshi Kataoka const int pointerId = node->getInputIndex(i); 1153107b467c91c471ce4e00c5d8de559f7b0da2cd6Satoshi Kataoka proximityType = mProximityInfoStates[i].getProximityTypeG(pointerId, childCodePoint); 1163107b467c91c471ce4e00c5d8de559f7b0da2cd6Satoshi Kataoka ASSERT(proximityType == UNRELATED_CHAR || proximityType == MATCH_CHAR); 1173107b467c91c471ce4e00c5d8de559f7b0da2cd6Satoshi Kataoka // TODO: Make this more generic 1183107b467c91c471ce4e00c5d8de559f7b0da2cd6Satoshi Kataoka // Currently we assume there are only two types here -- UNRELATED_CHAR 1193107b467c91c471ce4e00c5d8de559f7b0da2cd6Satoshi Kataoka // and MATCH_CHAR 1203107b467c91c471ce4e00c5d8de559f7b0da2cd6Satoshi Kataoka if (proximityType != UNRELATED_CHAR) { 1213107b467c91c471ce4e00c5d8de559f7b0da2cd6Satoshi Kataoka return proximityType; 1223107b467c91c471ce4e00c5d8de559f7b0da2cd6Satoshi Kataoka } 1233107b467c91c471ce4e00c5d8de559f7b0da2cd6Satoshi Kataoka } 1243107b467c91c471ce4e00c5d8de559f7b0da2cd6Satoshi Kataoka return proximityType; 1253107b467c91c471ce4e00c5d8de559f7b0da2cd6Satoshi Kataoka } 1263107b467c91c471ce4e00c5d8de559f7b0da2cd6Satoshi Kataoka 1273107b467c91c471ce4e00c5d8de559f7b0da2cd6Satoshi Kataoka AK_FORCE_INLINE bool isCacheBorderForTyping(const int inputSize) const { 1283107b467c91c471ce4e00c5d8de559f7b0da2cd6Satoshi Kataoka return mDicNodesCache.isCacheBorderForTyping(inputSize); 1293107b467c91c471ce4e00c5d8de559f7b0da2cd6Satoshi Kataoka } 1303107b467c91c471ce4e00c5d8de559f7b0da2cd6Satoshi Kataoka 1313107b467c91c471ce4e00c5d8de559f7b0da2cd6Satoshi Kataoka /** 1323107b467c91c471ce4e00c5d8de559f7b0da2cd6Satoshi Kataoka * Returns whether or not it is possible to continue suggestion from the previous search. 1333107b467c91c471ce4e00c5d8de559f7b0da2cd6Satoshi Kataoka */ 1343107b467c91c471ce4e00c5d8de559f7b0da2cd6Satoshi Kataoka // TODO: Remove. No need to check once the session is fully implemented. 1353107b467c91c471ce4e00c5d8de559f7b0da2cd6Satoshi Kataoka bool isContinuousSuggestionPossible() const { 1363107b467c91c471ce4e00c5d8de559f7b0da2cd6Satoshi Kataoka if (!mDicNodesCache.hasCachedDicNodesForContinuousSuggestion()) { 1373107b467c91c471ce4e00c5d8de559f7b0da2cd6Satoshi Kataoka return false; 1383107b467c91c471ce4e00c5d8de559f7b0da2cd6Satoshi Kataoka } 139a94bb198cf13a3729bb992fc9c5bfce779e58469Satoshi Kataoka ASSERT(mMaxPointerCount <= MAX_POINTER_COUNT_G); 1403107b467c91c471ce4e00c5d8de559f7b0da2cd6Satoshi Kataoka for (int i = 0; i < mMaxPointerCount; ++i) { 1413107b467c91c471ce4e00c5d8de559f7b0da2cd6Satoshi Kataoka const ProximityInfoState *const pInfoState = getProximityInfoState(i); 1423107b467c91c471ce4e00c5d8de559f7b0da2cd6Satoshi Kataoka // If a proximity info state is not continuous suggestion possible, 1433107b467c91c471ce4e00c5d8de559f7b0da2cd6Satoshi Kataoka // do not continue searching. 1443107b467c91c471ce4e00c5d8de559f7b0da2cd6Satoshi Kataoka if (pInfoState->isUsed() && !pInfoState->isContinuousSuggestionPossible()) { 1453107b467c91c471ce4e00c5d8de559f7b0da2cd6Satoshi Kataoka return false; 1463107b467c91c471ce4e00c5d8de559f7b0da2cd6Satoshi Kataoka } 1473107b467c91c471ce4e00c5d8de559f7b0da2cd6Satoshi Kataoka } 1483107b467c91c471ce4e00c5d8de559f7b0da2cd6Satoshi Kataoka return true; 1493107b467c91c471ce4e00c5d8de559f7b0da2cd6Satoshi Kataoka } 1503107b467c91c471ce4e00c5d8de559f7b0da2cd6Satoshi Kataoka 151837f46dcb35a8f42a6bd5bc5fc6395d7386acb81Satoshi Kataoka bool isTouchPositionCorrectionEnabled() const { 152837f46dcb35a8f42a6bd5bc5fc6395d7386acb81Satoshi Kataoka return mProximityInfoStates[0].touchPositionCorrectionEnabled(); 153837f46dcb35a8f42a6bd5bc5fc6395d7386acb81Satoshi Kataoka } 154837f46dcb35a8f42a6bd5bc5fc6395d7386acb81Satoshi Kataoka 155252412d7eb4573f91588b06b0fe49ef9f0ac38acSatoshi Kataoka float getMultiWordCostMultiplier() const { 156252412d7eb4573f91588b06b0fe49ef9f0ac38acSatoshi Kataoka return mMultiWordCostMultiplier; 157252412d7eb4573f91588b06b0fe49ef9f0ac38acSatoshi Kataoka } 158252412d7eb4573f91588b06b0fe49ef9f0ac38acSatoshi Kataoka 1593107b467c91c471ce4e00c5d8de559f7b0da2cd6Satoshi Kataoka private: 1603107b467c91c471ce4e00c5d8de559f7b0da2cd6Satoshi Kataoka DISALLOW_IMPLICIT_CONSTRUCTORS(DicTraverseSession); 1613107b467c91c471ce4e00c5d8de559f7b0da2cd6Satoshi Kataoka // threshold to start caching 1623107b467c91c471ce4e00c5d8de559f7b0da2cd6Satoshi Kataoka static const int CACHE_START_INPUT_LENGTH_THRESHOLD; 1633107b467c91c471ce4e00c5d8de559f7b0da2cd6Satoshi Kataoka void initializeProximityInfoStates(const int *const inputCodePoints, const int *const inputXs, 1643107b467c91c471ce4e00c5d8de559f7b0da2cd6Satoshi Kataoka const int *const inputYs, const int *const times, const int *const pointerIds, 1653107b467c91c471ce4e00c5d8de559f7b0da2cd6Satoshi Kataoka const int inputSize, const float maxSpatialDistance, const int maxPointerCount); 1663107b467c91c471ce4e00c5d8de559f7b0da2cd6Satoshi Kataoka 1673107b467c91c471ce4e00c5d8de559f7b0da2cd6Satoshi Kataoka int mPrevWordPos; 1683107b467c91c471ce4e00c5d8de559f7b0da2cd6Satoshi Kataoka const ProximityInfo *mProximityInfo; 1693107b467c91c471ce4e00c5d8de559f7b0da2cd6Satoshi Kataoka const Dictionary *mDictionary; 1703107b467c91c471ce4e00c5d8de559f7b0da2cd6Satoshi Kataoka 1713107b467c91c471ce4e00c5d8de559f7b0da2cd6Satoshi Kataoka DicNodesCache mDicNodesCache; 1723107b467c91c471ce4e00c5d8de559f7b0da2cd6Satoshi Kataoka // Temporary cache for bigram frequencies 1739559dd2e30de288a9ff7069bfc59f8500b949a88Tom Ouyang MultiBigramMap mMultiBigramMap; 1743107b467c91c471ce4e00c5d8de559f7b0da2cd6Satoshi Kataoka ProximityInfoState mProximityInfoStates[MAX_POINTER_COUNT_G]; 1753107b467c91c471ce4e00c5d8de559f7b0da2cd6Satoshi Kataoka 1763107b467c91c471ce4e00c5d8de559f7b0da2cd6Satoshi Kataoka int mInputSize; 1773107b467c91c471ce4e00c5d8de559f7b0da2cd6Satoshi Kataoka bool mPartiallyCommited; 1783107b467c91c471ce4e00c5d8de559f7b0da2cd6Satoshi Kataoka int mMaxPointerCount; 179252412d7eb4573f91588b06b0fe49ef9f0ac38acSatoshi Kataoka 180252412d7eb4573f91588b06b0fe49ef9f0ac38acSatoshi Kataoka ///////////////////////////////// 181252412d7eb4573f91588b06b0fe49ef9f0ac38acSatoshi Kataoka // Configuration per dictionary 182252412d7eb4573f91588b06b0fe49ef9f0ac38acSatoshi Kataoka float mMultiWordCostMultiplier; 183252412d7eb4573f91588b06b0fe49ef9f0ac38acSatoshi Kataoka 1843107b467c91c471ce4e00c5d8de559f7b0da2cd6Satoshi Kataoka}; 1853107b467c91c471ce4e00c5d8de559f7b0da2cd6Satoshi Kataoka} // namespace latinime 1863107b467c91c471ce4e00c5d8de559f7b0da2cd6Satoshi Kataoka#endif // LATINIME_DIC_TRAVERSE_SESSION_H 187