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