ver4_patricia_trie_node_writer.cpp revision 6bf268132d60061fd26bd8cba63a12b56b22056e
16bf268132d60061fd26bd8cba63a12b56b22056eKeisuke Kuroyanagi/*
26bf268132d60061fd26bd8cba63a12b56b22056eKeisuke Kuroyanagi * Copyright (C) 2013, The Android Open Source Project
36bf268132d60061fd26bd8cba63a12b56b22056eKeisuke Kuroyanagi *
46bf268132d60061fd26bd8cba63a12b56b22056eKeisuke Kuroyanagi * Licensed under the Apache License, Version 2.0 (the "License");
56bf268132d60061fd26bd8cba63a12b56b22056eKeisuke Kuroyanagi * you may not use this file except in compliance with the License.
66bf268132d60061fd26bd8cba63a12b56b22056eKeisuke Kuroyanagi * You may obtain a copy of the License at
76bf268132d60061fd26bd8cba63a12b56b22056eKeisuke Kuroyanagi *
86bf268132d60061fd26bd8cba63a12b56b22056eKeisuke Kuroyanagi *     http://www.apache.org/licenses/LICENSE-2.0
96bf268132d60061fd26bd8cba63a12b56b22056eKeisuke Kuroyanagi *
106bf268132d60061fd26bd8cba63a12b56b22056eKeisuke Kuroyanagi * Unless required by applicable law or agreed to in writing, software
116bf268132d60061fd26bd8cba63a12b56b22056eKeisuke Kuroyanagi * distributed under the License is distributed on an "AS IS" BASIS,
126bf268132d60061fd26bd8cba63a12b56b22056eKeisuke Kuroyanagi * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
136bf268132d60061fd26bd8cba63a12b56b22056eKeisuke Kuroyanagi * See the License for the specific language governing permissions and
146bf268132d60061fd26bd8cba63a12b56b22056eKeisuke Kuroyanagi * limitations under the License.
156bf268132d60061fd26bd8cba63a12b56b22056eKeisuke Kuroyanagi */
166bf268132d60061fd26bd8cba63a12b56b22056eKeisuke Kuroyanagi
176bf268132d60061fd26bd8cba63a12b56b22056eKeisuke Kuroyanagi/*
186bf268132d60061fd26bd8cba63a12b56b22056eKeisuke Kuroyanagi * !!!!! DO NOT EDIT THIS FILE !!!!!
196bf268132d60061fd26bd8cba63a12b56b22056eKeisuke Kuroyanagi *
206bf268132d60061fd26bd8cba63a12b56b22056eKeisuke Kuroyanagi * This file was generated from
216bf268132d60061fd26bd8cba63a12b56b22056eKeisuke Kuroyanagi *   suggest/policyimpl/dictionary/structure/v4/ver4_patricia_trie_node_writer.cpp
226bf268132d60061fd26bd8cba63a12b56b22056eKeisuke Kuroyanagi */
236bf268132d60061fd26bd8cba63a12b56b22056eKeisuke Kuroyanagi
246bf268132d60061fd26bd8cba63a12b56b22056eKeisuke Kuroyanagi#include "suggest/policyimpl/dictionary/structure/backward/v401/ver4_patricia_trie_node_writer.h"
256bf268132d60061fd26bd8cba63a12b56b22056eKeisuke Kuroyanagi
266bf268132d60061fd26bd8cba63a12b56b22056eKeisuke Kuroyanagi#include "suggest/core/dictionary/property/unigram_property.h"
276bf268132d60061fd26bd8cba63a12b56b22056eKeisuke Kuroyanagi#include "suggest/policyimpl/dictionary/header/header_policy.h"
286bf268132d60061fd26bd8cba63a12b56b22056eKeisuke Kuroyanagi#include "suggest/policyimpl/dictionary/structure/pt_common/dynamic_pt_reading_utils.h"
296bf268132d60061fd26bd8cba63a12b56b22056eKeisuke Kuroyanagi#include "suggest/policyimpl/dictionary/structure/pt_common/dynamic_pt_writing_utils.h"
306bf268132d60061fd26bd8cba63a12b56b22056eKeisuke Kuroyanagi#include "suggest/policyimpl/dictionary/structure/pt_common/patricia_trie_reading_utils.h"
316bf268132d60061fd26bd8cba63a12b56b22056eKeisuke Kuroyanagi#include "suggest/policyimpl/dictionary/structure/backward/v401/bigram/ver4_bigram_list_policy.h"
326bf268132d60061fd26bd8cba63a12b56b22056eKeisuke Kuroyanagi#include "suggest/policyimpl/dictionary/structure/backward/v401/content/probability_entry.h"
336bf268132d60061fd26bd8cba63a12b56b22056eKeisuke Kuroyanagi#include "suggest/policyimpl/dictionary/structure/backward/v401/shortcut/ver4_shortcut_list_policy.h"
346bf268132d60061fd26bd8cba63a12b56b22056eKeisuke Kuroyanagi#include "suggest/policyimpl/dictionary/structure/backward/v401/ver4_patricia_trie_node_reader.h"
356bf268132d60061fd26bd8cba63a12b56b22056eKeisuke Kuroyanagi#include "suggest/policyimpl/dictionary/structure/backward/v401/ver4_dict_buffers.h"
366bf268132d60061fd26bd8cba63a12b56b22056eKeisuke Kuroyanagi#include "suggest/policyimpl/dictionary/utils/buffer_with_extendable_buffer.h"
376bf268132d60061fd26bd8cba63a12b56b22056eKeisuke Kuroyanagi#include "suggest/policyimpl/dictionary/utils/forgetting_curve_utils.h"
386bf268132d60061fd26bd8cba63a12b56b22056eKeisuke Kuroyanagi
396bf268132d60061fd26bd8cba63a12b56b22056eKeisuke Kuroyanaginamespace latinime {
406bf268132d60061fd26bd8cba63a12b56b22056eKeisuke Kuroyanaginamespace backward {
416bf268132d60061fd26bd8cba63a12b56b22056eKeisuke Kuroyanaginamespace v401 {
426bf268132d60061fd26bd8cba63a12b56b22056eKeisuke Kuroyanagi
436bf268132d60061fd26bd8cba63a12b56b22056eKeisuke Kuroyanagiconst int Ver4PatriciaTrieNodeWriter::CHILDREN_POSITION_FIELD_SIZE = 3;
446bf268132d60061fd26bd8cba63a12b56b22056eKeisuke Kuroyanagi
456bf268132d60061fd26bd8cba63a12b56b22056eKeisuke Kuroyanagibool Ver4PatriciaTrieNodeWriter::markPtNodeAsDeleted(
466bf268132d60061fd26bd8cba63a12b56b22056eKeisuke Kuroyanagi        const PtNodeParams *const toBeUpdatedPtNodeParams) {
476bf268132d60061fd26bd8cba63a12b56b22056eKeisuke Kuroyanagi    int pos = toBeUpdatedPtNodeParams->getHeadPos();
486bf268132d60061fd26bd8cba63a12b56b22056eKeisuke Kuroyanagi    const bool usesAdditionalBuffer = mTrieBuffer->isInAdditionalBuffer(pos);
496bf268132d60061fd26bd8cba63a12b56b22056eKeisuke Kuroyanagi    const uint8_t *const dictBuf = mTrieBuffer->getBuffer(usesAdditionalBuffer);
506bf268132d60061fd26bd8cba63a12b56b22056eKeisuke Kuroyanagi    if (usesAdditionalBuffer) {
516bf268132d60061fd26bd8cba63a12b56b22056eKeisuke Kuroyanagi        pos -= mTrieBuffer->getOriginalBufferSize();
526bf268132d60061fd26bd8cba63a12b56b22056eKeisuke Kuroyanagi    }
536bf268132d60061fd26bd8cba63a12b56b22056eKeisuke Kuroyanagi    // Read original flags
546bf268132d60061fd26bd8cba63a12b56b22056eKeisuke Kuroyanagi    const PatriciaTrieReadingUtils::NodeFlags originalFlags =
556bf268132d60061fd26bd8cba63a12b56b22056eKeisuke Kuroyanagi            PatriciaTrieReadingUtils::getFlagsAndAdvancePosition(dictBuf, &pos);
566bf268132d60061fd26bd8cba63a12b56b22056eKeisuke Kuroyanagi    const PatriciaTrieReadingUtils::NodeFlags updatedFlags =
576bf268132d60061fd26bd8cba63a12b56b22056eKeisuke Kuroyanagi            DynamicPtReadingUtils::updateAndGetFlags(originalFlags, false /* isMoved */,
586bf268132d60061fd26bd8cba63a12b56b22056eKeisuke Kuroyanagi                    true /* isDeleted */, false /* willBecomeNonTerminal */);
596bf268132d60061fd26bd8cba63a12b56b22056eKeisuke Kuroyanagi    int writingPos = toBeUpdatedPtNodeParams->getHeadPos();
606bf268132d60061fd26bd8cba63a12b56b22056eKeisuke Kuroyanagi    // Update flags.
616bf268132d60061fd26bd8cba63a12b56b22056eKeisuke Kuroyanagi    if (!DynamicPtWritingUtils::writeFlagsAndAdvancePosition(mTrieBuffer, updatedFlags,
626bf268132d60061fd26bd8cba63a12b56b22056eKeisuke Kuroyanagi            &writingPos)) {
636bf268132d60061fd26bd8cba63a12b56b22056eKeisuke Kuroyanagi        return false;
646bf268132d60061fd26bd8cba63a12b56b22056eKeisuke Kuroyanagi    }
656bf268132d60061fd26bd8cba63a12b56b22056eKeisuke Kuroyanagi    if (toBeUpdatedPtNodeParams->isTerminal()) {
666bf268132d60061fd26bd8cba63a12b56b22056eKeisuke Kuroyanagi        // The PtNode is a terminal. Delete entry from the terminal position lookup table.
676bf268132d60061fd26bd8cba63a12b56b22056eKeisuke Kuroyanagi        return mBuffers->getMutableTerminalPositionLookupTable()->setTerminalPtNodePosition(
686bf268132d60061fd26bd8cba63a12b56b22056eKeisuke Kuroyanagi                toBeUpdatedPtNodeParams->getTerminalId(), NOT_A_DICT_POS /* ptNodePos */);
696bf268132d60061fd26bd8cba63a12b56b22056eKeisuke Kuroyanagi    } else {
706bf268132d60061fd26bd8cba63a12b56b22056eKeisuke Kuroyanagi        return true;
716bf268132d60061fd26bd8cba63a12b56b22056eKeisuke Kuroyanagi    }
726bf268132d60061fd26bd8cba63a12b56b22056eKeisuke Kuroyanagi}
736bf268132d60061fd26bd8cba63a12b56b22056eKeisuke Kuroyanagi
746bf268132d60061fd26bd8cba63a12b56b22056eKeisuke Kuroyanagibool Ver4PatriciaTrieNodeWriter::markPtNodeAsMoved(
756bf268132d60061fd26bd8cba63a12b56b22056eKeisuke Kuroyanagi        const PtNodeParams *const toBeUpdatedPtNodeParams,
766bf268132d60061fd26bd8cba63a12b56b22056eKeisuke Kuroyanagi        const int movedPos, const int bigramLinkedNodePos) {
776bf268132d60061fd26bd8cba63a12b56b22056eKeisuke Kuroyanagi    int pos = toBeUpdatedPtNodeParams->getHeadPos();
786bf268132d60061fd26bd8cba63a12b56b22056eKeisuke Kuroyanagi    const bool usesAdditionalBuffer = mTrieBuffer->isInAdditionalBuffer(pos);
796bf268132d60061fd26bd8cba63a12b56b22056eKeisuke Kuroyanagi    const uint8_t *const dictBuf = mTrieBuffer->getBuffer(usesAdditionalBuffer);
806bf268132d60061fd26bd8cba63a12b56b22056eKeisuke Kuroyanagi    if (usesAdditionalBuffer) {
816bf268132d60061fd26bd8cba63a12b56b22056eKeisuke Kuroyanagi        pos -= mTrieBuffer->getOriginalBufferSize();
826bf268132d60061fd26bd8cba63a12b56b22056eKeisuke Kuroyanagi    }
836bf268132d60061fd26bd8cba63a12b56b22056eKeisuke Kuroyanagi    // Read original flags
846bf268132d60061fd26bd8cba63a12b56b22056eKeisuke Kuroyanagi    const PatriciaTrieReadingUtils::NodeFlags originalFlags =
856bf268132d60061fd26bd8cba63a12b56b22056eKeisuke Kuroyanagi            PatriciaTrieReadingUtils::getFlagsAndAdvancePosition(dictBuf, &pos);
866bf268132d60061fd26bd8cba63a12b56b22056eKeisuke Kuroyanagi    const PatriciaTrieReadingUtils::NodeFlags updatedFlags =
876bf268132d60061fd26bd8cba63a12b56b22056eKeisuke Kuroyanagi            DynamicPtReadingUtils::updateAndGetFlags(originalFlags, true /* isMoved */,
886bf268132d60061fd26bd8cba63a12b56b22056eKeisuke Kuroyanagi                    false /* isDeleted */, false /* willBecomeNonTerminal */);
896bf268132d60061fd26bd8cba63a12b56b22056eKeisuke Kuroyanagi    int writingPos = toBeUpdatedPtNodeParams->getHeadPos();
906bf268132d60061fd26bd8cba63a12b56b22056eKeisuke Kuroyanagi    // Update flags.
916bf268132d60061fd26bd8cba63a12b56b22056eKeisuke Kuroyanagi    if (!DynamicPtWritingUtils::writeFlagsAndAdvancePosition(mTrieBuffer, updatedFlags,
926bf268132d60061fd26bd8cba63a12b56b22056eKeisuke Kuroyanagi            &writingPos)) {
936bf268132d60061fd26bd8cba63a12b56b22056eKeisuke Kuroyanagi        return false;
946bf268132d60061fd26bd8cba63a12b56b22056eKeisuke Kuroyanagi    }
956bf268132d60061fd26bd8cba63a12b56b22056eKeisuke Kuroyanagi    // Update moved position, which is stored in the parent offset field.
966bf268132d60061fd26bd8cba63a12b56b22056eKeisuke Kuroyanagi    if (!DynamicPtWritingUtils::writeParentPosOffsetAndAdvancePosition(
976bf268132d60061fd26bd8cba63a12b56b22056eKeisuke Kuroyanagi            mTrieBuffer, movedPos, toBeUpdatedPtNodeParams->getHeadPos(), &writingPos)) {
986bf268132d60061fd26bd8cba63a12b56b22056eKeisuke Kuroyanagi        return false;
996bf268132d60061fd26bd8cba63a12b56b22056eKeisuke Kuroyanagi    }
1006bf268132d60061fd26bd8cba63a12b56b22056eKeisuke Kuroyanagi    if (toBeUpdatedPtNodeParams->hasChildren()) {
1016bf268132d60061fd26bd8cba63a12b56b22056eKeisuke Kuroyanagi        // Update children's parent position.
1026bf268132d60061fd26bd8cba63a12b56b22056eKeisuke Kuroyanagi        mReadingHelper.initWithPtNodeArrayPos(toBeUpdatedPtNodeParams->getChildrenPos());
1036bf268132d60061fd26bd8cba63a12b56b22056eKeisuke Kuroyanagi        while (!mReadingHelper.isEnd()) {
1046bf268132d60061fd26bd8cba63a12b56b22056eKeisuke Kuroyanagi            const PtNodeParams childPtNodeParams(mReadingHelper.getPtNodeParams());
1056bf268132d60061fd26bd8cba63a12b56b22056eKeisuke Kuroyanagi            int parentOffsetFieldPos = childPtNodeParams.getHeadPos()
1066bf268132d60061fd26bd8cba63a12b56b22056eKeisuke Kuroyanagi                    + DynamicPtWritingUtils::NODE_FLAG_FIELD_SIZE;
1076bf268132d60061fd26bd8cba63a12b56b22056eKeisuke Kuroyanagi            if (!DynamicPtWritingUtils::writeParentPosOffsetAndAdvancePosition(
1086bf268132d60061fd26bd8cba63a12b56b22056eKeisuke Kuroyanagi                    mTrieBuffer, bigramLinkedNodePos, childPtNodeParams.getHeadPos(),
1096bf268132d60061fd26bd8cba63a12b56b22056eKeisuke Kuroyanagi                    &parentOffsetFieldPos)) {
1106bf268132d60061fd26bd8cba63a12b56b22056eKeisuke Kuroyanagi                // Parent offset cannot be written because of a bug or a broken dictionary; thus,
1116bf268132d60061fd26bd8cba63a12b56b22056eKeisuke Kuroyanagi                // we give up to update dictionary.
1126bf268132d60061fd26bd8cba63a12b56b22056eKeisuke Kuroyanagi                return false;
1136bf268132d60061fd26bd8cba63a12b56b22056eKeisuke Kuroyanagi            }
1146bf268132d60061fd26bd8cba63a12b56b22056eKeisuke Kuroyanagi            mReadingHelper.readNextSiblingNode(childPtNodeParams);
1156bf268132d60061fd26bd8cba63a12b56b22056eKeisuke Kuroyanagi        }
1166bf268132d60061fd26bd8cba63a12b56b22056eKeisuke Kuroyanagi    }
1176bf268132d60061fd26bd8cba63a12b56b22056eKeisuke Kuroyanagi    return true;
1186bf268132d60061fd26bd8cba63a12b56b22056eKeisuke Kuroyanagi}
1196bf268132d60061fd26bd8cba63a12b56b22056eKeisuke Kuroyanagi
1206bf268132d60061fd26bd8cba63a12b56b22056eKeisuke Kuroyanagibool Ver4PatriciaTrieNodeWriter::markPtNodeAsWillBecomeNonTerminal(
1216bf268132d60061fd26bd8cba63a12b56b22056eKeisuke Kuroyanagi        const PtNodeParams *const toBeUpdatedPtNodeParams) {
1226bf268132d60061fd26bd8cba63a12b56b22056eKeisuke Kuroyanagi    int pos = toBeUpdatedPtNodeParams->getHeadPos();
1236bf268132d60061fd26bd8cba63a12b56b22056eKeisuke Kuroyanagi    const bool usesAdditionalBuffer = mTrieBuffer->isInAdditionalBuffer(pos);
1246bf268132d60061fd26bd8cba63a12b56b22056eKeisuke Kuroyanagi    const uint8_t *const dictBuf = mTrieBuffer->getBuffer(usesAdditionalBuffer);
1256bf268132d60061fd26bd8cba63a12b56b22056eKeisuke Kuroyanagi    if (usesAdditionalBuffer) {
1266bf268132d60061fd26bd8cba63a12b56b22056eKeisuke Kuroyanagi        pos -= mTrieBuffer->getOriginalBufferSize();
1276bf268132d60061fd26bd8cba63a12b56b22056eKeisuke Kuroyanagi    }
1286bf268132d60061fd26bd8cba63a12b56b22056eKeisuke Kuroyanagi    // Read original flags
1296bf268132d60061fd26bd8cba63a12b56b22056eKeisuke Kuroyanagi    const PatriciaTrieReadingUtils::NodeFlags originalFlags =
1306bf268132d60061fd26bd8cba63a12b56b22056eKeisuke Kuroyanagi            PatriciaTrieReadingUtils::getFlagsAndAdvancePosition(dictBuf, &pos);
1316bf268132d60061fd26bd8cba63a12b56b22056eKeisuke Kuroyanagi    const PatriciaTrieReadingUtils::NodeFlags updatedFlags =
1326bf268132d60061fd26bd8cba63a12b56b22056eKeisuke Kuroyanagi            DynamicPtReadingUtils::updateAndGetFlags(originalFlags, false /* isMoved */,
1336bf268132d60061fd26bd8cba63a12b56b22056eKeisuke Kuroyanagi                    false /* isDeleted */, true /* willBecomeNonTerminal */);
1346bf268132d60061fd26bd8cba63a12b56b22056eKeisuke Kuroyanagi    if (!mBuffers->getMutableTerminalPositionLookupTable()->setTerminalPtNodePosition(
1356bf268132d60061fd26bd8cba63a12b56b22056eKeisuke Kuroyanagi            toBeUpdatedPtNodeParams->getTerminalId(), NOT_A_DICT_POS /* ptNodePos */)) {
1366bf268132d60061fd26bd8cba63a12b56b22056eKeisuke Kuroyanagi        AKLOGE("Cannot update terminal position lookup table. terminal id: %d",
1376bf268132d60061fd26bd8cba63a12b56b22056eKeisuke Kuroyanagi                toBeUpdatedPtNodeParams->getTerminalId());
1386bf268132d60061fd26bd8cba63a12b56b22056eKeisuke Kuroyanagi        return false;
1396bf268132d60061fd26bd8cba63a12b56b22056eKeisuke Kuroyanagi    }
1406bf268132d60061fd26bd8cba63a12b56b22056eKeisuke Kuroyanagi    // Update flags.
1416bf268132d60061fd26bd8cba63a12b56b22056eKeisuke Kuroyanagi    int writingPos = toBeUpdatedPtNodeParams->getHeadPos();
1426bf268132d60061fd26bd8cba63a12b56b22056eKeisuke Kuroyanagi    return DynamicPtWritingUtils::writeFlagsAndAdvancePosition(mTrieBuffer, updatedFlags,
1436bf268132d60061fd26bd8cba63a12b56b22056eKeisuke Kuroyanagi            &writingPos);
1446bf268132d60061fd26bd8cba63a12b56b22056eKeisuke Kuroyanagi}
1456bf268132d60061fd26bd8cba63a12b56b22056eKeisuke Kuroyanagi
1466bf268132d60061fd26bd8cba63a12b56b22056eKeisuke Kuroyanagibool Ver4PatriciaTrieNodeWriter::updatePtNodeUnigramProperty(
1476bf268132d60061fd26bd8cba63a12b56b22056eKeisuke Kuroyanagi        const PtNodeParams *const toBeUpdatedPtNodeParams,
1486bf268132d60061fd26bd8cba63a12b56b22056eKeisuke Kuroyanagi        const UnigramProperty *const unigramProperty) {
1496bf268132d60061fd26bd8cba63a12b56b22056eKeisuke Kuroyanagi    // Update probability and historical information.
1506bf268132d60061fd26bd8cba63a12b56b22056eKeisuke Kuroyanagi    // TODO: Update other information in the unigram property.
1516bf268132d60061fd26bd8cba63a12b56b22056eKeisuke Kuroyanagi    if (!toBeUpdatedPtNodeParams->isTerminal()) {
1526bf268132d60061fd26bd8cba63a12b56b22056eKeisuke Kuroyanagi        return false;
1536bf268132d60061fd26bd8cba63a12b56b22056eKeisuke Kuroyanagi    }
1546bf268132d60061fd26bd8cba63a12b56b22056eKeisuke Kuroyanagi    const ProbabilityEntry originalProbabilityEntry =
1556bf268132d60061fd26bd8cba63a12b56b22056eKeisuke Kuroyanagi            mBuffers->getProbabilityDictContent()->getProbabilityEntry(
1566bf268132d60061fd26bd8cba63a12b56b22056eKeisuke Kuroyanagi                    toBeUpdatedPtNodeParams->getTerminalId());
1576bf268132d60061fd26bd8cba63a12b56b22056eKeisuke Kuroyanagi    const ProbabilityEntry probabilityEntry = createUpdatedEntryFrom(&originalProbabilityEntry,
1586bf268132d60061fd26bd8cba63a12b56b22056eKeisuke Kuroyanagi            unigramProperty);
1596bf268132d60061fd26bd8cba63a12b56b22056eKeisuke Kuroyanagi    return mBuffers->getMutableProbabilityDictContent()->setProbabilityEntry(
1606bf268132d60061fd26bd8cba63a12b56b22056eKeisuke Kuroyanagi            toBeUpdatedPtNodeParams->getTerminalId(), &probabilityEntry);
1616bf268132d60061fd26bd8cba63a12b56b22056eKeisuke Kuroyanagi}
1626bf268132d60061fd26bd8cba63a12b56b22056eKeisuke Kuroyanagi
1636bf268132d60061fd26bd8cba63a12b56b22056eKeisuke Kuroyanagibool Ver4PatriciaTrieNodeWriter::updatePtNodeProbabilityAndGetNeedsToKeepPtNodeAfterGC(
1646bf268132d60061fd26bd8cba63a12b56b22056eKeisuke Kuroyanagi        const PtNodeParams *const toBeUpdatedPtNodeParams, bool *const outNeedsToKeepPtNode) {
1656bf268132d60061fd26bd8cba63a12b56b22056eKeisuke Kuroyanagi    if (!toBeUpdatedPtNodeParams->isTerminal()) {
1666bf268132d60061fd26bd8cba63a12b56b22056eKeisuke Kuroyanagi        AKLOGE("updatePtNodeProbabilityAndGetNeedsToSaveForGC is called for non-terminal PtNode.");
1676bf268132d60061fd26bd8cba63a12b56b22056eKeisuke Kuroyanagi        return false;
1686bf268132d60061fd26bd8cba63a12b56b22056eKeisuke Kuroyanagi    }
1696bf268132d60061fd26bd8cba63a12b56b22056eKeisuke Kuroyanagi    const ProbabilityEntry originalProbabilityEntry =
1706bf268132d60061fd26bd8cba63a12b56b22056eKeisuke Kuroyanagi            mBuffers->getProbabilityDictContent()->getProbabilityEntry(
1716bf268132d60061fd26bd8cba63a12b56b22056eKeisuke Kuroyanagi                    toBeUpdatedPtNodeParams->getTerminalId());
1726bf268132d60061fd26bd8cba63a12b56b22056eKeisuke Kuroyanagi    if (originalProbabilityEntry.hasHistoricalInfo()) {
1736bf268132d60061fd26bd8cba63a12b56b22056eKeisuke Kuroyanagi        const HistoricalInfo historicalInfo = ForgettingCurveUtils::createHistoricalInfoToSave(
1746bf268132d60061fd26bd8cba63a12b56b22056eKeisuke Kuroyanagi                originalProbabilityEntry.getHistoricalInfo(), mHeaderPolicy);
1756bf268132d60061fd26bd8cba63a12b56b22056eKeisuke Kuroyanagi        const ProbabilityEntry probabilityEntry =
1766bf268132d60061fd26bd8cba63a12b56b22056eKeisuke Kuroyanagi                originalProbabilityEntry.createEntryWithUpdatedHistoricalInfo(&historicalInfo);
1776bf268132d60061fd26bd8cba63a12b56b22056eKeisuke Kuroyanagi        if (!mBuffers->getMutableProbabilityDictContent()->setProbabilityEntry(
1786bf268132d60061fd26bd8cba63a12b56b22056eKeisuke Kuroyanagi                toBeUpdatedPtNodeParams->getTerminalId(), &probabilityEntry)) {
1796bf268132d60061fd26bd8cba63a12b56b22056eKeisuke Kuroyanagi            AKLOGE("Cannot write updated probability entry. terminalId: %d",
1806bf268132d60061fd26bd8cba63a12b56b22056eKeisuke Kuroyanagi                    toBeUpdatedPtNodeParams->getTerminalId());
1816bf268132d60061fd26bd8cba63a12b56b22056eKeisuke Kuroyanagi            return false;
1826bf268132d60061fd26bd8cba63a12b56b22056eKeisuke Kuroyanagi        }
1836bf268132d60061fd26bd8cba63a12b56b22056eKeisuke Kuroyanagi        const bool isValid = ForgettingCurveUtils::needsToKeep(&historicalInfo, mHeaderPolicy);
1846bf268132d60061fd26bd8cba63a12b56b22056eKeisuke Kuroyanagi        if (!isValid) {
1856bf268132d60061fd26bd8cba63a12b56b22056eKeisuke Kuroyanagi            if (!markPtNodeAsWillBecomeNonTerminal(toBeUpdatedPtNodeParams)) {
1866bf268132d60061fd26bd8cba63a12b56b22056eKeisuke Kuroyanagi                AKLOGE("Cannot mark PtNode as willBecomeNonTerminal.");
1876bf268132d60061fd26bd8cba63a12b56b22056eKeisuke Kuroyanagi                return false;
1886bf268132d60061fd26bd8cba63a12b56b22056eKeisuke Kuroyanagi            }
1896bf268132d60061fd26bd8cba63a12b56b22056eKeisuke Kuroyanagi        }
1906bf268132d60061fd26bd8cba63a12b56b22056eKeisuke Kuroyanagi        *outNeedsToKeepPtNode = isValid;
1916bf268132d60061fd26bd8cba63a12b56b22056eKeisuke Kuroyanagi    } else {
1926bf268132d60061fd26bd8cba63a12b56b22056eKeisuke Kuroyanagi        // No need to update probability.
1936bf268132d60061fd26bd8cba63a12b56b22056eKeisuke Kuroyanagi        *outNeedsToKeepPtNode = true;
1946bf268132d60061fd26bd8cba63a12b56b22056eKeisuke Kuroyanagi    }
1956bf268132d60061fd26bd8cba63a12b56b22056eKeisuke Kuroyanagi    return true;
1966bf268132d60061fd26bd8cba63a12b56b22056eKeisuke Kuroyanagi}
1976bf268132d60061fd26bd8cba63a12b56b22056eKeisuke Kuroyanagi
1986bf268132d60061fd26bd8cba63a12b56b22056eKeisuke Kuroyanagibool Ver4PatriciaTrieNodeWriter::updateChildrenPosition(
1996bf268132d60061fd26bd8cba63a12b56b22056eKeisuke Kuroyanagi        const PtNodeParams *const toBeUpdatedPtNodeParams, const int newChildrenPosition) {
2006bf268132d60061fd26bd8cba63a12b56b22056eKeisuke Kuroyanagi    int childrenPosFieldPos = toBeUpdatedPtNodeParams->getChildrenPosFieldPos();
2016bf268132d60061fd26bd8cba63a12b56b22056eKeisuke Kuroyanagi    return DynamicPtWritingUtils::writeChildrenPositionAndAdvancePosition(mTrieBuffer,
2026bf268132d60061fd26bd8cba63a12b56b22056eKeisuke Kuroyanagi            newChildrenPosition, &childrenPosFieldPos);
2036bf268132d60061fd26bd8cba63a12b56b22056eKeisuke Kuroyanagi}
2046bf268132d60061fd26bd8cba63a12b56b22056eKeisuke Kuroyanagi
2056bf268132d60061fd26bd8cba63a12b56b22056eKeisuke Kuroyanagibool Ver4PatriciaTrieNodeWriter::updateTerminalId(const PtNodeParams *const toBeUpdatedPtNodeParams,
2066bf268132d60061fd26bd8cba63a12b56b22056eKeisuke Kuroyanagi        const int newTerminalId) {
2076bf268132d60061fd26bd8cba63a12b56b22056eKeisuke Kuroyanagi    return mTrieBuffer->writeUint(newTerminalId, Ver4DictConstants::TERMINAL_ID_FIELD_SIZE,
2086bf268132d60061fd26bd8cba63a12b56b22056eKeisuke Kuroyanagi            toBeUpdatedPtNodeParams->getTerminalIdFieldPos());
2096bf268132d60061fd26bd8cba63a12b56b22056eKeisuke Kuroyanagi}
2106bf268132d60061fd26bd8cba63a12b56b22056eKeisuke Kuroyanagi
2116bf268132d60061fd26bd8cba63a12b56b22056eKeisuke Kuroyanagibool Ver4PatriciaTrieNodeWriter::writePtNodeAndAdvancePosition(
2126bf268132d60061fd26bd8cba63a12b56b22056eKeisuke Kuroyanagi        const PtNodeParams *const ptNodeParams, int *const ptNodeWritingPos) {
2136bf268132d60061fd26bd8cba63a12b56b22056eKeisuke Kuroyanagi    return writePtNodeAndGetTerminalIdAndAdvancePosition(ptNodeParams, 0 /* outTerminalId */,
2146bf268132d60061fd26bd8cba63a12b56b22056eKeisuke Kuroyanagi            ptNodeWritingPos);
2156bf268132d60061fd26bd8cba63a12b56b22056eKeisuke Kuroyanagi}
2166bf268132d60061fd26bd8cba63a12b56b22056eKeisuke Kuroyanagi
2176bf268132d60061fd26bd8cba63a12b56b22056eKeisuke Kuroyanagi
2186bf268132d60061fd26bd8cba63a12b56b22056eKeisuke Kuroyanagibool Ver4PatriciaTrieNodeWriter::writeNewTerminalPtNodeAndAdvancePosition(
2196bf268132d60061fd26bd8cba63a12b56b22056eKeisuke Kuroyanagi        const PtNodeParams *const ptNodeParams, const UnigramProperty *const unigramProperty,
2206bf268132d60061fd26bd8cba63a12b56b22056eKeisuke Kuroyanagi        int *const ptNodeWritingPos) {
2216bf268132d60061fd26bd8cba63a12b56b22056eKeisuke Kuroyanagi    int terminalId = Ver4DictConstants::NOT_A_TERMINAL_ID;
2226bf268132d60061fd26bd8cba63a12b56b22056eKeisuke Kuroyanagi    if (!writePtNodeAndGetTerminalIdAndAdvancePosition(ptNodeParams, &terminalId,
2236bf268132d60061fd26bd8cba63a12b56b22056eKeisuke Kuroyanagi            ptNodeWritingPos)) {
2246bf268132d60061fd26bd8cba63a12b56b22056eKeisuke Kuroyanagi        return false;
2256bf268132d60061fd26bd8cba63a12b56b22056eKeisuke Kuroyanagi    }
2266bf268132d60061fd26bd8cba63a12b56b22056eKeisuke Kuroyanagi    // Write probability.
2276bf268132d60061fd26bd8cba63a12b56b22056eKeisuke Kuroyanagi    ProbabilityEntry newProbabilityEntry;
2286bf268132d60061fd26bd8cba63a12b56b22056eKeisuke Kuroyanagi    const ProbabilityEntry probabilityEntryToWrite = createUpdatedEntryFrom(
2296bf268132d60061fd26bd8cba63a12b56b22056eKeisuke Kuroyanagi            &newProbabilityEntry, unigramProperty);
2306bf268132d60061fd26bd8cba63a12b56b22056eKeisuke Kuroyanagi    return mBuffers->getMutableProbabilityDictContent()->setProbabilityEntry(terminalId,
2316bf268132d60061fd26bd8cba63a12b56b22056eKeisuke Kuroyanagi            &probabilityEntryToWrite);
2326bf268132d60061fd26bd8cba63a12b56b22056eKeisuke Kuroyanagi}
2336bf268132d60061fd26bd8cba63a12b56b22056eKeisuke Kuroyanagi
2346bf268132d60061fd26bd8cba63a12b56b22056eKeisuke Kuroyanagibool Ver4PatriciaTrieNodeWriter::addNewBigramEntry(
2356bf268132d60061fd26bd8cba63a12b56b22056eKeisuke Kuroyanagi        const PtNodeParams *const sourcePtNodeParams, const PtNodeParams *const targetPtNodeParam,
2366bf268132d60061fd26bd8cba63a12b56b22056eKeisuke Kuroyanagi        const BigramProperty *const bigramProperty, bool *const outAddedNewBigram) {
2376bf268132d60061fd26bd8cba63a12b56b22056eKeisuke Kuroyanagi    if (!mBigramPolicy->addNewEntry(sourcePtNodeParams->getTerminalId(),
2386bf268132d60061fd26bd8cba63a12b56b22056eKeisuke Kuroyanagi            targetPtNodeParam->getTerminalId(), bigramProperty, outAddedNewBigram)) {
2396bf268132d60061fd26bd8cba63a12b56b22056eKeisuke Kuroyanagi        AKLOGE("Cannot add new bigram entry. terminalId: %d, targetTerminalId: %d",
2406bf268132d60061fd26bd8cba63a12b56b22056eKeisuke Kuroyanagi                sourcePtNodeParams->getTerminalId(), targetPtNodeParam->getTerminalId());
2416bf268132d60061fd26bd8cba63a12b56b22056eKeisuke Kuroyanagi        return false;
2426bf268132d60061fd26bd8cba63a12b56b22056eKeisuke Kuroyanagi    }
2436bf268132d60061fd26bd8cba63a12b56b22056eKeisuke Kuroyanagi    if (!sourcePtNodeParams->hasBigrams()) {
2446bf268132d60061fd26bd8cba63a12b56b22056eKeisuke Kuroyanagi        // Update has bigrams flag.
2456bf268132d60061fd26bd8cba63a12b56b22056eKeisuke Kuroyanagi        return updatePtNodeFlags(sourcePtNodeParams->getHeadPos(),
2466bf268132d60061fd26bd8cba63a12b56b22056eKeisuke Kuroyanagi                sourcePtNodeParams->isBlacklisted(), sourcePtNodeParams->isNotAWord(),
2476bf268132d60061fd26bd8cba63a12b56b22056eKeisuke Kuroyanagi                sourcePtNodeParams->isTerminal(), sourcePtNodeParams->hasShortcutTargets(),
2486bf268132d60061fd26bd8cba63a12b56b22056eKeisuke Kuroyanagi                true /* hasBigrams */,
2496bf268132d60061fd26bd8cba63a12b56b22056eKeisuke Kuroyanagi                sourcePtNodeParams->getCodePointCount() > 1 /* hasMultipleChars */);
2506bf268132d60061fd26bd8cba63a12b56b22056eKeisuke Kuroyanagi    }
2516bf268132d60061fd26bd8cba63a12b56b22056eKeisuke Kuroyanagi    return true;
2526bf268132d60061fd26bd8cba63a12b56b22056eKeisuke Kuroyanagi}
2536bf268132d60061fd26bd8cba63a12b56b22056eKeisuke Kuroyanagi
2546bf268132d60061fd26bd8cba63a12b56b22056eKeisuke Kuroyanagibool Ver4PatriciaTrieNodeWriter::removeBigramEntry(
2556bf268132d60061fd26bd8cba63a12b56b22056eKeisuke Kuroyanagi        const PtNodeParams *const sourcePtNodeParams, const PtNodeParams *const targetPtNodeParam) {
2566bf268132d60061fd26bd8cba63a12b56b22056eKeisuke Kuroyanagi    return mBigramPolicy->removeEntry(sourcePtNodeParams->getTerminalId(),
2576bf268132d60061fd26bd8cba63a12b56b22056eKeisuke Kuroyanagi            targetPtNodeParam->getTerminalId());
2586bf268132d60061fd26bd8cba63a12b56b22056eKeisuke Kuroyanagi}
2596bf268132d60061fd26bd8cba63a12b56b22056eKeisuke Kuroyanagi
2606bf268132d60061fd26bd8cba63a12b56b22056eKeisuke Kuroyanagibool Ver4PatriciaTrieNodeWriter::updateAllBigramEntriesAndDeleteUselessEntries(
2616bf268132d60061fd26bd8cba63a12b56b22056eKeisuke Kuroyanagi            const PtNodeParams *const sourcePtNodeParams, int *const outBigramEntryCount) {
2626bf268132d60061fd26bd8cba63a12b56b22056eKeisuke Kuroyanagi    return mBigramPolicy->updateAllBigramEntriesAndDeleteUselessEntries(
2636bf268132d60061fd26bd8cba63a12b56b22056eKeisuke Kuroyanagi            sourcePtNodeParams->getTerminalId(), outBigramEntryCount);
2646bf268132d60061fd26bd8cba63a12b56b22056eKeisuke Kuroyanagi}
2656bf268132d60061fd26bd8cba63a12b56b22056eKeisuke Kuroyanagi
2666bf268132d60061fd26bd8cba63a12b56b22056eKeisuke Kuroyanagibool Ver4PatriciaTrieNodeWriter::updateAllPositionFields(
2676bf268132d60061fd26bd8cba63a12b56b22056eKeisuke Kuroyanagi        const PtNodeParams *const toBeUpdatedPtNodeParams,
2686bf268132d60061fd26bd8cba63a12b56b22056eKeisuke Kuroyanagi        const DictPositionRelocationMap *const dictPositionRelocationMap,
2696bf268132d60061fd26bd8cba63a12b56b22056eKeisuke Kuroyanagi        int *const outBigramEntryCount) {
2706bf268132d60061fd26bd8cba63a12b56b22056eKeisuke Kuroyanagi    int parentPos = toBeUpdatedPtNodeParams->getParentPos();
2716bf268132d60061fd26bd8cba63a12b56b22056eKeisuke Kuroyanagi    if (parentPos != NOT_A_DICT_POS) {
2726bf268132d60061fd26bd8cba63a12b56b22056eKeisuke Kuroyanagi        PtNodeWriter::PtNodePositionRelocationMap::const_iterator it =
2736bf268132d60061fd26bd8cba63a12b56b22056eKeisuke Kuroyanagi                dictPositionRelocationMap->mPtNodePositionRelocationMap.find(parentPos);
2746bf268132d60061fd26bd8cba63a12b56b22056eKeisuke Kuroyanagi        if (it != dictPositionRelocationMap->mPtNodePositionRelocationMap.end()) {
2756bf268132d60061fd26bd8cba63a12b56b22056eKeisuke Kuroyanagi            parentPos = it->second;
2766bf268132d60061fd26bd8cba63a12b56b22056eKeisuke Kuroyanagi        }
2776bf268132d60061fd26bd8cba63a12b56b22056eKeisuke Kuroyanagi    }
2786bf268132d60061fd26bd8cba63a12b56b22056eKeisuke Kuroyanagi    int writingPos = toBeUpdatedPtNodeParams->getHeadPos()
2796bf268132d60061fd26bd8cba63a12b56b22056eKeisuke Kuroyanagi            + DynamicPtWritingUtils::NODE_FLAG_FIELD_SIZE;
2806bf268132d60061fd26bd8cba63a12b56b22056eKeisuke Kuroyanagi    // Write updated parent offset.
2816bf268132d60061fd26bd8cba63a12b56b22056eKeisuke Kuroyanagi    if (!DynamicPtWritingUtils::writeParentPosOffsetAndAdvancePosition(mTrieBuffer,
2826bf268132d60061fd26bd8cba63a12b56b22056eKeisuke Kuroyanagi            parentPos, toBeUpdatedPtNodeParams->getHeadPos(), &writingPos)) {
2836bf268132d60061fd26bd8cba63a12b56b22056eKeisuke Kuroyanagi        return false;
2846bf268132d60061fd26bd8cba63a12b56b22056eKeisuke Kuroyanagi    }
2856bf268132d60061fd26bd8cba63a12b56b22056eKeisuke Kuroyanagi
2866bf268132d60061fd26bd8cba63a12b56b22056eKeisuke Kuroyanagi    // Updates children position.
2876bf268132d60061fd26bd8cba63a12b56b22056eKeisuke Kuroyanagi    int childrenPos = toBeUpdatedPtNodeParams->getChildrenPos();
2886bf268132d60061fd26bd8cba63a12b56b22056eKeisuke Kuroyanagi    if (childrenPos != NOT_A_DICT_POS) {
2896bf268132d60061fd26bd8cba63a12b56b22056eKeisuke Kuroyanagi        PtNodeWriter::PtNodeArrayPositionRelocationMap::const_iterator it =
2906bf268132d60061fd26bd8cba63a12b56b22056eKeisuke Kuroyanagi                dictPositionRelocationMap->mPtNodeArrayPositionRelocationMap.find(childrenPos);
2916bf268132d60061fd26bd8cba63a12b56b22056eKeisuke Kuroyanagi        if (it != dictPositionRelocationMap->mPtNodeArrayPositionRelocationMap.end()) {
2926bf268132d60061fd26bd8cba63a12b56b22056eKeisuke Kuroyanagi            childrenPos = it->second;
2936bf268132d60061fd26bd8cba63a12b56b22056eKeisuke Kuroyanagi        }
2946bf268132d60061fd26bd8cba63a12b56b22056eKeisuke Kuroyanagi    }
2956bf268132d60061fd26bd8cba63a12b56b22056eKeisuke Kuroyanagi    if (!updateChildrenPosition(toBeUpdatedPtNodeParams, childrenPos)) {
2966bf268132d60061fd26bd8cba63a12b56b22056eKeisuke Kuroyanagi        return false;
2976bf268132d60061fd26bd8cba63a12b56b22056eKeisuke Kuroyanagi    }
2986bf268132d60061fd26bd8cba63a12b56b22056eKeisuke Kuroyanagi
2996bf268132d60061fd26bd8cba63a12b56b22056eKeisuke Kuroyanagi    // Counts bigram entries.
3006bf268132d60061fd26bd8cba63a12b56b22056eKeisuke Kuroyanagi    if (outBigramEntryCount) {
3016bf268132d60061fd26bd8cba63a12b56b22056eKeisuke Kuroyanagi        *outBigramEntryCount = mBigramPolicy->getBigramEntryConut(
3026bf268132d60061fd26bd8cba63a12b56b22056eKeisuke Kuroyanagi                toBeUpdatedPtNodeParams->getTerminalId());
3036bf268132d60061fd26bd8cba63a12b56b22056eKeisuke Kuroyanagi    }
3046bf268132d60061fd26bd8cba63a12b56b22056eKeisuke Kuroyanagi    return true;
3056bf268132d60061fd26bd8cba63a12b56b22056eKeisuke Kuroyanagi}
3066bf268132d60061fd26bd8cba63a12b56b22056eKeisuke Kuroyanagi
3076bf268132d60061fd26bd8cba63a12b56b22056eKeisuke Kuroyanagibool Ver4PatriciaTrieNodeWriter::addShortcutTarget(const PtNodeParams *const ptNodeParams,
3086bf268132d60061fd26bd8cba63a12b56b22056eKeisuke Kuroyanagi        const int *const targetCodePoints, const int targetCodePointCount,
3096bf268132d60061fd26bd8cba63a12b56b22056eKeisuke Kuroyanagi        const int shortcutProbability) {
3106bf268132d60061fd26bd8cba63a12b56b22056eKeisuke Kuroyanagi    if (!mShortcutPolicy->addNewShortcut(ptNodeParams->getTerminalId(),
3116bf268132d60061fd26bd8cba63a12b56b22056eKeisuke Kuroyanagi            targetCodePoints, targetCodePointCount, shortcutProbability)) {
3126bf268132d60061fd26bd8cba63a12b56b22056eKeisuke Kuroyanagi        AKLOGE("Cannot add new shortuct entry. terminalId: %d", ptNodeParams->getTerminalId());
3136bf268132d60061fd26bd8cba63a12b56b22056eKeisuke Kuroyanagi        return false;
3146bf268132d60061fd26bd8cba63a12b56b22056eKeisuke Kuroyanagi    }
3156bf268132d60061fd26bd8cba63a12b56b22056eKeisuke Kuroyanagi    if (!ptNodeParams->hasShortcutTargets()) {
3166bf268132d60061fd26bd8cba63a12b56b22056eKeisuke Kuroyanagi        // Update has shortcut targets flag.
3176bf268132d60061fd26bd8cba63a12b56b22056eKeisuke Kuroyanagi        return updatePtNodeFlags(ptNodeParams->getHeadPos(),
3186bf268132d60061fd26bd8cba63a12b56b22056eKeisuke Kuroyanagi                ptNodeParams->isBlacklisted(), ptNodeParams->isNotAWord(),
3196bf268132d60061fd26bd8cba63a12b56b22056eKeisuke Kuroyanagi                ptNodeParams->isTerminal(), true /* hasShortcutTargets */,
3206bf268132d60061fd26bd8cba63a12b56b22056eKeisuke Kuroyanagi                ptNodeParams->hasBigrams(),
3216bf268132d60061fd26bd8cba63a12b56b22056eKeisuke Kuroyanagi                ptNodeParams->getCodePointCount() > 1 /* hasMultipleChars */);
3226bf268132d60061fd26bd8cba63a12b56b22056eKeisuke Kuroyanagi    }
3236bf268132d60061fd26bd8cba63a12b56b22056eKeisuke Kuroyanagi    return true;
3246bf268132d60061fd26bd8cba63a12b56b22056eKeisuke Kuroyanagi}
3256bf268132d60061fd26bd8cba63a12b56b22056eKeisuke Kuroyanagi
3266bf268132d60061fd26bd8cba63a12b56b22056eKeisuke Kuroyanagibool Ver4PatriciaTrieNodeWriter::updatePtNodeHasBigramsAndShortcutTargetsFlags(
3276bf268132d60061fd26bd8cba63a12b56b22056eKeisuke Kuroyanagi        const PtNodeParams *const ptNodeParams) {
3286bf268132d60061fd26bd8cba63a12b56b22056eKeisuke Kuroyanagi    const bool hasBigrams = mBuffers->getBigramDictContent()->getBigramListHeadPos(
3296bf268132d60061fd26bd8cba63a12b56b22056eKeisuke Kuroyanagi            ptNodeParams->getTerminalId()) != NOT_A_DICT_POS;
3306bf268132d60061fd26bd8cba63a12b56b22056eKeisuke Kuroyanagi    const bool hasShortcutTargets = mBuffers->getShortcutDictContent()->getShortcutListHeadPos(
3316bf268132d60061fd26bd8cba63a12b56b22056eKeisuke Kuroyanagi            ptNodeParams->getTerminalId()) != NOT_A_DICT_POS;
3326bf268132d60061fd26bd8cba63a12b56b22056eKeisuke Kuroyanagi    return updatePtNodeFlags(ptNodeParams->getHeadPos(), ptNodeParams->isBlacklisted(),
3336bf268132d60061fd26bd8cba63a12b56b22056eKeisuke Kuroyanagi            ptNodeParams->isNotAWord(), ptNodeParams->isTerminal(), hasShortcutTargets,
3346bf268132d60061fd26bd8cba63a12b56b22056eKeisuke Kuroyanagi            hasBigrams, ptNodeParams->getCodePointCount() > 1 /* hasMultipleChars */);
3356bf268132d60061fd26bd8cba63a12b56b22056eKeisuke Kuroyanagi}
3366bf268132d60061fd26bd8cba63a12b56b22056eKeisuke Kuroyanagi
3376bf268132d60061fd26bd8cba63a12b56b22056eKeisuke Kuroyanagibool Ver4PatriciaTrieNodeWriter::writePtNodeAndGetTerminalIdAndAdvancePosition(
3386bf268132d60061fd26bd8cba63a12b56b22056eKeisuke Kuroyanagi        const PtNodeParams *const ptNodeParams, int *const outTerminalId,
3396bf268132d60061fd26bd8cba63a12b56b22056eKeisuke Kuroyanagi        int *const ptNodeWritingPos) {
3406bf268132d60061fd26bd8cba63a12b56b22056eKeisuke Kuroyanagi    const int nodePos = *ptNodeWritingPos;
3416bf268132d60061fd26bd8cba63a12b56b22056eKeisuke Kuroyanagi    // Write dummy flags. The Node flags are updated with appropriate flags at the last step of the
3426bf268132d60061fd26bd8cba63a12b56b22056eKeisuke Kuroyanagi    // PtNode writing.
3436bf268132d60061fd26bd8cba63a12b56b22056eKeisuke Kuroyanagi    if (!DynamicPtWritingUtils::writeFlagsAndAdvancePosition(mTrieBuffer,
3446bf268132d60061fd26bd8cba63a12b56b22056eKeisuke Kuroyanagi            0 /* nodeFlags */, ptNodeWritingPos)) {
3456bf268132d60061fd26bd8cba63a12b56b22056eKeisuke Kuroyanagi        return false;
3466bf268132d60061fd26bd8cba63a12b56b22056eKeisuke Kuroyanagi    }
3476bf268132d60061fd26bd8cba63a12b56b22056eKeisuke Kuroyanagi    // Calculate a parent offset and write the offset.
3486bf268132d60061fd26bd8cba63a12b56b22056eKeisuke Kuroyanagi    if (!DynamicPtWritingUtils::writeParentPosOffsetAndAdvancePosition(mTrieBuffer,
3496bf268132d60061fd26bd8cba63a12b56b22056eKeisuke Kuroyanagi            ptNodeParams->getParentPos(), nodePos, ptNodeWritingPos)) {
3506bf268132d60061fd26bd8cba63a12b56b22056eKeisuke Kuroyanagi        return false;
3516bf268132d60061fd26bd8cba63a12b56b22056eKeisuke Kuroyanagi    }
3526bf268132d60061fd26bd8cba63a12b56b22056eKeisuke Kuroyanagi    // Write code points
3536bf268132d60061fd26bd8cba63a12b56b22056eKeisuke Kuroyanagi    if (!DynamicPtWritingUtils::writeCodePointsAndAdvancePosition(mTrieBuffer,
3546bf268132d60061fd26bd8cba63a12b56b22056eKeisuke Kuroyanagi            ptNodeParams->getCodePoints(), ptNodeParams->getCodePointCount(), ptNodeWritingPos)) {
3556bf268132d60061fd26bd8cba63a12b56b22056eKeisuke Kuroyanagi        return false;
3566bf268132d60061fd26bd8cba63a12b56b22056eKeisuke Kuroyanagi    }
3576bf268132d60061fd26bd8cba63a12b56b22056eKeisuke Kuroyanagi    int terminalId = Ver4DictConstants::NOT_A_TERMINAL_ID;
3586bf268132d60061fd26bd8cba63a12b56b22056eKeisuke Kuroyanagi    if (!ptNodeParams->willBecomeNonTerminal()) {
3596bf268132d60061fd26bd8cba63a12b56b22056eKeisuke Kuroyanagi        if (ptNodeParams->getTerminalId() != Ver4DictConstants::NOT_A_TERMINAL_ID) {
3606bf268132d60061fd26bd8cba63a12b56b22056eKeisuke Kuroyanagi            terminalId = ptNodeParams->getTerminalId();
3616bf268132d60061fd26bd8cba63a12b56b22056eKeisuke Kuroyanagi        } else if (ptNodeParams->isTerminal()) {
3626bf268132d60061fd26bd8cba63a12b56b22056eKeisuke Kuroyanagi            // Write terminal information using a new terminal id.
3636bf268132d60061fd26bd8cba63a12b56b22056eKeisuke Kuroyanagi            // Get a new unused terminal id.
3646bf268132d60061fd26bd8cba63a12b56b22056eKeisuke Kuroyanagi            terminalId = mBuffers->getTerminalPositionLookupTable()->getNextTerminalId();
3656bf268132d60061fd26bd8cba63a12b56b22056eKeisuke Kuroyanagi        }
3666bf268132d60061fd26bd8cba63a12b56b22056eKeisuke Kuroyanagi    }
3676bf268132d60061fd26bd8cba63a12b56b22056eKeisuke Kuroyanagi    const int isTerminal = terminalId != Ver4DictConstants::NOT_A_TERMINAL_ID;
3686bf268132d60061fd26bd8cba63a12b56b22056eKeisuke Kuroyanagi    if (isTerminal) {
3696bf268132d60061fd26bd8cba63a12b56b22056eKeisuke Kuroyanagi        // Update the lookup table.
3706bf268132d60061fd26bd8cba63a12b56b22056eKeisuke Kuroyanagi        if (!mBuffers->getMutableTerminalPositionLookupTable()->setTerminalPtNodePosition(
3716bf268132d60061fd26bd8cba63a12b56b22056eKeisuke Kuroyanagi                terminalId, nodePos)) {
3726bf268132d60061fd26bd8cba63a12b56b22056eKeisuke Kuroyanagi            return false;
3736bf268132d60061fd26bd8cba63a12b56b22056eKeisuke Kuroyanagi        }
3746bf268132d60061fd26bd8cba63a12b56b22056eKeisuke Kuroyanagi        // Write terminal Id.
3756bf268132d60061fd26bd8cba63a12b56b22056eKeisuke Kuroyanagi        if (!mTrieBuffer->writeUintAndAdvancePosition(terminalId,
3766bf268132d60061fd26bd8cba63a12b56b22056eKeisuke Kuroyanagi                Ver4DictConstants::TERMINAL_ID_FIELD_SIZE, ptNodeWritingPos)) {
3776bf268132d60061fd26bd8cba63a12b56b22056eKeisuke Kuroyanagi            return false;
3786bf268132d60061fd26bd8cba63a12b56b22056eKeisuke Kuroyanagi        }
3796bf268132d60061fd26bd8cba63a12b56b22056eKeisuke Kuroyanagi        if (outTerminalId) {
3806bf268132d60061fd26bd8cba63a12b56b22056eKeisuke Kuroyanagi            *outTerminalId = terminalId;
3816bf268132d60061fd26bd8cba63a12b56b22056eKeisuke Kuroyanagi        }
3826bf268132d60061fd26bd8cba63a12b56b22056eKeisuke Kuroyanagi    }
3836bf268132d60061fd26bd8cba63a12b56b22056eKeisuke Kuroyanagi    // Write children position
3846bf268132d60061fd26bd8cba63a12b56b22056eKeisuke Kuroyanagi    if (!DynamicPtWritingUtils::writeChildrenPositionAndAdvancePosition(mTrieBuffer,
3856bf268132d60061fd26bd8cba63a12b56b22056eKeisuke Kuroyanagi            ptNodeParams->getChildrenPos(), ptNodeWritingPos)) {
3866bf268132d60061fd26bd8cba63a12b56b22056eKeisuke Kuroyanagi        return false;
3876bf268132d60061fd26bd8cba63a12b56b22056eKeisuke Kuroyanagi    }
3886bf268132d60061fd26bd8cba63a12b56b22056eKeisuke Kuroyanagi    return updatePtNodeFlags(nodePos, ptNodeParams->isBlacklisted(), ptNodeParams->isNotAWord(),
3896bf268132d60061fd26bd8cba63a12b56b22056eKeisuke Kuroyanagi            isTerminal, ptNodeParams->hasShortcutTargets(), ptNodeParams->hasBigrams(),
3906bf268132d60061fd26bd8cba63a12b56b22056eKeisuke Kuroyanagi            ptNodeParams->getCodePointCount() > 1 /* hasMultipleChars */);
3916bf268132d60061fd26bd8cba63a12b56b22056eKeisuke Kuroyanagi}
3926bf268132d60061fd26bd8cba63a12b56b22056eKeisuke Kuroyanagi
3936bf268132d60061fd26bd8cba63a12b56b22056eKeisuke Kuroyanagiconst ProbabilityEntry Ver4PatriciaTrieNodeWriter::createUpdatedEntryFrom(
3946bf268132d60061fd26bd8cba63a12b56b22056eKeisuke Kuroyanagi        const ProbabilityEntry *const originalProbabilityEntry,
3956bf268132d60061fd26bd8cba63a12b56b22056eKeisuke Kuroyanagi        const UnigramProperty *const unigramProperty) const {
3966bf268132d60061fd26bd8cba63a12b56b22056eKeisuke Kuroyanagi    // TODO: Consolidate historical info and probability.
3976bf268132d60061fd26bd8cba63a12b56b22056eKeisuke Kuroyanagi    if (mHeaderPolicy->hasHistoricalInfoOfWords()) {
3986bf268132d60061fd26bd8cba63a12b56b22056eKeisuke Kuroyanagi        const HistoricalInfo historicalInfoForUpdate(unigramProperty->getTimestamp(),
3996bf268132d60061fd26bd8cba63a12b56b22056eKeisuke Kuroyanagi                unigramProperty->getLevel(), unigramProperty->getCount());
4006bf268132d60061fd26bd8cba63a12b56b22056eKeisuke Kuroyanagi        const HistoricalInfo updatedHistoricalInfo =
4016bf268132d60061fd26bd8cba63a12b56b22056eKeisuke Kuroyanagi                ForgettingCurveUtils::createUpdatedHistoricalInfo(
4026bf268132d60061fd26bd8cba63a12b56b22056eKeisuke Kuroyanagi                        originalProbabilityEntry->getHistoricalInfo(),
4036bf268132d60061fd26bd8cba63a12b56b22056eKeisuke Kuroyanagi                        unigramProperty->getProbability(), &historicalInfoForUpdate, mHeaderPolicy);
4046bf268132d60061fd26bd8cba63a12b56b22056eKeisuke Kuroyanagi        return originalProbabilityEntry->createEntryWithUpdatedHistoricalInfo(
4056bf268132d60061fd26bd8cba63a12b56b22056eKeisuke Kuroyanagi                &updatedHistoricalInfo);
4066bf268132d60061fd26bd8cba63a12b56b22056eKeisuke Kuroyanagi    } else {
4076bf268132d60061fd26bd8cba63a12b56b22056eKeisuke Kuroyanagi        return originalProbabilityEntry->createEntryWithUpdatedProbability(
4086bf268132d60061fd26bd8cba63a12b56b22056eKeisuke Kuroyanagi                unigramProperty->getProbability());
4096bf268132d60061fd26bd8cba63a12b56b22056eKeisuke Kuroyanagi    }
4106bf268132d60061fd26bd8cba63a12b56b22056eKeisuke Kuroyanagi}
4116bf268132d60061fd26bd8cba63a12b56b22056eKeisuke Kuroyanagi
4126bf268132d60061fd26bd8cba63a12b56b22056eKeisuke Kuroyanagibool Ver4PatriciaTrieNodeWriter::updatePtNodeFlags(const int ptNodePos,
4136bf268132d60061fd26bd8cba63a12b56b22056eKeisuke Kuroyanagi        const bool isBlacklisted, const bool isNotAWord, const bool isTerminal,
4146bf268132d60061fd26bd8cba63a12b56b22056eKeisuke Kuroyanagi        const bool hasShortcutTargets, const bool hasBigrams, const bool hasMultipleChars) {
4156bf268132d60061fd26bd8cba63a12b56b22056eKeisuke Kuroyanagi    // Create node flags and write them.
4166bf268132d60061fd26bd8cba63a12b56b22056eKeisuke Kuroyanagi    PatriciaTrieReadingUtils::NodeFlags nodeFlags =
4176bf268132d60061fd26bd8cba63a12b56b22056eKeisuke Kuroyanagi            PatriciaTrieReadingUtils::createAndGetFlags(isBlacklisted, isNotAWord, isTerminal,
4186bf268132d60061fd26bd8cba63a12b56b22056eKeisuke Kuroyanagi                    hasShortcutTargets, hasBigrams, hasMultipleChars,
4196bf268132d60061fd26bd8cba63a12b56b22056eKeisuke Kuroyanagi                    CHILDREN_POSITION_FIELD_SIZE);
4206bf268132d60061fd26bd8cba63a12b56b22056eKeisuke Kuroyanagi    if (!DynamicPtWritingUtils::writeFlags(mTrieBuffer, nodeFlags, ptNodePos)) {
4216bf268132d60061fd26bd8cba63a12b56b22056eKeisuke Kuroyanagi        AKLOGE("Cannot write PtNode flags. flags: %x, pos: %d", nodeFlags, ptNodePos);
4226bf268132d60061fd26bd8cba63a12b56b22056eKeisuke Kuroyanagi        return false;
4236bf268132d60061fd26bd8cba63a12b56b22056eKeisuke Kuroyanagi    }
4246bf268132d60061fd26bd8cba63a12b56b22056eKeisuke Kuroyanagi    return true;
4256bf268132d60061fd26bd8cba63a12b56b22056eKeisuke Kuroyanagi}
4266bf268132d60061fd26bd8cba63a12b56b22056eKeisuke Kuroyanagi
4276bf268132d60061fd26bd8cba63a12b56b22056eKeisuke Kuroyanagi} // namespace v401
4286bf268132d60061fd26bd8cba63a12b56b22056eKeisuke Kuroyanagi} // namespace backward
4296bf268132d60061fd26bd8cba63a12b56b22056eKeisuke Kuroyanagi} // namespace latinime
430