Home | History | Annotate | Download | only in session
      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