1 /* 2 * Copyright (C) 2013, 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 #include "suggest/policyimpl/dictionary/dynamic_patricia_trie_node_reader.h" 18 19 #include "suggest/core/policy/dictionary_bigrams_structure_policy.h" 20 #include "suggest/core/policy/dictionary_shortcuts_structure_policy.h" 21 #include "suggest/policyimpl/dictionary/dynamic_patricia_trie_reading_utils.h" 22 #include "suggest/policyimpl/dictionary/utils/buffer_with_extendable_buffer.h" 23 24 namespace latinime { 25 26 void DynamicPatriciaTrieNodeReader::fetchPtNodeInfoFromBufferAndProcessMovedPtNode( 27 const int ptNodePos, const int maxCodePointCount, int *const outCodePoints) { 28 if (ptNodePos < 0 || ptNodePos >= mBuffer->getTailPosition()) { 29 // Reading invalid position because of bug or broken dictionary. 30 AKLOGE("Fetching PtNode info from invalid dictionary position: %d, dictionary size: %d", 31 ptNodePos, mBuffer->getTailPosition()); 32 ASSERT(false); 33 invalidatePtNodeInfo(); 34 return; 35 } 36 const bool usesAdditionalBuffer = mBuffer->isInAdditionalBuffer(ptNodePos); 37 const uint8_t *const dictBuf = mBuffer->getBuffer(usesAdditionalBuffer); 38 int pos = ptNodePos; 39 mHeadPos = ptNodePos; 40 if (usesAdditionalBuffer) { 41 pos -= mBuffer->getOriginalBufferSize(); 42 } 43 mFlags = PatriciaTrieReadingUtils::getFlagsAndAdvancePosition(dictBuf, &pos); 44 const int parentPosOffset = 45 DynamicPatriciaTrieReadingUtils::getParentPtNodePosOffsetAndAdvancePosition(dictBuf, 46 &pos); 47 mParentPos = DynamicPatriciaTrieReadingUtils::getParentPtNodePos(parentPosOffset, mHeadPos); 48 if (outCodePoints != 0) { 49 mCodePointCount = PatriciaTrieReadingUtils::getCharsAndAdvancePosition( 50 dictBuf, mFlags, maxCodePointCount, outCodePoints, &pos); 51 } else { 52 mCodePointCount = PatriciaTrieReadingUtils::skipCharacters( 53 dictBuf, mFlags, MAX_WORD_LENGTH, &pos); 54 } 55 if (isTerminal()) { 56 mProbabilityFieldPos = pos; 57 if (usesAdditionalBuffer) { 58 mProbabilityFieldPos += mBuffer->getOriginalBufferSize(); 59 } 60 mProbability = PatriciaTrieReadingUtils::readProbabilityAndAdvancePosition(dictBuf, &pos); 61 } else { 62 mProbabilityFieldPos = NOT_A_DICT_POS; 63 mProbability = NOT_A_PROBABILITY; 64 } 65 mChildrenPosFieldPos = pos; 66 if (usesAdditionalBuffer) { 67 mChildrenPosFieldPos += mBuffer->getOriginalBufferSize(); 68 } 69 mChildrenPos = DynamicPatriciaTrieReadingUtils::readChildrenPositionAndAdvancePosition( 70 dictBuf, &pos); 71 if (usesAdditionalBuffer && mChildrenPos != NOT_A_DICT_POS) { 72 mChildrenPos += mBuffer->getOriginalBufferSize(); 73 } 74 if (mSiblingPos == NOT_A_DICT_POS) { 75 if (DynamicPatriciaTrieReadingUtils::isMoved(mFlags)) { 76 mBigramLinkedNodePos = mChildrenPos; 77 } else { 78 mBigramLinkedNodePos = NOT_A_DICT_POS; 79 } 80 } 81 if (usesAdditionalBuffer) { 82 pos += mBuffer->getOriginalBufferSize(); 83 } 84 if (PatriciaTrieReadingUtils::hasShortcutTargets(mFlags)) { 85 mShortcutPos = pos; 86 mShortcutsPolicy->skipAllShortcuts(&pos); 87 } else { 88 mShortcutPos = NOT_A_DICT_POS; 89 } 90 if (PatriciaTrieReadingUtils::hasBigrams(mFlags)) { 91 mBigramPos = pos; 92 mBigramsPolicy->skipAllBigrams(&pos); 93 } else { 94 mBigramPos = NOT_A_DICT_POS; 95 } 96 // Update siblingPos if needed. 97 if (mSiblingPos == NOT_A_DICT_POS) { 98 // Sibling position is the tail position of current node. 99 mSiblingPos = pos; 100 } 101 // Read destination node if the read node is a moved node. 102 if (DynamicPatriciaTrieReadingUtils::isMoved(mFlags)) { 103 // The destination position is stored at the same place as the parent position. 104 fetchPtNodeInfoFromBufferAndProcessMovedPtNode(mParentPos, maxCodePointCount, 105 outCodePoints); 106 } 107 } 108 109 void DynamicPatriciaTrieNodeReader::invalidatePtNodeInfo() { 110 mHeadPos = NOT_A_DICT_POS; 111 mFlags = 0; 112 mParentPos = NOT_A_DICT_POS; 113 mCodePointCount = 0; 114 mProbabilityFieldPos = NOT_A_DICT_POS; 115 mProbability = NOT_A_PROBABILITY; 116 mChildrenPosFieldPos = NOT_A_DICT_POS; 117 mChildrenPos = NOT_A_DICT_POS; 118 mBigramLinkedNodePos = NOT_A_DICT_POS; 119 mShortcutPos = NOT_A_DICT_POS; 120 mBigramPos = NOT_A_DICT_POS; 121 mSiblingPos = NOT_A_DICT_POS; 122 } 123 124 } 125