diff options
Diffstat (limited to 'native')
9 files changed, 319 insertions, 65 deletions
diff --git a/native/jni/Android.mk b/native/jni/Android.mk index acd230ff2..e14cf5a71 100644 --- a/native/jni/Android.mk +++ b/native/jni/Android.mk @@ -71,7 +71,9 @@ LATIN_IME_CORE_SRC_FILES := \ suggest/core/policy/weighting.cpp \ suggest/core/session/dic_traverse_session.cpp \ $(addprefix suggest/policyimpl/dictionary/, \ + dynamic_patricia_trie_node_reader.cpp \ dynamic_patricia_trie_policy.cpp \ + dynamic_patricia_trie_reading_utils.cpp \ patricia_trie_policy.cpp \ patricia_trie_reading_utils.cpp) \ suggest/policyimpl/gesture/gesture_suggest_policy_factory.cpp \ diff --git a/native/jni/com_android_inputmethod_latin_BinaryDictionary.cpp b/native/jni/com_android_inputmethod_latin_BinaryDictionary.cpp index 6e1b80ee0..8b46c2644 100644 --- a/native/jni/com_android_inputmethod_latin_BinaryDictionary.cpp +++ b/native/jni/com_android_inputmethod_latin_BinaryDictionary.cpp @@ -186,7 +186,7 @@ static int latinime_BinaryDictionary_getSuggestions(JNIEnv *env, jclass clazz, j scores, spaceIndices, outputTypes); } else { count = dictionary->getBigrams(prevWordCodePoints, prevWordCodePointsLength, - inputCodePoints, inputSize, outputCodePoints, scores, outputTypes); + outputCodePoints, scores, outputTypes); } // Copy back the output values diff --git a/native/jni/src/suggest/core/dictionary/bigram_dictionary.cpp b/native/jni/src/suggest/core/dictionary/bigram_dictionary.cpp index 532c769c6..3751ae500 100644 --- a/native/jni/src/suggest/core/dictionary/bigram_dictionary.cpp +++ b/native/jni/src/suggest/core/dictionary/bigram_dictionary.cpp @@ -87,21 +87,14 @@ void BigramDictionary::addWordBigram(int *word, int length, int probability, int /* Parameters : * prevWord: the word before, the one for which we need to look up bigrams. * prevWordLength: its length. - * inputCodePoints: what user typed, in the same format as for UnigramDictionary::getSuggestions. - * inputSize: the size of the codes array. - * bigramCodePoints: an array for output, at the same format as outwords for getSuggestions. - * bigramProbability: an array to output frequencies. + * outBigramCodePoints: an array for output, at the same format as outwords for getSuggestions. + * outBigramProbability: an array to output frequencies. * outputTypes: an array to output types. * This method returns the number of bigrams this word has, for backward compatibility. - * Note: this is not the number of bigrams output in the array, which is the number of - * bigrams this word has WHOSE first letter also matches the letter the user typed. - * TODO: this may not be a sensible thing to do. It makes sense when the bigrams are - * used to match the first letter of the second word, but once the user has typed more - * and the bigrams are used to boost unigram result scores, it makes little sense to - * reduce their scope to the ones that match the first letter. */ -int BigramDictionary::getPredictions(const int *prevWord, int prevWordLength, int *inputCodePoints, - int inputSize, int *bigramCodePoints, int *bigramProbability, int *outputTypes) const { +int BigramDictionary::getPredictions(const int *prevWord, const int prevWordLength, + int *const outBigramCodePoints, int *const outBigramProbability, + int *const outputTypes) const { // TODO: remove unused arguments, and refrain from storing stuff in members of this class // TODO: have "in" arguments before "out" ones, and make out args explicit in the name @@ -126,21 +119,16 @@ int BigramDictionary::getPredictions(const int *prevWord, int prevWordLength, in getCodePointsAndProbabilityAndReturnCodePointCount( mBinaryDictionaryInfo, bigramsIt.getBigramPos(), MAX_WORD_LENGTH, bigramBuffer, &unigramProbability); - - // inputSize == 0 means we are trying to find bigram predictions. - if (inputSize < 1 || checkFirstCharacter(bigramBuffer, inputCodePoints)) { - const int bigramProbabilityTemp = bigramsIt.getProbability(); - // Due to space constraints, the probability for bigrams is approximate - the lower the - // unigram probability, the worse the precision. The theoritical maximum error in - // resulting probability is 8 - although in the practice it's never bigger than 3 or 4 - // in very bad cases. This means that sometimes, we'll see some bigrams interverted - // here, but it can't get too bad. - const int probability = ProbabilityUtils::computeProbabilityForBigram( - unigramProbability, bigramProbabilityTemp); - addWordBigram(bigramBuffer, length, probability, bigramProbability, bigramCodePoints, - outputTypes); - ++bigramCount; - } + // Due to space constraints, the probability for bigrams is approximate - the lower the + // unigram probability, the worse the precision. The theoritical maximum error in + // resulting probability is 8 - although in the practice it's never bigger than 3 or 4 + // in very bad cases. This means that sometimes, we'll see some bigrams interverted + // here, but it can't get too bad. + const int probability = ProbabilityUtils::computeProbabilityForBigram( + unigramProbability, bigramsIt.getProbability()); + addWordBigram(bigramBuffer, length, probability, outBigramProbability, outBigramCodePoints, + outputTypes); + ++bigramCount; } return min(bigramCount, MAX_RESULTS); } @@ -157,22 +145,6 @@ int BigramDictionary::getBigramListPositionForWord(const int *prevWord, const in mBinaryDictionaryInfo, pos); } -bool BigramDictionary::checkFirstCharacter(int *word, int *inputCodePoints) const { - // Checks whether this word starts with same character or neighboring characters of - // what user typed. - - int maxAlt = MAX_ALTERNATIVES; - const int firstBaseLowerCodePoint = CharUtils::toBaseLowerCase(*word); - while (maxAlt > 0) { - if (CharUtils::toBaseLowerCase(*inputCodePoints) == firstBaseLowerCodePoint) { - return true; - } - inputCodePoints++; - maxAlt--; - } - return false; -} - bool BigramDictionary::isValidBigram(const int *word0, int length0, const int *word1, int length1) const { int pos = getBigramListPositionForWord(word0, length0, false /* forceLowerCaseSearch */); diff --git a/native/jni/src/suggest/core/dictionary/bigram_dictionary.h b/native/jni/src/suggest/core/dictionary/bigram_dictionary.h index 7706a2c22..438c34cac 100644 --- a/native/jni/src/suggest/core/dictionary/bigram_dictionary.h +++ b/native/jni/src/suggest/core/dictionary/bigram_dictionary.h @@ -27,8 +27,8 @@ class BigramDictionary { public: BigramDictionary(const BinaryDictionaryInfo *const binaryDictionaryInfo); - int getPredictions(const int *word, int length, int *inputCodePoints, int inputSize, - int *outWords, int *frequencies, int *outputTypes) const; + int getPredictions(const int *word, int length, int *outBigramCodePoints, + int *outBigramProbability, int *outputTypes) const; bool isValidBigram(const int *word1, int length1, const int *word2, int length2) const; ~BigramDictionary(); @@ -37,13 +37,10 @@ class BigramDictionary { void addWordBigram(int *word, int length, int probability, int *bigramProbability, int *bigramCodePoints, int *outputTypes) const; - bool checkFirstCharacter(int *word, int *inputCodePoints) const; int getBigramListPositionForWord(const int *prevWord, const int prevWordLength, const bool forceLowerCaseSearch) const; const BinaryDictionaryInfo *const mBinaryDictionaryInfo; - // TODO: Re-implement proximity correction for bigram correction - static const int MAX_ALTERNATIVES = 1; }; } // namespace latinime #endif // LATINIME_BIGRAM_DICTIONARY_H diff --git a/native/jni/src/suggest/core/dictionary/dictionary.cpp b/native/jni/src/suggest/core/dictionary/dictionary.cpp index 4f5d29f6a..4a9e38fe8 100644 --- a/native/jni/src/suggest/core/dictionary/dictionary.cpp +++ b/native/jni/src/suggest/core/dictionary/dictionary.cpp @@ -76,11 +76,10 @@ int Dictionary::getSuggestions(ProximityInfo *proximityInfo, DicTraverseSession } } -int Dictionary::getBigrams(const int *word, int length, int *inputCodePoints, int inputSize, - int *outWords, int *frequencies, int *outputTypes) const { +int Dictionary::getBigrams(const int *word, int length, int *outWords, int *frequencies, + int *outputTypes) const { if (length <= 0) return 0; - return mBigramDictionary->getPredictions(word, length, inputCodePoints, inputSize, outWords, - frequencies, outputTypes); + return mBigramDictionary->getPredictions(word, length, outWords, frequencies, outputTypes); } int Dictionary::getProbability(const int *word, int length) const { diff --git a/native/jni/src/suggest/core/dictionary/dictionary.h b/native/jni/src/suggest/core/dictionary/dictionary.h index 1bf24a85b..9f1e0729d 100644 --- a/native/jni/src/suggest/core/dictionary/dictionary.h +++ b/native/jni/src/suggest/core/dictionary/dictionary.h @@ -62,8 +62,8 @@ class Dictionary { const SuggestOptions *const suggestOptions, int *outWords, int *frequencies, int *spaceIndices, int *outputTypes) const; - int getBigrams(const int *word, int length, int *inputCodePoints, int inputSize, int *outWords, - int *frequencies, int *outputTypes) const; + int getBigrams(const int *word, int length, int *outWords, int *frequencies, + int *outputTypes) const; int getProbability(const int *word, int length) const; diff --git a/native/jni/src/suggest/policyimpl/dictionary/dynamic_patricia_trie_node_reader.cpp b/native/jni/src/suggest/policyimpl/dictionary/dynamic_patricia_trie_node_reader.cpp new file mode 100644 index 000000000..20cda91a3 --- /dev/null +++ b/native/jni/src/suggest/policyimpl/dictionary/dynamic_patricia_trie_node_reader.cpp @@ -0,0 +1,74 @@ +/* + * Copyright (C) 2013, The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "suggest/policyimpl/dictionary/dynamic_patricia_trie_node_reader.h" + +#include "suggest/core/dictionary/binary_dictionary_info.h" +#include "suggest/core/dictionary/binary_dictionary_terminal_attributes_reading_utils.h" +#include "suggest/policyimpl/dictionary/dynamic_patricia_trie_reading_utils.h" + +namespace latinime { + +void DynamicPatriciaTrieNodeReader::fetchNodeInfoFromBufferAndProcessMovedNode(const int nodePos, + const int maxCodePointCount, int *const outCodePoints) { + const uint8_t *const dictRoot = mBinaryDictionaryInfo->getDictRoot(); + int pos = nodePos; + mFlags = PatriciaTrieReadingUtils::getFlagsAndAdvancePosition(dictRoot, &pos); + mParentPos = DynamicPatriciaTrieReadingUtils::getParentPosAndAdvancePosition(dictRoot, &pos); + if (outCodePoints != 0) { + mCodePointCount = PatriciaTrieReadingUtils::getCharsAndAdvancePosition( + dictRoot, mFlags, maxCodePointCount, outCodePoints, &pos); + } else { + mCodePointCount = PatriciaTrieReadingUtils::skipCharacters( + dictRoot, mFlags, MAX_WORD_LENGTH, &pos); + } + if (isTerminal()) { + mProbability = PatriciaTrieReadingUtils::readProbabilityAndAdvancePosition(dictRoot, &pos); + } else { + mProbability = NOT_A_PROBABILITY; + } + if (hasChildren()) { + mChildrenPos = DynamicPatriciaTrieReadingUtils::readChildrenPositionAndAdvancePosition( + dictRoot, mFlags, &pos); + } else { + mChildrenPos = NOT_A_DICT_POS; + } + if (PatriciaTrieReadingUtils::hasShortcutTargets(mFlags)) { + mShortcutPos = pos; + BinaryDictionaryTerminalAttributesReadingUtils::skipShortcuts(mBinaryDictionaryInfo, &pos); + } else { + mShortcutPos = NOT_A_DICT_POS; + } + if (PatriciaTrieReadingUtils::hasBigrams(mFlags)) { + mBigramPos = pos; + BinaryDictionaryTerminalAttributesReadingUtils::skipExistingBigrams( + mBinaryDictionaryInfo, &pos); + } else { + mBigramPos = NOT_A_DICT_POS; + } + // Update siblingPos if needed. + if (mSiblingPos == NOT_A_VALID_WORD_POS) { + // Sibling position is the tail position of current node. + mSiblingPos = pos; + } + // Read destination node if the read node is a moved node. + if (DynamicPatriciaTrieReadingUtils::isMoved(mFlags)) { + // The destination position is stored at the same place as the parent position. + fetchNodeInfoFromBufferAndProcessMovedNode(mParentPos, maxCodePointCount, outCodePoints); + } +} + +} diff --git a/native/jni/src/suggest/policyimpl/dictionary/dynamic_patricia_trie_node_reader.h b/native/jni/src/suggest/policyimpl/dictionary/dynamic_patricia_trie_node_reader.h new file mode 100644 index 000000000..b668aab78 --- /dev/null +++ b/native/jni/src/suggest/policyimpl/dictionary/dynamic_patricia_trie_node_reader.h @@ -0,0 +1,134 @@ +/* + * Copyright (C) 2013, The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef LATINIME_DYNAMIC_PATRICIA_TRIE_NODE_READER_H +#define LATINIME_DYNAMIC_PATRICIA_TRIE_NODE_READER_H + +#include "defines.h" +#include "suggest/policyimpl/dictionary/dynamic_patricia_trie_reading_utils.h" +#include "suggest/policyimpl/dictionary/patricia_trie_reading_utils.h" + +namespace latinime { + +class BinaryDictionaryInfo; + +/* + * This class is used for helping to read nodes of dynamic patricia trie. This class handles moved + * node and reads node attributes. + */ +class DynamicPatriciaTrieNodeReader { + public: + explicit DynamicPatriciaTrieNodeReader(const BinaryDictionaryInfo *const binaryDictionaryInfo) + : mBinaryDictionaryInfo(binaryDictionaryInfo), mNodePos(NOT_A_VALID_WORD_POS), + mFlags(0), mParentPos(NOT_A_DICT_POS), mCodePointCount(0), + mProbability(NOT_A_PROBABILITY), mChildrenPos(NOT_A_DICT_POS), + mShortcutPos(NOT_A_DICT_POS), mBigramPos(NOT_A_DICT_POS), + mSiblingPos(NOT_A_VALID_WORD_POS) {} + + ~DynamicPatriciaTrieNodeReader() {} + + // Reads node information from dictionary buffer and updates members with the information. + AK_FORCE_INLINE void fetchNodeInfoFromBuffer(const int nodePos) { + fetchNodeInfoFromBufferAndGetNodeCodePoints(mNodePos , 0 /* maxCodePointCount */, + 0 /* outCodePoints */); + } + + AK_FORCE_INLINE void fetchNodeInfoFromBufferAndGetNodeCodePoints(const int nodePos, + const int maxCodePointCount, int *const outCodePoints) { + mNodePos = nodePos; + mSiblingPos = NOT_A_VALID_WORD_POS; + fetchNodeInfoFromBufferAndProcessMovedNode(mNodePos, maxCodePointCount, outCodePoints); + } + + AK_FORCE_INLINE int getNodePos() const { + return mNodePos; + } + + // Flags + AK_FORCE_INLINE bool isDeleted() const { + return DynamicPatriciaTrieReadingUtils::isDeleted(mFlags); + } + + AK_FORCE_INLINE bool hasChildren() const { + return PatriciaTrieReadingUtils::hasChildrenInFlags(mFlags); + } + + AK_FORCE_INLINE bool isTerminal() const { + return PatriciaTrieReadingUtils::isTerminal(mFlags); + } + + AK_FORCE_INLINE bool isBlacklisted() const { + return PatriciaTrieReadingUtils::isBlacklisted(mFlags); + } + + AK_FORCE_INLINE bool isNotAWord() const { + return PatriciaTrieReadingUtils::isNotAWord(mFlags); + } + + // Parent node position + AK_FORCE_INLINE int getParentPos() const { + return mParentPos; + } + + // Number of code points + AK_FORCE_INLINE uint8_t getCodePointCount() const { + return mCodePointCount; + } + + // Probability + AK_FORCE_INLINE int getProbability() const { + return mProbability; + } + + // Children node group position + AK_FORCE_INLINE int getChildrenPos() const { + return mChildrenPos; + } + + // Shortcutlist position + AK_FORCE_INLINE int getShortcutPos() const { + return mShortcutPos; + } + + // Bigrams position + AK_FORCE_INLINE int getBigramsPos() const { + return mBigramPos; + } + + // Sibling node position + AK_FORCE_INLINE int getSiblingNodePos() const { + return mSiblingPos; + } + + private: + DISALLOW_COPY_AND_ASSIGN(DynamicPatriciaTrieNodeReader); + + const BinaryDictionaryInfo *const mBinaryDictionaryInfo; + int mNodePos; + DynamicPatriciaTrieReadingUtils::NodeFlags mFlags; + int mParentPos; + uint8_t mCodePointCount; + int mProbability; + int mChildrenPos; + int mShortcutPos; + int mBigramPos; + int mSiblingPos; + + void fetchNodeInfoFromBufferAndProcessMovedNode(const int nodePos, const int maxCodePointCount, + int *const outCodePoints); +}; +} // namespace latinime +#endif /* LATINIME_DYNAMIC_PATRICIA_TRIE_NODE_READER_H */ diff --git a/native/jni/src/suggest/policyimpl/dictionary/dynamic_patricia_trie_policy.cpp b/native/jni/src/suggest/policyimpl/dictionary/dynamic_patricia_trie_policy.cpp index c7314ecf1..9a180e6f7 100644 --- a/native/jni/src/suggest/policyimpl/dictionary/dynamic_patricia_trie_policy.cpp +++ b/native/jni/src/suggest/policyimpl/dictionary/dynamic_patricia_trie_policy.cpp @@ -14,12 +14,15 @@ * limitations under the License. */ -#include "suggest/policyimpl/dictionary/patricia_trie_policy.h" +#include "suggest/policyimpl/dictionary/dynamic_patricia_trie_policy.h" #include "defines.h" #include "suggest/core/dicnode/dic_node.h" #include "suggest/core/dicnode/dic_node_vector.h" #include "suggest/core/dictionary/binary_dictionary_info.h" +#include "suggest/policyimpl/dictionary/dynamic_patricia_trie_node_reader.h" +#include "suggest/policyimpl/dictionary/dynamic_patricia_trie_reading_utils.h" +#include "suggest/policyimpl/dictionary/patricia_trie_reading_utils.h" namespace latinime { @@ -28,15 +31,76 @@ const DynamicPatriciaTriePolicy DynamicPatriciaTriePolicy::sInstance; void DynamicPatriciaTriePolicy::createAndGetAllChildNodes(const DicNode *const dicNode, const BinaryDictionaryInfo *const binaryDictionaryInfo, const NodeFilter *const nodeFilter, DicNodeVector *const childDicNodes) const { - // TODO: Implement. + if (!dicNode->hasChildren()) { + return; + } + DynamicPatriciaTrieNodeReader nodeReader(binaryDictionaryInfo); + int mergedNodeCodePoints[MAX_WORD_LENGTH]; + int nextPos = dicNode->getChildrenPos(); + do { + const int childCount = PatriciaTrieReadingUtils::getGroupCountAndAdvancePosition( + binaryDictionaryInfo->getDictRoot(), &nextPos); + for (int i = 0; i < childCount; i++) { + nodeReader.fetchNodeInfoFromBufferAndGetNodeCodePoints(nextPos, MAX_WORD_LENGTH, + mergedNodeCodePoints); + if (!nodeReader.isDeleted() && !nodeFilter->isFilteredOut(mergedNodeCodePoints[0])) { + // Push child note when the node is not deleted and not filtered out. + childDicNodes->pushLeavingChild(dicNode, nodeReader.getNodePos(), + nodeReader.getChildrenPos(), nodeReader.getProbability(), + nodeReader.isTerminal(), nodeReader.hasChildren(), + nodeReader.isBlacklisted() || nodeReader.isNotAWord(), + nodeReader.getCodePointCount(), mergedNodeCodePoints); + } + nextPos = nodeReader.getSiblingNodePos(); + } + nextPos = DynamicPatriciaTrieReadingUtils::getForwardLinkPosition( + binaryDictionaryInfo->getDictRoot(), nextPos); + } while(DynamicPatriciaTrieReadingUtils::isValidForwardLinkPosition(nextPos)); } int DynamicPatriciaTriePolicy::getCodePointsAndProbabilityAndReturnCodePointCount( const BinaryDictionaryInfo *const binaryDictionaryInfo, const int nodePos, const int maxCodePointCount, int *const outCodePoints, int *const outUnigramProbability) const { - // TODO: Implement. - return 0; + // This method traverses parent nodes from the terminal by following parent pointers; thus, + // node code points are stored in the buffer in the reverse order. + int reverseCodePoints[maxCodePointCount]; + int mergedNodeCodePoints[maxCodePointCount]; + int codePointCount = 0; + + DynamicPatriciaTrieNodeReader nodeReader(binaryDictionaryInfo); + // First, read terminal node and get its probability. + nodeReader.fetchNodeInfoFromBufferAndGetNodeCodePoints(nodePos, maxCodePointCount, + mergedNodeCodePoints); + // Store terminal node probability. + *outUnigramProbability = nodeReader.getProbability(); + // Store terminal node code points to buffer in the reverse order. + for (int i = nodeReader.getCodePointCount() - 1; i >= 0; --i) { + reverseCodePoints[codePointCount++] = mergedNodeCodePoints[i]; + } + // Then, follow parent pos toward the root node. + while (nodeReader.getParentPos() != getRootPosition()) { + // codePointCount must be incremented at least once in each iteration to ensure preventing + // infinite loop. + if (nodeReader.isDeleted() || codePointCount > maxCodePointCount + || nodeReader.getCodePointCount() <= 0) { + // The nodePos is not a valid terminal node position in the dictionary. + *outUnigramProbability = NOT_A_PROBABILITY; + return 0; + } + // Read parent node. + nodeReader.fetchNodeInfoFromBufferAndGetNodeCodePoints(nodeReader.getParentPos(), + maxCodePointCount, mergedNodeCodePoints); + // Store node code points to buffer in the reverse order. + for (int i = nodeReader.getCodePointCount() - 1; i >= 0; --i) { + reverseCodePoints[codePointCount++] = mergedNodeCodePoints[i]; + } + } + // Reverse the stored code points to output them. + for (int i = 0; i < codePointCount; ++i) { + outCodePoints[i] = reverseCodePoints[codePointCount - i - 1]; + } + return codePointCount; } int DynamicPatriciaTriePolicy::getTerminalNodePositionOfWord( @@ -48,22 +112,34 @@ int DynamicPatriciaTriePolicy::getTerminalNodePositionOfWord( int DynamicPatriciaTriePolicy::getUnigramProbability( const BinaryDictionaryInfo *const binaryDictionaryInfo, const int nodePos) const { - // TODO: Implement. - return NOT_A_PROBABILITY; + DynamicPatriciaTrieNodeReader nodeReader(binaryDictionaryInfo); + nodeReader.fetchNodeInfoFromBuffer(nodePos); + if (nodeReader.isDeleted() || nodeReader.isBlacklisted() || nodeReader.isNotAWord()) { + return NOT_A_PROBABILITY; + } + return nodeReader.getProbability(); } int DynamicPatriciaTriePolicy::getShortcutPositionOfNode( const BinaryDictionaryInfo *const binaryDictionaryInfo, const int nodePos) const { - // TODO: Implement. - return NOT_A_DICT_POS; + DynamicPatriciaTrieNodeReader nodeReader(binaryDictionaryInfo); + nodeReader.fetchNodeInfoFromBuffer(nodePos); + if (nodeReader.isDeleted()) { + return NOT_A_DICT_POS; + } + return nodeReader.getShortcutPos(); } int DynamicPatriciaTriePolicy::getBigramsPositionOfNode( const BinaryDictionaryInfo *const binaryDictionaryInfo, const int nodePos) const { - // TODO: Implement. - return NOT_A_DICT_POS; + DynamicPatriciaTrieNodeReader nodeReader(binaryDictionaryInfo); + nodeReader.fetchNodeInfoFromBuffer(nodePos); + if (nodeReader.isDeleted()) { + return NOT_A_DICT_POS; + } + return nodeReader.getBigramsPos(); } } // namespace latinime |