dic_traverse_session.cpp revision 9559dd2e30de288a9ff7069bfc59f8500b949a88
13107b467c91c471ce4e00c5d8de559f7b0da2cd6Satoshi Kataoka/*
23107b467c91c471ce4e00c5d8de559f7b0da2cd6Satoshi Kataoka * Copyright (C) 2012 The Android Open Source Project
33107b467c91c471ce4e00c5d8de559f7b0da2cd6Satoshi Kataoka *
43107b467c91c471ce4e00c5d8de559f7b0da2cd6Satoshi Kataoka * Licensed under the Apache License, Version 2.0 (the "License");
53107b467c91c471ce4e00c5d8de559f7b0da2cd6Satoshi Kataoka * you may not use this file except in compliance with the License.
63107b467c91c471ce4e00c5d8de559f7b0da2cd6Satoshi Kataoka * You may obtain a copy of the License at
73107b467c91c471ce4e00c5d8de559f7b0da2cd6Satoshi Kataoka *
83107b467c91c471ce4e00c5d8de559f7b0da2cd6Satoshi Kataoka *      http://www.apache.org/licenses/LICENSE-2.0
93107b467c91c471ce4e00c5d8de559f7b0da2cd6Satoshi Kataoka *
103107b467c91c471ce4e00c5d8de559f7b0da2cd6Satoshi Kataoka * Unless required by applicable law or agreed to in writing, software
113107b467c91c471ce4e00c5d8de559f7b0da2cd6Satoshi Kataoka * distributed under the License is distributed on an "AS IS" BASIS,
123107b467c91c471ce4e00c5d8de559f7b0da2cd6Satoshi Kataoka * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
133107b467c91c471ce4e00c5d8de559f7b0da2cd6Satoshi Kataoka * See the License for the specific language governing permissions and
143107b467c91c471ce4e00c5d8de559f7b0da2cd6Satoshi Kataoka * limitations under the License.
153107b467c91c471ce4e00c5d8de559f7b0da2cd6Satoshi Kataoka */
163107b467c91c471ce4e00c5d8de559f7b0da2cd6Satoshi Kataoka
17b68e73448104714e8f12f89a1e00fb10b5fd14c4Ken Wakasa#include "suggest/core/session/dic_traverse_session.h"
18b68e73448104714e8f12f89a1e00fb10b5fd14c4Ken Wakasa
19252412d7eb4573f91588b06b0fe49ef9f0ac38acSatoshi Kataoka#include "binary_format.h"
203107b467c91c471ce4e00c5d8de559f7b0da2cd6Satoshi Kataoka#include "defines.h"
213107b467c91c471ce4e00c5d8de559f7b0da2cd6Satoshi Kataoka#include "dictionary.h"
223107b467c91c471ce4e00c5d8de559f7b0da2cd6Satoshi Kataoka#include "dic_traverse_wrapper.h"
233107b467c91c471ce4e00c5d8de559f7b0da2cd6Satoshi Kataoka#include "jni.h"
24b68e73448104714e8f12f89a1e00fb10b5fd14c4Ken Wakasa#include "suggest/core/dicnode/dic_node_utils.h"
253107b467c91c471ce4e00c5d8de559f7b0da2cd6Satoshi Kataoka
263107b467c91c471ce4e00c5d8de559f7b0da2cd6Satoshi Kataokanamespace latinime {
273107b467c91c471ce4e00c5d8de559f7b0da2cd6Satoshi Kataoka
283107b467c91c471ce4e00c5d8de559f7b0da2cd6Satoshi Kataokaconst int DicTraverseSession::CACHE_START_INPUT_LENGTH_THRESHOLD = 20;
293107b467c91c471ce4e00c5d8de559f7b0da2cd6Satoshi Kataoka
303107b467c91c471ce4e00c5d8de559f7b0da2cd6Satoshi Kataoka// A factory method for DicTraverseSession
313107b467c91c471ce4e00c5d8de559f7b0da2cd6Satoshi Kataokastatic void *getSessionInstance(JNIEnv *env, jstring localeStr) {
323107b467c91c471ce4e00c5d8de559f7b0da2cd6Satoshi Kataoka    return new DicTraverseSession(env, localeStr);
333107b467c91c471ce4e00c5d8de559f7b0da2cd6Satoshi Kataoka}
343107b467c91c471ce4e00c5d8de559f7b0da2cd6Satoshi Kataoka
353107b467c91c471ce4e00c5d8de559f7b0da2cd6Satoshi Kataoka// TODO: Pass "DicTraverseSession *traverseSession" when the source code structure settles down.
363107b467c91c471ce4e00c5d8de559f7b0da2cd6Satoshi Kataokastatic void initSessionInstance(void *traverseSession, const Dictionary *const dictionary,
373107b467c91c471ce4e00c5d8de559f7b0da2cd6Satoshi Kataoka        const int *prevWord, const int prevWordLength) {
383107b467c91c471ce4e00c5d8de559f7b0da2cd6Satoshi Kataoka    if (traverseSession) {
393107b467c91c471ce4e00c5d8de559f7b0da2cd6Satoshi Kataoka        DicTraverseSession *tSession = static_cast<DicTraverseSession *>(traverseSession);
403107b467c91c471ce4e00c5d8de559f7b0da2cd6Satoshi Kataoka        tSession->init(dictionary, prevWord, prevWordLength);
413107b467c91c471ce4e00c5d8de559f7b0da2cd6Satoshi Kataoka    }
423107b467c91c471ce4e00c5d8de559f7b0da2cd6Satoshi Kataoka}
433107b467c91c471ce4e00c5d8de559f7b0da2cd6Satoshi Kataoka
443107b467c91c471ce4e00c5d8de559f7b0da2cd6Satoshi Kataoka// TODO: Pass "DicTraverseSession *traverseSession" when the source code structure settles down.
453107b467c91c471ce4e00c5d8de559f7b0da2cd6Satoshi Kataokastatic void releaseSessionInstance(void *traverseSession) {
463107b467c91c471ce4e00c5d8de559f7b0da2cd6Satoshi Kataoka    delete static_cast<DicTraverseSession *>(traverseSession);
473107b467c91c471ce4e00c5d8de559f7b0da2cd6Satoshi Kataoka}
483107b467c91c471ce4e00c5d8de559f7b0da2cd6Satoshi Kataoka
493107b467c91c471ce4e00c5d8de559f7b0da2cd6Satoshi Kataoka// An ad-hoc internal class to register the factory method defined above
503107b467c91c471ce4e00c5d8de559f7b0da2cd6Satoshi Kataokaclass TraverseSessionFactoryRegisterer {
513107b467c91c471ce4e00c5d8de559f7b0da2cd6Satoshi Kataoka public:
523107b467c91c471ce4e00c5d8de559f7b0da2cd6Satoshi Kataoka    TraverseSessionFactoryRegisterer() {
533107b467c91c471ce4e00c5d8de559f7b0da2cd6Satoshi Kataoka        DicTraverseWrapper::setTraverseSessionFactoryMethod(getSessionInstance);
543107b467c91c471ce4e00c5d8de559f7b0da2cd6Satoshi Kataoka        DicTraverseWrapper::setTraverseSessionInitMethod(initSessionInstance);
553107b467c91c471ce4e00c5d8de559f7b0da2cd6Satoshi Kataoka        DicTraverseWrapper::setTraverseSessionReleaseMethod(releaseSessionInstance);
563107b467c91c471ce4e00c5d8de559f7b0da2cd6Satoshi Kataoka    }
573107b467c91c471ce4e00c5d8de559f7b0da2cd6Satoshi Kataoka private:
583107b467c91c471ce4e00c5d8de559f7b0da2cd6Satoshi Kataoka    DISALLOW_COPY_AND_ASSIGN(TraverseSessionFactoryRegisterer);
593107b467c91c471ce4e00c5d8de559f7b0da2cd6Satoshi Kataoka};
603107b467c91c471ce4e00c5d8de559f7b0da2cd6Satoshi Kataoka
613107b467c91c471ce4e00c5d8de559f7b0da2cd6Satoshi Kataoka// To invoke the TraverseSessionFactoryRegisterer constructor in the global constructor.
623107b467c91c471ce4e00c5d8de559f7b0da2cd6Satoshi Kataokastatic TraverseSessionFactoryRegisterer traverseSessionFactoryRegisterer;
633107b467c91c471ce4e00c5d8de559f7b0da2cd6Satoshi Kataoka
643107b467c91c471ce4e00c5d8de559f7b0da2cd6Satoshi Kataokavoid DicTraverseSession::init(const Dictionary *const dictionary, const int *prevWord,
653107b467c91c471ce4e00c5d8de559f7b0da2cd6Satoshi Kataoka        int prevWordLength) {
663107b467c91c471ce4e00c5d8de559f7b0da2cd6Satoshi Kataoka    mDictionary = dictionary;
67252412d7eb4573f91588b06b0fe49ef9f0ac38acSatoshi Kataoka    mMultiWordCostMultiplier = BinaryFormat::getMultiWordCostMultiplier(mDictionary->getDict());
683107b467c91c471ce4e00c5d8de559f7b0da2cd6Satoshi Kataoka    if (!prevWord) {
693107b467c91c471ce4e00c5d8de559f7b0da2cd6Satoshi Kataoka        mPrevWordPos = NOT_VALID_WORD;
703107b467c91c471ce4e00c5d8de559f7b0da2cd6Satoshi Kataoka        return;
713107b467c91c471ce4e00c5d8de559f7b0da2cd6Satoshi Kataoka    }
725fa33a701d4b8405254d3369c714702481a90e6bTom Ouyang    // TODO: merge following similar calls to getTerminalPosition into one case-insensitive call.
735fa33a701d4b8405254d3369c714702481a90e6bTom Ouyang    mPrevWordPos = BinaryFormat::getTerminalPosition(dictionary->getOffsetDict(), prevWord,
745fa33a701d4b8405254d3369c714702481a90e6bTom Ouyang            prevWordLength, false /* forceLowerCaseSearch */);
755fa33a701d4b8405254d3369c714702481a90e6bTom Ouyang    if (mPrevWordPos == NOT_VALID_WORD) {
765fa33a701d4b8405254d3369c714702481a90e6bTom Ouyang        // Check bigrams for lower-cased previous word if original was not found. Useful for
775fa33a701d4b8405254d3369c714702481a90e6bTom Ouyang        // auto-capitalized words like "The [current_word]".
785fa33a701d4b8405254d3369c714702481a90e6bTom Ouyang        mPrevWordPos = BinaryFormat::getTerminalPosition(dictionary->getOffsetDict(), prevWord,
795fa33a701d4b8405254d3369c714702481a90e6bTom Ouyang                prevWordLength, true /* forceLowerCaseSearch */);
805fa33a701d4b8405254d3369c714702481a90e6bTom Ouyang    }
813107b467c91c471ce4e00c5d8de559f7b0da2cd6Satoshi Kataoka}
823107b467c91c471ce4e00c5d8de559f7b0da2cd6Satoshi Kataoka
833107b467c91c471ce4e00c5d8de559f7b0da2cd6Satoshi Kataokavoid DicTraverseSession::setupForGetSuggestions(const ProximityInfo *pInfo,
843107b467c91c471ce4e00c5d8de559f7b0da2cd6Satoshi Kataoka        const int *inputCodePoints, const int inputSize, const int *const inputXs,
853107b467c91c471ce4e00c5d8de559f7b0da2cd6Satoshi Kataoka        const int *const inputYs, const int *const times, const int *const pointerIds,
863107b467c91c471ce4e00c5d8de559f7b0da2cd6Satoshi Kataoka        const float maxSpatialDistance, const int maxPointerCount) {
873107b467c91c471ce4e00c5d8de559f7b0da2cd6Satoshi Kataoka    mProximityInfo = pInfo;
883107b467c91c471ce4e00c5d8de559f7b0da2cd6Satoshi Kataoka    mMaxPointerCount = maxPointerCount;
893107b467c91c471ce4e00c5d8de559f7b0da2cd6Satoshi Kataoka    initializeProximityInfoStates(inputCodePoints, inputXs, inputYs, times, pointerIds, inputSize,
903107b467c91c471ce4e00c5d8de559f7b0da2cd6Satoshi Kataoka            maxSpatialDistance, maxPointerCount);
913107b467c91c471ce4e00c5d8de559f7b0da2cd6Satoshi Kataoka}
923107b467c91c471ce4e00c5d8de559f7b0da2cd6Satoshi Kataoka
933107b467c91c471ce4e00c5d8de559f7b0da2cd6Satoshi Kataokaconst uint8_t *DicTraverseSession::getOffsetDict() const {
943107b467c91c471ce4e00c5d8de559f7b0da2cd6Satoshi Kataoka    return mDictionary->getOffsetDict();
953107b467c91c471ce4e00c5d8de559f7b0da2cd6Satoshi Kataoka}
963107b467c91c471ce4e00c5d8de559f7b0da2cd6Satoshi Kataoka
97ede2333640accecc066de328cb4f93e03e4bc5d7Tom Ouyangint DicTraverseSession::getDictFlags() const {
98ede2333640accecc066de328cb4f93e03e4bc5d7Tom Ouyang    return mDictionary->getDictFlags();
99ede2333640accecc066de328cb4f93e03e4bc5d7Tom Ouyang}
100ede2333640accecc066de328cb4f93e03e4bc5d7Tom Ouyang
1013107b467c91c471ce4e00c5d8de559f7b0da2cd6Satoshi Kataokavoid DicTraverseSession::resetCache(const int nextActiveCacheSize, const int maxWords) {
1023107b467c91c471ce4e00c5d8de559f7b0da2cd6Satoshi Kataoka    mDicNodesCache.reset(nextActiveCacheSize, maxWords);
1039559dd2e30de288a9ff7069bfc59f8500b949a88Tom Ouyang    mMultiBigramMap.clear();
1043107b467c91c471ce4e00c5d8de559f7b0da2cd6Satoshi Kataoka    mPartiallyCommited = false;
1053107b467c91c471ce4e00c5d8de559f7b0da2cd6Satoshi Kataoka}
1063107b467c91c471ce4e00c5d8de559f7b0da2cd6Satoshi Kataoka
1073107b467c91c471ce4e00c5d8de559f7b0da2cd6Satoshi Kataokavoid DicTraverseSession::initializeProximityInfoStates(const int *const inputCodePoints,
1083107b467c91c471ce4e00c5d8de559f7b0da2cd6Satoshi Kataoka        const int *const inputXs, const int *const inputYs, const int *const times,
1093107b467c91c471ce4e00c5d8de559f7b0da2cd6Satoshi Kataoka        const int *const pointerIds, const int inputSize, const float maxSpatialDistance,
1103107b467c91c471ce4e00c5d8de559f7b0da2cd6Satoshi Kataoka        const int maxPointerCount) {
1113107b467c91c471ce4e00c5d8de559f7b0da2cd6Satoshi Kataoka    ASSERT(1 <= maxPointerCount && maxPointerCount <= MAX_POINTER_COUNT_G);
1123107b467c91c471ce4e00c5d8de559f7b0da2cd6Satoshi Kataoka    mInputSize = 0;
1133107b467c91c471ce4e00c5d8de559f7b0da2cd6Satoshi Kataoka    for (int i = 0; i < maxPointerCount; ++i) {
1143107b467c91c471ce4e00c5d8de559f7b0da2cd6Satoshi Kataoka        mProximityInfoStates[i].initInputParams(i, maxSpatialDistance, getProximityInfo(),
1153107b467c91c471ce4e00c5d8de559f7b0da2cd6Satoshi Kataoka                inputCodePoints, inputSize, inputXs, inputYs, times, pointerIds,
1163107b467c91c471ce4e00c5d8de559f7b0da2cd6Satoshi Kataoka                maxPointerCount == MAX_POINTER_COUNT_G
1173107b467c91c471ce4e00c5d8de559f7b0da2cd6Satoshi Kataoka                /* TODO: this is a hack. fix proximity info state */);
1183107b467c91c471ce4e00c5d8de559f7b0da2cd6Satoshi Kataoka        mInputSize += mProximityInfoStates[i].size();
1193107b467c91c471ce4e00c5d8de559f7b0da2cd6Satoshi Kataoka    }
1203107b467c91c471ce4e00c5d8de559f7b0da2cd6Satoshi Kataoka}
1213107b467c91c471ce4e00c5d8de559f7b0da2cd6Satoshi Kataoka} // namespace latinime
122