1 /* 2 * Copyright (C) 2012 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 #ifndef LATINIME_DIC_TRAVERSE_SESSION_H 18 #define LATINIME_DIC_TRAVERSE_SESSION_H 19 20 #include <stdint.h> 21 #include <vector> 22 23 #include "defines.h" 24 #include "jni.h" 25 #include "multi_bigram_map.h" 26 #include "proximity_info_state.h" 27 #include "suggest/core/dicnode/dic_nodes_cache.h" 28 29 namespace latinime { 30 31 class Dictionary; 32 class ProximityInfo; 33 34 class DicTraverseSession { 35 public: 36 AK_FORCE_INLINE DicTraverseSession(JNIEnv *env, jstring localeStr) 37 : mPrevWordPos(NOT_VALID_WORD), mProximityInfo(0), 38 mDictionary(0), mDicNodesCache(), mMultiBigramMap(), 39 mInputSize(0), mPartiallyCommited(false), mMaxPointerCount(1), 40 mMultiWordCostMultiplier(1.0f) { 41 // NOTE: mProximityInfoStates is an array of instances. 42 // No need to initialize it explicitly here. 43 } 44 45 // Non virtual inline destructor -- never inherit this class 46 AK_FORCE_INLINE ~DicTraverseSession() {} 47 48 void init(const Dictionary *dictionary, const int *prevWord, int prevWordLength); 49 // TODO: Remove and merge into init 50 void setupForGetSuggestions(const ProximityInfo *pInfo, const int *inputCodePoints, 51 const int inputSize, const int *const inputXs, const int *const inputYs, 52 const int *const times, const int *const pointerIds, const float maxSpatialDistance, 53 const int maxPointerCount); 54 void resetCache(const int nextActiveCacheSize, const int maxWords); 55 56 // TODO: Remove 57 const uint8_t *getOffsetDict() const; 58 int getDictFlags() const; 59 60 //-------------------- 61 // getters and setters 62 //-------------------- 63 const ProximityInfo *getProximityInfo() const { return mProximityInfo; } 64 int getPrevWordPos() const { return mPrevWordPos; } 65 // TODO: REMOVE 66 void setPrevWordPos(int pos) { mPrevWordPos = pos; } 67 // TODO: Use proper parameter when changed 68 int getDicRootPos() const { return 0; } 69 DicNodesCache *getDicTraverseCache() { return &mDicNodesCache; } 70 MultiBigramMap *getMultiBigramMap() { return &mMultiBigramMap; } 71 const ProximityInfoState *getProximityInfoState(int id) const { 72 return &mProximityInfoStates[id]; 73 } 74 int getInputSize() const { return mInputSize; } 75 void setPartiallyCommited() { mPartiallyCommited = true; } 76 bool isPartiallyCommited() const { return mPartiallyCommited; } 77 78 bool isOnlyOnePointerUsed(int *pointerId) const { 79 // Not in the dictionary word 80 int usedPointerCount = 0; 81 int usedPointerId = 0; 82 for (int i = 0; i < mMaxPointerCount; ++i) { 83 if (mProximityInfoStates[i].isUsed()) { 84 ++usedPointerCount; 85 usedPointerId = i; 86 } 87 } 88 if (usedPointerCount != 1) { 89 return false; 90 } 91 *pointerId = usedPointerId; 92 return true; 93 } 94 95 void getSearchKeys(const DicNode *node, std::vector<int> *const outputSearchKeyVector) const { 96 for (int i = 0; i < MAX_POINTER_COUNT_G; ++i) { 97 if (!mProximityInfoStates[i].isUsed()) { 98 continue; 99 } 100 const int pointerId = node->getInputIndex(i); 101 const std::vector<int> *const searchKeyVector = 102 mProximityInfoStates[i].getSearchKeyVector(pointerId); 103 outputSearchKeyVector->insert(outputSearchKeyVector->end(), searchKeyVector->begin(), 104 searchKeyVector->end()); 105 } 106 } 107 108 ProximityType getProximityTypeG(const DicNode *const node, const int childCodePoint) const { 109 ProximityType proximityType = UNRELATED_CHAR; 110 for (int i = 0; i < MAX_POINTER_COUNT_G; ++i) { 111 if (!mProximityInfoStates[i].isUsed()) { 112 continue; 113 } 114 const int pointerId = node->getInputIndex(i); 115 proximityType = mProximityInfoStates[i].getProximityTypeG(pointerId, childCodePoint); 116 ASSERT(proximityType == UNRELATED_CHAR || proximityType == MATCH_CHAR); 117 // TODO: Make this more generic 118 // Currently we assume there are only two types here -- UNRELATED_CHAR 119 // and MATCH_CHAR 120 if (proximityType != UNRELATED_CHAR) { 121 return proximityType; 122 } 123 } 124 return proximityType; 125 } 126 127 AK_FORCE_INLINE bool isCacheBorderForTyping(const int inputSize) const { 128 return mDicNodesCache.isCacheBorderForTyping(inputSize); 129 } 130 131 /** 132 * Returns whether or not it is possible to continue suggestion from the previous search. 133 */ 134 // TODO: Remove. No need to check once the session is fully implemented. 135 bool isContinuousSuggestionPossible() const { 136 if (!mDicNodesCache.hasCachedDicNodesForContinuousSuggestion()) { 137 return false; 138 } 139 ASSERT(mMaxPointerCount <= MAX_POINTER_COUNT_G); 140 for (int i = 0; i < mMaxPointerCount; ++i) { 141 const ProximityInfoState *const pInfoState = getProximityInfoState(i); 142 // If a proximity info state is not continuous suggestion possible, 143 // do not continue searching. 144 if (pInfoState->isUsed() && !pInfoState->isContinuousSuggestionPossible()) { 145 return false; 146 } 147 } 148 return true; 149 } 150 151 bool isTouchPositionCorrectionEnabled() const { 152 return mProximityInfoStates[0].touchPositionCorrectionEnabled(); 153 } 154 155 float getMultiWordCostMultiplier() const { 156 return mMultiWordCostMultiplier; 157 } 158 159 private: 160 DISALLOW_IMPLICIT_CONSTRUCTORS(DicTraverseSession); 161 // threshold to start caching 162 static const int CACHE_START_INPUT_LENGTH_THRESHOLD; 163 void initializeProximityInfoStates(const int *const inputCodePoints, const int *const inputXs, 164 const int *const inputYs, const int *const times, const int *const pointerIds, 165 const int inputSize, const float maxSpatialDistance, const int maxPointerCount); 166 167 int mPrevWordPos; 168 const ProximityInfo *mProximityInfo; 169 const Dictionary *mDictionary; 170 171 DicNodesCache mDicNodesCache; 172 // Temporary cache for bigram frequencies 173 MultiBigramMap mMultiBigramMap; 174 ProximityInfoState mProximityInfoStates[MAX_POINTER_COUNT_G]; 175 176 int mInputSize; 177 bool mPartiallyCommited; 178 int mMaxPointerCount; 179 180 ///////////////////////////////// 181 // Configuration per dictionary 182 float mMultiWordCostMultiplier; 183 184 }; 185 } // namespace latinime 186 #endif // LATINIME_DIC_TRAVERSE_SESSION_H 187