dic_traverse_session.h revision d6fdd58cc0dcdd1e1b1018de10a30e423494a8fd
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 <vector> 21 22#include "defines.h" 23#include "jni.h" 24#include "suggest/core/dicnode/dic_nodes_cache.h" 25#include "suggest/core/dictionary/multi_bigram_map.h" 26#include "suggest/core/layout/proximity_info_state.h" 27 28namespace latinime { 29 30class Dictionary; 31class DictionaryStructureWithBufferPolicy; 32class ProximityInfo; 33class SuggestOptions; 34 35class DicTraverseSession { 36 public: 37 38 // A factory method for DicTraverseSession 39 static AK_FORCE_INLINE void *getSessionInstance(JNIEnv *env, jstring localeStr, 40 jlong dictSize) { 41 // To deal with the trade-off between accuracy and memory space, large cache is used for 42 // dictionaries larger that the threshold 43 return new DicTraverseSession(env, localeStr, 44 dictSize >= DICTIONARY_SIZE_THRESHOLD_TO_USE_LARGE_CACHE_FOR_SUGGESTION); 45 } 46 47 static AK_FORCE_INLINE void releaseSessionInstance(DicTraverseSession *traverseSession) { 48 delete traverseSession; 49 } 50 51 AK_FORCE_INLINE DicTraverseSession(JNIEnv *env, jstring localeStr, bool usesLargeCache) 52 : mPrevWordPtNodePos(NOT_A_DICT_POS), mProximityInfo(nullptr), 53 mDictionary(nullptr), mSuggestOptions(nullptr), mDicNodesCache(usesLargeCache), 54 mMultiBigramMap(), mInputSize(0), mMaxPointerCount(1), 55 mMultiWordCostMultiplier(1.0f) { 56 // NOTE: mProximityInfoStates is an array of instances. 57 // No need to initialize it explicitly here. 58 } 59 60 // Non virtual inline destructor -- never inherit this class 61 AK_FORCE_INLINE ~DicTraverseSession() {} 62 63 void init(const Dictionary *dictionary, const int *prevWord, int prevWordLength, 64 const SuggestOptions *const suggestOptions); 65 // TODO: Remove and merge into init 66 void setupForGetSuggestions(const ProximityInfo *pInfo, const int *inputCodePoints, 67 const int inputSize, const int *const inputXs, const int *const inputYs, 68 const int *const times, const int *const pointerIds, const float maxSpatialDistance, 69 const int maxPointerCount); 70 void resetCache(const int thresholdForNextActiveDicNodes, const int maxWords); 71 72 const DictionaryStructureWithBufferPolicy *getDictionaryStructurePolicy() const; 73 74 //-------------------- 75 // getters and setters 76 //-------------------- 77 const ProximityInfo *getProximityInfo() const { return mProximityInfo; } 78 const SuggestOptions *getSuggestOptions() const { return mSuggestOptions; } 79 int getPrevWordPtNodePos() const { return mPrevWordPtNodePos; } 80 DicNodesCache *getDicTraverseCache() { return &mDicNodesCache; } 81 MultiBigramMap *getMultiBigramMap() { return &mMultiBigramMap; } 82 const ProximityInfoState *getProximityInfoState(int id) const { 83 return &mProximityInfoStates[id]; 84 } 85 int getInputSize() const { return mInputSize; } 86 87 bool isOnlyOnePointerUsed(int *pointerId) const { 88 // Not in the dictionary word 89 int usedPointerCount = 0; 90 int usedPointerId = 0; 91 for (int i = 0; i < mMaxPointerCount; ++i) { 92 if (mProximityInfoStates[i].isUsed()) { 93 ++usedPointerCount; 94 usedPointerId = i; 95 } 96 } 97 if (usedPointerCount != 1) { 98 return false; 99 } 100 if (pointerId) { 101 *pointerId = usedPointerId; 102 } 103 return true; 104 } 105 106 ProximityType getProximityTypeG(const DicNode *const dicNode, const int childCodePoint) const { 107 ProximityType proximityType = UNRELATED_CHAR; 108 for (int i = 0; i < MAX_POINTER_COUNT_G; ++i) { 109 if (!mProximityInfoStates[i].isUsed()) { 110 continue; 111 } 112 const int pointerId = dicNode->getInputIndex(i); 113 proximityType = mProximityInfoStates[i].getProximityTypeG(pointerId, childCodePoint); 114 ASSERT(proximityType == UNRELATED_CHAR || proximityType == MATCH_CHAR); 115 // TODO: Make this more generic 116 // Currently we assume there are only two types here -- UNRELATED_CHAR 117 // and MATCH_CHAR 118 if (proximityType != UNRELATED_CHAR) { 119 return proximityType; 120 } 121 } 122 return proximityType; 123 } 124 125 AK_FORCE_INLINE bool isCacheBorderForTyping(const int inputSize) const { 126 return mDicNodesCache.isCacheBorderForTyping(inputSize); 127 } 128 129 /** 130 * Returns whether or not it is possible to continue suggestion from the previous search. 131 */ 132 // TODO: Remove. No need to check once the session is fully implemented. 133 bool isContinuousSuggestionPossible() const { 134 if (!mDicNodesCache.hasCachedDicNodesForContinuousSuggestion()) { 135 return false; 136 } 137 ASSERT(mMaxPointerCount <= MAX_POINTER_COUNT_G); 138 for (int i = 0; i < mMaxPointerCount; ++i) { 139 const ProximityInfoState *const pInfoState = getProximityInfoState(i); 140 // If a proximity info state is not continuous suggestion possible, 141 // do not continue searching. 142 if (pInfoState->isUsed() && !pInfoState->isContinuousSuggestionPossible()) { 143 return false; 144 } 145 } 146 return true; 147 } 148 149 bool isTouchPositionCorrectionEnabled() const { 150 return mProximityInfoStates[0].touchPositionCorrectionEnabled(); 151 } 152 153 float getMultiWordCostMultiplier() const { 154 return mMultiWordCostMultiplier; 155 } 156 157 private: 158 DISALLOW_IMPLICIT_CONSTRUCTORS(DicTraverseSession); 159 // threshold to start caching 160 static const int CACHE_START_INPUT_LENGTH_THRESHOLD; 161 static const int DICTIONARY_SIZE_THRESHOLD_TO_USE_LARGE_CACHE_FOR_SUGGESTION; 162 void initializeProximityInfoStates(const int *const inputCodePoints, const int *const inputXs, 163 const int *const inputYs, const int *const times, const int *const pointerIds, 164 const int inputSize, const float maxSpatialDistance, const int maxPointerCount); 165 166 int mPrevWordPtNodePos; 167 const ProximityInfo *mProximityInfo; 168 const Dictionary *mDictionary; 169 const SuggestOptions *mSuggestOptions; 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 int mMaxPointerCount; 178 179 ///////////////////////////////// 180 // Configuration per dictionary 181 float mMultiWordCostMultiplier; 182 183}; 184} // namespace latinime 185#endif // LATINIME_DIC_TRAVERSE_SESSION_H 186