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