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