dic_traverse_session.h revision 8a7129530b4dbb2453e88747f251d30a2ce75a45
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 "suggest/core/dicnode/dic_nodes_cache.h" 26#include "suggest/core/dictionary/multi_bigram_map.h" 27#include "suggest/core/layout/proximity_info_state.h" 28 29namespace latinime { 30 31class BinaryDictionaryInfo; 32class Dictionary; 33class ProximityInfo; 34class SuggestOptions; 35 36class DicTraverseSession { 37 public: 38 39 // A factory method for DicTraverseSession 40 static AK_FORCE_INLINE void *getSessionInstance(JNIEnv *env, jstring localeStr) { 41 return new DicTraverseSession(env, localeStr); 42 } 43 44 static AK_FORCE_INLINE void initSessionInstance(DicTraverseSession *traverseSession, 45 const Dictionary *const dictionary, const int *prevWord, const int prevWordLength, 46 const SuggestOptions *const suggestOptions) { 47 if (traverseSession) { 48 DicTraverseSession *tSession = static_cast<DicTraverseSession *>(traverseSession); 49 tSession->init(dictionary, prevWord, prevWordLength, suggestOptions); 50 } 51 } 52 53 static AK_FORCE_INLINE void releaseSessionInstance(DicTraverseSession *traverseSession) { 54 delete traverseSession; 55 } 56 57 AK_FORCE_INLINE DicTraverseSession(JNIEnv *env, jstring localeStr) 58 : mPrevWordPos(NOT_A_VALID_WORD_POS), mProximityInfo(0), 59 mDictionary(0), mSuggestOptions(0), mDicNodesCache(), mMultiBigramMap(), 60 mInputSize(0), mPartiallyCommited(false), mMaxPointerCount(1), 61 mMultiWordCostMultiplier(1.0f) { 62 // NOTE: mProximityInfoStates is an array of instances. 63 // No need to initialize it explicitly here. 64 } 65 66 // Non virtual inline destructor -- never inherit this class 67 AK_FORCE_INLINE ~DicTraverseSession() {} 68 69 void init(const Dictionary *dictionary, const int *prevWord, int prevWordLength, 70 const SuggestOptions *const suggestOptions); 71 // TODO: Remove and merge into init 72 void setupForGetSuggestions(const ProximityInfo *pInfo, const int *inputCodePoints, 73 const int inputSize, const int *const inputXs, const int *const inputYs, 74 const int *const times, const int *const pointerIds, const float maxSpatialDistance, 75 const int maxPointerCount); 76 void resetCache(const int nextActiveCacheSize, const int maxWords); 77 78 // TODO: Remove 79 const BinaryDictionaryInfo *getBinaryDictionaryInfo() const; 80 81 //-------------------- 82 // getters and setters 83 //-------------------- 84 const ProximityInfo *getProximityInfo() const { return mProximityInfo; } 85 const SuggestOptions *getSuggestOptions() const { return mSuggestOptions; } 86 int getPrevWordPos() const { return mPrevWordPos; } 87 // TODO: REMOVE 88 void setPrevWordPos(int pos) { mPrevWordPos = pos; } 89 // TODO: Use proper parameter when changed 90 int getDicRootPos() const { return 0; } 91 DicNodesCache *getDicTraverseCache() { return &mDicNodesCache; } 92 MultiBigramMap *getMultiBigramMap() { return &mMultiBigramMap; } 93 const ProximityInfoState *getProximityInfoState(int id) const { 94 return &mProximityInfoStates[id]; 95 } 96 int getInputSize() const { return mInputSize; } 97 void setPartiallyCommited() { mPartiallyCommited = true; } 98 bool isPartiallyCommited() const { return mPartiallyCommited; } 99 100 bool isOnlyOnePointerUsed(int *pointerId) const { 101 // Not in the dictionary word 102 int usedPointerCount = 0; 103 int usedPointerId = 0; 104 for (int i = 0; i < mMaxPointerCount; ++i) { 105 if (mProximityInfoStates[i].isUsed()) { 106 ++usedPointerCount; 107 usedPointerId = i; 108 } 109 } 110 if (usedPointerCount != 1) { 111 return false; 112 } 113 *pointerId = usedPointerId; 114 return true; 115 } 116 117 void getSearchKeys(const DicNode *node, std::vector<int> *const outputSearchKeyVector) const { 118 for (int i = 0; i < MAX_POINTER_COUNT_G; ++i) { 119 if (!mProximityInfoStates[i].isUsed()) { 120 continue; 121 } 122 const int pointerId = node->getInputIndex(i); 123 const std::vector<int> *const searchKeyVector = 124 mProximityInfoStates[i].getSearchKeyVector(pointerId); 125 outputSearchKeyVector->insert(outputSearchKeyVector->end(), searchKeyVector->begin(), 126 searchKeyVector->end()); 127 } 128 } 129 130 ProximityType getProximityTypeG(const DicNode *const node, const int childCodePoint) const { 131 ProximityType proximityType = UNRELATED_CHAR; 132 for (int i = 0; i < MAX_POINTER_COUNT_G; ++i) { 133 if (!mProximityInfoStates[i].isUsed()) { 134 continue; 135 } 136 const int pointerId = node->getInputIndex(i); 137 proximityType = mProximityInfoStates[i].getProximityTypeG(pointerId, childCodePoint); 138 ASSERT(proximityType == UNRELATED_CHAR || proximityType == MATCH_CHAR); 139 // TODO: Make this more generic 140 // Currently we assume there are only two types here -- UNRELATED_CHAR 141 // and MATCH_CHAR 142 if (proximityType != UNRELATED_CHAR) { 143 return proximityType; 144 } 145 } 146 return proximityType; 147 } 148 149 AK_FORCE_INLINE bool isCacheBorderForTyping(const int inputSize) const { 150 return mDicNodesCache.isCacheBorderForTyping(inputSize); 151 } 152 153 /** 154 * Returns whether or not it is possible to continue suggestion from the previous search. 155 */ 156 // TODO: Remove. No need to check once the session is fully implemented. 157 bool isContinuousSuggestionPossible() const { 158 if (!mDicNodesCache.hasCachedDicNodesForContinuousSuggestion()) { 159 return false; 160 } 161 ASSERT(mMaxPointerCount <= MAX_POINTER_COUNT_G); 162 for (int i = 0; i < mMaxPointerCount; ++i) { 163 const ProximityInfoState *const pInfoState = getProximityInfoState(i); 164 // If a proximity info state is not continuous suggestion possible, 165 // do not continue searching. 166 if (pInfoState->isUsed() && !pInfoState->isContinuousSuggestionPossible()) { 167 return false; 168 } 169 } 170 return true; 171 } 172 173 bool isTouchPositionCorrectionEnabled() const { 174 return mProximityInfoStates[0].touchPositionCorrectionEnabled(); 175 } 176 177 float getMultiWordCostMultiplier() const { 178 return mMultiWordCostMultiplier; 179 } 180 181 private: 182 DISALLOW_IMPLICIT_CONSTRUCTORS(DicTraverseSession); 183 // threshold to start caching 184 static const int CACHE_START_INPUT_LENGTH_THRESHOLD; 185 void initializeProximityInfoStates(const int *const inputCodePoints, const int *const inputXs, 186 const int *const inputYs, const int *const times, const int *const pointerIds, 187 const int inputSize, const float maxSpatialDistance, const int maxPointerCount); 188 189 int mPrevWordPos; 190 const ProximityInfo *mProximityInfo; 191 const Dictionary *mDictionary; 192 const SuggestOptions *mSuggestOptions; 193 194 DicNodesCache mDicNodesCache; 195 // Temporary cache for bigram frequencies 196 MultiBigramMap mMultiBigramMap; 197 ProximityInfoState mProximityInfoStates[MAX_POINTER_COUNT_G]; 198 199 int mInputSize; 200 bool mPartiallyCommited; 201 int mMaxPointerCount; 202 203 ///////////////////////////////// 204 // Configuration per dictionary 205 float mMultiWordCostMultiplier; 206 207}; 208} // namespace latinime 209#endif // LATINIME_DIC_TRAVERSE_SESSION_H 210