ver4_patricia_trie_node_writer.cpp revision d0d0113983f000fadc9da89271200620330b0356
12fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa/*
22fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa * Copyright (C) 2013, The Android Open Source Project
32fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa *
42fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa * Licensed under the Apache License, Version 2.0 (the "License");
52fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa * you may not use this file except in compliance with the License.
62fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa * You may obtain a copy of the License at
72fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa *
82fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa *     http://www.apache.org/licenses/LICENSE-2.0
92fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa *
102fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa * Unless required by applicable law or agreed to in writing, software
112fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa * distributed under the License is distributed on an "AS IS" BASIS,
122fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
132fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa * See the License for the specific language governing permissions and
142fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa * limitations under the License.
152fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa */
162fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa
172fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa#include "suggest/policyimpl/dictionary/structure/v4/ver4_patricia_trie_node_writer.h"
182fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa
19b636e25e951e48e071d5348756413d6fc065632dKeisuke Kuroyanagi#include "suggest/core/dictionary/property/unigram_property.h"
202fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa#include "suggest/policyimpl/dictionary/bigram/ver4_bigram_list_policy.h"
212fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa#include "suggest/policyimpl/dictionary/header/header_policy.h"
222fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa#include "suggest/policyimpl/dictionary/shortcut/ver4_shortcut_list_policy.h"
232fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa#include "suggest/policyimpl/dictionary/structure/pt_common/dynamic_pt_reading_utils.h"
242fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa#include "suggest/policyimpl/dictionary/structure/pt_common/dynamic_pt_writing_utils.h"
258dac7ce2e2b56c77e289507625b7695449b2e41aKeisuke Kuroyanagi#include "suggest/policyimpl/dictionary/structure/pt_common/patricia_trie_reading_utils.h"
262fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa#include "suggest/policyimpl/dictionary/structure/v4/content/probability_entry.h"
272fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa#include "suggest/policyimpl/dictionary/structure/v4/ver4_patricia_trie_node_reader.h"
282fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa#include "suggest/policyimpl/dictionary/structure/v4/ver4_dict_buffers.h"
292fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa#include "suggest/policyimpl/dictionary/utils/buffer_with_extendable_buffer.h"
302fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa#include "suggest/policyimpl/dictionary/utils/forgetting_curve_utils.h"
312fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa
322fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasanamespace latinime {
332fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa
342fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasaconst int Ver4PatriciaTrieNodeWriter::CHILDREN_POSITION_FIELD_SIZE = 3;
352fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa
362fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasabool Ver4PatriciaTrieNodeWriter::markPtNodeAsDeleted(
372fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa        const PtNodeParams *const toBeUpdatedPtNodeParams) {
382fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa    int pos = toBeUpdatedPtNodeParams->getHeadPos();
392fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa    const bool usesAdditionalBuffer = mTrieBuffer->isInAdditionalBuffer(pos);
402fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa    const uint8_t *const dictBuf = mTrieBuffer->getBuffer(usesAdditionalBuffer);
412fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa    if (usesAdditionalBuffer) {
422fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa        pos -= mTrieBuffer->getOriginalBufferSize();
432fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa    }
442fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa    // Read original flags
452fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa    const PatriciaTrieReadingUtils::NodeFlags originalFlags =
462fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa            PatriciaTrieReadingUtils::getFlagsAndAdvancePosition(dictBuf, &pos);
472fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa    const PatriciaTrieReadingUtils::NodeFlags updatedFlags =
482fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa            DynamicPtReadingUtils::updateAndGetFlags(originalFlags, false /* isMoved */,
492fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa                    true /* isDeleted */, false /* willBecomeNonTerminal */);
502fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa    int writingPos = toBeUpdatedPtNodeParams->getHeadPos();
512fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa    // Update flags.
522fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa    if (!DynamicPtWritingUtils::writeFlagsAndAdvancePosition(mTrieBuffer, updatedFlags,
532fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa            &writingPos)) {
542fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa        return false;
552fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa    }
562fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa    if (toBeUpdatedPtNodeParams->isTerminal()) {
572fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa        // The PtNode is a terminal. Delete entry from the terminal position lookup table.
582fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa        return mBuffers->getMutableTerminalPositionLookupTable()->setTerminalPtNodePosition(
592fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa                toBeUpdatedPtNodeParams->getTerminalId(), NOT_A_DICT_POS /* ptNodePos */);
602fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa    } else {
612fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa        return true;
622fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa    }
632fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa}
642fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa
652fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasabool Ver4PatriciaTrieNodeWriter::markPtNodeAsMoved(
662fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa        const PtNodeParams *const toBeUpdatedPtNodeParams,
672fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa        const int movedPos, const int bigramLinkedNodePos) {
682fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa    int pos = toBeUpdatedPtNodeParams->getHeadPos();
692fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa    const bool usesAdditionalBuffer = mTrieBuffer->isInAdditionalBuffer(pos);
702fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa    const uint8_t *const dictBuf = mTrieBuffer->getBuffer(usesAdditionalBuffer);
712fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa    if (usesAdditionalBuffer) {
722fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa        pos -= mTrieBuffer->getOriginalBufferSize();
732fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa    }
742fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa    // Read original flags
752fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa    const PatriciaTrieReadingUtils::NodeFlags originalFlags =
762fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa            PatriciaTrieReadingUtils::getFlagsAndAdvancePosition(dictBuf, &pos);
772fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa    const PatriciaTrieReadingUtils::NodeFlags updatedFlags =
782fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa            DynamicPtReadingUtils::updateAndGetFlags(originalFlags, true /* isMoved */,
79d0d0113983f000fadc9da89271200620330b0356Keisuke Kuroyanagi                    false /* isDeleted */, false /* willBecomeNonTerminal */);
802fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa    int writingPos = toBeUpdatedPtNodeParams->getHeadPos();
812fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa    // Update flags.
822fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa    if (!DynamicPtWritingUtils::writeFlagsAndAdvancePosition(mTrieBuffer, updatedFlags,
832fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa            &writingPos)) {
842fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa        return false;
852fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa    }
862fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa    // Update moved position, which is stored in the parent offset field.
872fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa    if (!DynamicPtWritingUtils::writeParentPosOffsetAndAdvancePosition(
882fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa            mTrieBuffer, movedPos, toBeUpdatedPtNodeParams->getHeadPos(), &writingPos)) {
892fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa        return false;
902fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa    }
912fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa    if (toBeUpdatedPtNodeParams->hasChildren()) {
922fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa        // Update children's parent position.
932fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa        mReadingHelper.initWithPtNodeArrayPos(toBeUpdatedPtNodeParams->getChildrenPos());
942fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa        while (!mReadingHelper.isEnd()) {
952fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa            const PtNodeParams childPtNodeParams(mReadingHelper.getPtNodeParams());
962fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa            int parentOffsetFieldPos = childPtNodeParams.getHeadPos()
972fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa                    + DynamicPtWritingUtils::NODE_FLAG_FIELD_SIZE;
982fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa            if (!DynamicPtWritingUtils::writeParentPosOffsetAndAdvancePosition(
992fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa                    mTrieBuffer, bigramLinkedNodePos, childPtNodeParams.getHeadPos(),
1002fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa                    &parentOffsetFieldPos)) {
1012fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa                // Parent offset cannot be written because of a bug or a broken dictionary; thus,
1022fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa                // we give up to update dictionary.
1032fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa                return false;
1042fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa            }
1052fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa            mReadingHelper.readNextSiblingNode(childPtNodeParams);
1062fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa        }
1072fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa    }
1082fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa    return true;
1092fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa}
1102fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa
1112fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasabool Ver4PatriciaTrieNodeWriter::markPtNodeAsWillBecomeNonTerminal(
1122fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa        const PtNodeParams *const toBeUpdatedPtNodeParams) {
1132fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa    int pos = toBeUpdatedPtNodeParams->getHeadPos();
1142fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa    const bool usesAdditionalBuffer = mTrieBuffer->isInAdditionalBuffer(pos);
1152fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa    const uint8_t *const dictBuf = mTrieBuffer->getBuffer(usesAdditionalBuffer);
1162fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa    if (usesAdditionalBuffer) {
1172fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa        pos -= mTrieBuffer->getOriginalBufferSize();
1182fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa    }
1192fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa    // Read original flags
1202fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa    const PatriciaTrieReadingUtils::NodeFlags originalFlags =
1212fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa            PatriciaTrieReadingUtils::getFlagsAndAdvancePosition(dictBuf, &pos);
1222fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa    const PatriciaTrieReadingUtils::NodeFlags updatedFlags =
1232fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa            DynamicPtReadingUtils::updateAndGetFlags(originalFlags, false /* isMoved */,
1242fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa                    false /* isDeleted */, true /* willBecomeNonTerminal */);
1252fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa    if (!mBuffers->getMutableTerminalPositionLookupTable()->setTerminalPtNodePosition(
1262fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa            toBeUpdatedPtNodeParams->getTerminalId(), NOT_A_DICT_POS /* ptNodePos */)) {
1272fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa        AKLOGE("Cannot update terminal position lookup table. terminal id: %d",
1282fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa                toBeUpdatedPtNodeParams->getTerminalId());
1292fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa        return false;
1302fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa    }
1312fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa    // Update flags.
1322fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa    int writingPos = toBeUpdatedPtNodeParams->getHeadPos();
1332fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa    return DynamicPtWritingUtils::writeFlagsAndAdvancePosition(mTrieBuffer, updatedFlags,
1342fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa            &writingPos);
1352fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa}
1362fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa
137b636e25e951e48e071d5348756413d6fc065632dKeisuke Kuroyanagibool Ver4PatriciaTrieNodeWriter::updatePtNodeUnigramProperty(
138b636e25e951e48e071d5348756413d6fc065632dKeisuke Kuroyanagi        const PtNodeParams *const toBeUpdatedPtNodeParams,
139b636e25e951e48e071d5348756413d6fc065632dKeisuke Kuroyanagi        const UnigramProperty *const unigramProperty) {
140b636e25e951e48e071d5348756413d6fc065632dKeisuke Kuroyanagi    // Update probability and historical information.
141b636e25e951e48e071d5348756413d6fc065632dKeisuke Kuroyanagi    // TODO: Update other information in the unigram property.
1422fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa    if (!toBeUpdatedPtNodeParams->isTerminal()) {
1432fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa        return false;
1442fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa    }
1452fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa    const ProbabilityEntry originalProbabilityEntry =
1462fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa            mBuffers->getProbabilityDictContent()->getProbabilityEntry(
1472fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa                    toBeUpdatedPtNodeParams->getTerminalId());
1482fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa    const ProbabilityEntry probabilityEntry = createUpdatedEntryFrom(&originalProbabilityEntry,
149b636e25e951e48e071d5348756413d6fc065632dKeisuke Kuroyanagi            unigramProperty);
1502fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa    return mBuffers->getMutableProbabilityDictContent()->setProbabilityEntry(
1512fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa            toBeUpdatedPtNodeParams->getTerminalId(), &probabilityEntry);
1522fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa}
1532fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa
1542fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasabool Ver4PatriciaTrieNodeWriter::updatePtNodeProbabilityAndGetNeedsToKeepPtNodeAfterGC(
1552fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa        const PtNodeParams *const toBeUpdatedPtNodeParams, bool *const outNeedsToKeepPtNode) {
1562fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa    if (!toBeUpdatedPtNodeParams->isTerminal()) {
1572fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa        AKLOGE("updatePtNodeProbabilityAndGetNeedsToSaveForGC is called for non-terminal PtNode.");
1582fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa        return false;
1592fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa    }
1602fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa    const ProbabilityEntry originalProbabilityEntry =
1612fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa            mBuffers->getProbabilityDictContent()->getProbabilityEntry(
1622fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa                    toBeUpdatedPtNodeParams->getTerminalId());
1632fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa    if (originalProbabilityEntry.hasHistoricalInfo()) {
1642fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa        const HistoricalInfo historicalInfo = ForgettingCurveUtils::createHistoricalInfoToSave(
16557816c7a8bac1a47913da7a503ece2b5dd7cc0fcKeisuke Kuroyanagi                originalProbabilityEntry.getHistoricalInfo(), mHeaderPolicy);
1662fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa        const ProbabilityEntry probabilityEntry =
1672fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa                originalProbabilityEntry.createEntryWithUpdatedHistoricalInfo(&historicalInfo);
1682fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa        if (!mBuffers->getMutableProbabilityDictContent()->setProbabilityEntry(
1692fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa                toBeUpdatedPtNodeParams->getTerminalId(), &probabilityEntry)) {
1702fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa            AKLOGE("Cannot write updated probability entry. terminalId: %d",
1712fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa                    toBeUpdatedPtNodeParams->getTerminalId());
1722fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa            return false;
1732fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa        }
1745128935ac4d7961e3c863270b828e47a79b97235Keisuke Kuroyanagi        const bool isValid = ForgettingCurveUtils::needsToKeep(&historicalInfo, mHeaderPolicy);
1752fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa        if (!isValid) {
1762fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa            if (!markPtNodeAsWillBecomeNonTerminal(toBeUpdatedPtNodeParams)) {
1772fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa                AKLOGE("Cannot mark PtNode as willBecomeNonTerminal.");
1782fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa                return false;
1792fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa            }
1802fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa        }
1812fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa        *outNeedsToKeepPtNode = isValid;
1822fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa    } else {
1832fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa        // No need to update probability.
1842fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa        *outNeedsToKeepPtNode = true;
1852fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa    }
1862fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa    return true;
1872fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa}
1882fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa
1892fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasabool Ver4PatriciaTrieNodeWriter::updateChildrenPosition(
1902fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa        const PtNodeParams *const toBeUpdatedPtNodeParams, const int newChildrenPosition) {
1912fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa    int childrenPosFieldPos = toBeUpdatedPtNodeParams->getChildrenPosFieldPos();
1922fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa    return DynamicPtWritingUtils::writeChildrenPositionAndAdvancePosition(mTrieBuffer,
1932fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa            newChildrenPosition, &childrenPosFieldPos);
1942fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa}
1952fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa
1962fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasabool Ver4PatriciaTrieNodeWriter::updateTerminalId(const PtNodeParams *const toBeUpdatedPtNodeParams,
1972fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa        const int newTerminalId) {
1982fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa    return mTrieBuffer->writeUint(newTerminalId, Ver4DictConstants::TERMINAL_ID_FIELD_SIZE,
1992fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa            toBeUpdatedPtNodeParams->getTerminalIdFieldPos());
2002fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa}
2012fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa
2022fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasabool Ver4PatriciaTrieNodeWriter::writePtNodeAndAdvancePosition(
2032fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa        const PtNodeParams *const ptNodeParams, int *const ptNodeWritingPos) {
2042fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa    return writePtNodeAndGetTerminalIdAndAdvancePosition(ptNodeParams, 0 /* outTerminalId */,
2052fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa            ptNodeWritingPos);
2062fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa}
2072fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa
2082fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa
2092fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasabool Ver4PatriciaTrieNodeWriter::writeNewTerminalPtNodeAndAdvancePosition(
210b636e25e951e48e071d5348756413d6fc065632dKeisuke Kuroyanagi        const PtNodeParams *const ptNodeParams, const UnigramProperty *const unigramProperty,
211b636e25e951e48e071d5348756413d6fc065632dKeisuke Kuroyanagi        int *const ptNodeWritingPos) {
2122fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa    int terminalId = Ver4DictConstants::NOT_A_TERMINAL_ID;
2132fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa    if (!writePtNodeAndGetTerminalIdAndAdvancePosition(ptNodeParams, &terminalId,
2142fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa            ptNodeWritingPos)) {
2152fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa        return false;
2162fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa    }
2172fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa    // Write probability.
2182fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa    ProbabilityEntry newProbabilityEntry;
2192fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa    const ProbabilityEntry probabilityEntryToWrite = createUpdatedEntryFrom(
220b636e25e951e48e071d5348756413d6fc065632dKeisuke Kuroyanagi            &newProbabilityEntry, unigramProperty);
2212fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa    return mBuffers->getMutableProbabilityDictContent()->setProbabilityEntry(terminalId,
2222fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa            &probabilityEntryToWrite);
2232fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa}
2242fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa
2252fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasabool Ver4PatriciaTrieNodeWriter::addNewBigramEntry(
226620a05ae59ec9f7be39557094fc306c51c712ca1Keisuke Kuroyanagi        const PtNodeParams *const sourcePtNodeParams, const PtNodeParams *const targetPtNodeParam,
227620a05ae59ec9f7be39557094fc306c51c712ca1Keisuke Kuroyanagi        const BigramProperty *const bigramProperty, bool *const outAddedNewBigram) {
2282fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa    if (!mBigramPolicy->addNewEntry(sourcePtNodeParams->getTerminalId(),
229620a05ae59ec9f7be39557094fc306c51c712ca1Keisuke Kuroyanagi            targetPtNodeParam->getTerminalId(), bigramProperty, outAddedNewBigram)) {
2302fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa        AKLOGE("Cannot add new bigram entry. terminalId: %d, targetTerminalId: %d",
2312fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa                sourcePtNodeParams->getTerminalId(), targetPtNodeParam->getTerminalId());
2322fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa        return false;
2332fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa    }
2342fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa    if (!sourcePtNodeParams->hasBigrams()) {
2352fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa        // Update has bigrams flag.
2362fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa        return updatePtNodeFlags(sourcePtNodeParams->getHeadPos(),
2372fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa                sourcePtNodeParams->isBlacklisted(), sourcePtNodeParams->isNotAWord(),
2382fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa                sourcePtNodeParams->isTerminal(), sourcePtNodeParams->hasShortcutTargets(),
2392fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa                true /* hasBigrams */,
2402fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa                sourcePtNodeParams->getCodePointCount() > 1 /* hasMultipleChars */);
2412fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa    }
2422fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa    return true;
2432fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa}
2442fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa
2452fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasabool Ver4PatriciaTrieNodeWriter::removeBigramEntry(
2462fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa        const PtNodeParams *const sourcePtNodeParams, const PtNodeParams *const targetPtNodeParam) {
2472fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa    return mBigramPolicy->removeEntry(sourcePtNodeParams->getTerminalId(),
2482fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa            targetPtNodeParam->getTerminalId());
2492fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa}
2502fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa
2512fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasabool Ver4PatriciaTrieNodeWriter::updateAllBigramEntriesAndDeleteUselessEntries(
2522fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa            const PtNodeParams *const sourcePtNodeParams, int *const outBigramEntryCount) {
2532fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa    return mBigramPolicy->updateAllBigramEntriesAndDeleteUselessEntries(
2542fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa            sourcePtNodeParams->getTerminalId(), outBigramEntryCount);
2552fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa}
2562fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa
2572fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasabool Ver4PatriciaTrieNodeWriter::updateAllPositionFields(
2582fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa        const PtNodeParams *const toBeUpdatedPtNodeParams,
2592fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa        const DictPositionRelocationMap *const dictPositionRelocationMap,
2602fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa        int *const outBigramEntryCount) {
2612fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa    int parentPos = toBeUpdatedPtNodeParams->getParentPos();
2622fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa    if (parentPos != NOT_A_DICT_POS) {
2632fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa        PtNodeWriter::PtNodePositionRelocationMap::const_iterator it =
2642fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa                dictPositionRelocationMap->mPtNodePositionRelocationMap.find(parentPos);
2652fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa        if (it != dictPositionRelocationMap->mPtNodePositionRelocationMap.end()) {
2662fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa            parentPos = it->second;
2672fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa        }
2682fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa    }
2692fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa    int writingPos = toBeUpdatedPtNodeParams->getHeadPos()
2702fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa            + DynamicPtWritingUtils::NODE_FLAG_FIELD_SIZE;
2712fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa    // Write updated parent offset.
2722fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa    if (!DynamicPtWritingUtils::writeParentPosOffsetAndAdvancePosition(mTrieBuffer,
2732fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa            parentPos, toBeUpdatedPtNodeParams->getHeadPos(), &writingPos)) {
2742fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa        return false;
2752fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa    }
2762fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa
2772fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa    // Updates children position.
2782fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa    int childrenPos = toBeUpdatedPtNodeParams->getChildrenPos();
2792fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa    if (childrenPos != NOT_A_DICT_POS) {
2802fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa        PtNodeWriter::PtNodeArrayPositionRelocationMap::const_iterator it =
2812fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa                dictPositionRelocationMap->mPtNodeArrayPositionRelocationMap.find(childrenPos);
2822fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa        if (it != dictPositionRelocationMap->mPtNodeArrayPositionRelocationMap.end()) {
2832fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa            childrenPos = it->second;
2842fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa        }
2852fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa    }
2862fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa    if (!updateChildrenPosition(toBeUpdatedPtNodeParams, childrenPos)) {
2872fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa        return false;
2882fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa    }
2892fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa
2902fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa    // Counts bigram entries.
2912fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa    if (outBigramEntryCount) {
2922fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa        *outBigramEntryCount = mBigramPolicy->getBigramEntryConut(
2932fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa                toBeUpdatedPtNodeParams->getTerminalId());
2942fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa    }
2952fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa    return true;
2962fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa}
2972fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa
2982fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasabool Ver4PatriciaTrieNodeWriter::addShortcutTarget(const PtNodeParams *const ptNodeParams,
2992fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa        const int *const targetCodePoints, const int targetCodePointCount,
3002fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa        const int shortcutProbability) {
3012fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa    if (!mShortcutPolicy->addNewShortcut(ptNodeParams->getTerminalId(),
3022fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa            targetCodePoints, targetCodePointCount, shortcutProbability)) {
3032fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa        AKLOGE("Cannot add new shortuct entry. terminalId: %d", ptNodeParams->getTerminalId());
3042fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa        return false;
3052fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa    }
3062fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa    if (!ptNodeParams->hasShortcutTargets()) {
3072fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa        // Update has shortcut targets flag.
3082fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa        return updatePtNodeFlags(ptNodeParams->getHeadPos(),
3092fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa                ptNodeParams->isBlacklisted(), ptNodeParams->isNotAWord(),
3102fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa                ptNodeParams->isTerminal(), true /* hasShortcutTargets */,
3112fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa                ptNodeParams->hasBigrams(),
3122fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa                ptNodeParams->getCodePointCount() > 1 /* hasMultipleChars */);
3132fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa    }
3142fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa    return true;
3152fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa}
3162fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa
3172fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasabool Ver4PatriciaTrieNodeWriter::updatePtNodeHasBigramsAndShortcutTargetsFlags(
3182fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa        const PtNodeParams *const ptNodeParams) {
3192fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa    const bool hasBigrams = mBuffers->getBigramDictContent()->getBigramListHeadPos(
3202fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa            ptNodeParams->getTerminalId()) != NOT_A_DICT_POS;
3212fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa    const bool hasShortcutTargets = mBuffers->getShortcutDictContent()->getShortcutListHeadPos(
3222fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa            ptNodeParams->getTerminalId()) != NOT_A_DICT_POS;
3232fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa    return updatePtNodeFlags(ptNodeParams->getHeadPos(), ptNodeParams->isBlacklisted(),
3242fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa            ptNodeParams->isNotAWord(), ptNodeParams->isTerminal(), hasShortcutTargets,
3252fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa            hasBigrams, ptNodeParams->getCodePointCount() > 1 /* hasMultipleChars */);
3262fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa}
3272fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa
3282fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasabool Ver4PatriciaTrieNodeWriter::writePtNodeAndGetTerminalIdAndAdvancePosition(
3292fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa        const PtNodeParams *const ptNodeParams, int *const outTerminalId,
3302fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa        int *const ptNodeWritingPos) {
3312fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa    const int nodePos = *ptNodeWritingPos;
3322fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa    // Write dummy flags. The Node flags are updated with appropriate flags at the last step of the
3332fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa    // PtNode writing.
3342fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa    if (!DynamicPtWritingUtils::writeFlagsAndAdvancePosition(mTrieBuffer,
3352fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa            0 /* nodeFlags */, ptNodeWritingPos)) {
3362fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa        return false;
3372fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa    }
3382fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa    // Calculate a parent offset and write the offset.
3392fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa    if (!DynamicPtWritingUtils::writeParentPosOffsetAndAdvancePosition(mTrieBuffer,
3402fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa            ptNodeParams->getParentPos(), nodePos, ptNodeWritingPos)) {
3412fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa        return false;
3422fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa    }
3432fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa    // Write code points
3442fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa    if (!DynamicPtWritingUtils::writeCodePointsAndAdvancePosition(mTrieBuffer,
3452fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa            ptNodeParams->getCodePoints(), ptNodeParams->getCodePointCount(), ptNodeWritingPos)) {
3462fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa        return false;
3472fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa    }
3482fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa    int terminalId = Ver4DictConstants::NOT_A_TERMINAL_ID;
3492fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa    if (!ptNodeParams->willBecomeNonTerminal()) {
3502fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa        if (ptNodeParams->getTerminalId() != Ver4DictConstants::NOT_A_TERMINAL_ID) {
3512fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa            terminalId = ptNodeParams->getTerminalId();
3522fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa        } else if (ptNodeParams->isTerminal()) {
3532fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa            // Write terminal information using a new terminal id.
3542fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa            // Get a new unused terminal id.
3552fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa            terminalId = mBuffers->getTerminalPositionLookupTable()->getNextTerminalId();
3562fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa        }
3572fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa    }
3582fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa    const int isTerminal = terminalId != Ver4DictConstants::NOT_A_TERMINAL_ID;
3592fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa    if (isTerminal) {
3602fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa        // Update the lookup table.
3612fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa        if (!mBuffers->getMutableTerminalPositionLookupTable()->setTerminalPtNodePosition(
3622fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa                terminalId, nodePos)) {
3632fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa            return false;
3642fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa        }
3652fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa        // Write terminal Id.
3662fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa        if (!mTrieBuffer->writeUintAndAdvancePosition(terminalId,
3672fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa                Ver4DictConstants::TERMINAL_ID_FIELD_SIZE, ptNodeWritingPos)) {
3682fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa            return false;
3692fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa        }
3702fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa        if (outTerminalId) {
3712fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa            *outTerminalId = terminalId;
3722fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa        }
3732fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa    }
3742fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa    // Write children position
3752fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa    if (!DynamicPtWritingUtils::writeChildrenPositionAndAdvancePosition(mTrieBuffer,
3762fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa            ptNodeParams->getChildrenPos(), ptNodeWritingPos)) {
3772fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa        return false;
3782fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa    }
3792fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa    return updatePtNodeFlags(nodePos, ptNodeParams->isBlacklisted(), ptNodeParams->isNotAWord(),
3802fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa            isTerminal, ptNodeParams->hasShortcutTargets(), ptNodeParams->hasBigrams(),
3812fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa            ptNodeParams->getCodePointCount() > 1 /* hasMultipleChars */);
3822fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa}
3832fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa
3842fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasaconst ProbabilityEntry Ver4PatriciaTrieNodeWriter::createUpdatedEntryFrom(
385b636e25e951e48e071d5348756413d6fc065632dKeisuke Kuroyanagi        const ProbabilityEntry *const originalProbabilityEntry,
386b636e25e951e48e071d5348756413d6fc065632dKeisuke Kuroyanagi        const UnigramProperty *const unigramProperty) const {
3872fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa    // TODO: Consolidate historical info and probability.
38857816c7a8bac1a47913da7a503ece2b5dd7cc0fcKeisuke Kuroyanagi    if (mHeaderPolicy->hasHistoricalInfoOfWords()) {
3899d7e8c717f56a8b706a174fd3d5a2864d08d320cKeisuke Kuroyanagi        const HistoricalInfo historicalInfoForUpdate(unigramProperty->getTimestamp(),
3909d7e8c717f56a8b706a174fd3d5a2864d08d320cKeisuke Kuroyanagi                unigramProperty->getLevel(), unigramProperty->getCount());
3912fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa        const HistoricalInfo updatedHistoricalInfo =
3922fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa                ForgettingCurveUtils::createUpdatedHistoricalInfo(
393b636e25e951e48e071d5348756413d6fc065632dKeisuke Kuroyanagi                        originalProbabilityEntry->getHistoricalInfo(),
3949d7e8c717f56a8b706a174fd3d5a2864d08d320cKeisuke Kuroyanagi                        unigramProperty->getProbability(), &historicalInfoForUpdate, mHeaderPolicy);
3952fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa        return originalProbabilityEntry->createEntryWithUpdatedHistoricalInfo(
3962fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa                &updatedHistoricalInfo);
3972fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa    } else {
398b636e25e951e48e071d5348756413d6fc065632dKeisuke Kuroyanagi        return originalProbabilityEntry->createEntryWithUpdatedProbability(
399b636e25e951e48e071d5348756413d6fc065632dKeisuke Kuroyanagi                unigramProperty->getProbability());
4002fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa    }
4012fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa}
4022fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa
4032fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasabool Ver4PatriciaTrieNodeWriter::updatePtNodeFlags(const int ptNodePos,
4042fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa        const bool isBlacklisted, const bool isNotAWord, const bool isTerminal,
4052fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa        const bool hasShortcutTargets, const bool hasBigrams, const bool hasMultipleChars) {
4062fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa    // Create node flags and write them.
4072fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa    PatriciaTrieReadingUtils::NodeFlags nodeFlags =
4082fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa            PatriciaTrieReadingUtils::createAndGetFlags(isBlacklisted, isNotAWord, isTerminal,
4092fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa                    hasShortcutTargets, hasBigrams, hasMultipleChars,
4102fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa                    CHILDREN_POSITION_FIELD_SIZE);
4112fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa    if (!DynamicPtWritingUtils::writeFlags(mTrieBuffer, nodeFlags, ptNodePos)) {
4122fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa        AKLOGE("Cannot write PtNode flags. flags: %x, pos: %d", nodeFlags, ptNodePos);
4132fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa        return false;
4142fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa    }
4152fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa    return true;
4162fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa}
4172fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa
4182fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa}
419