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
1788bc312ad34321fb3e81be2dc939a889d065f4a7Keisuke Kuroyanagi#include "dictionary/structure/v4/ver4_patricia_trie_node_writer.h"
182fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa
1988bc312ad34321fb3e81be2dc939a889d065f4a7Keisuke Kuroyanagi#include "dictionary/header/header_policy.h"
2088bc312ad34321fb3e81be2dc939a889d065f4a7Keisuke Kuroyanagi#include "dictionary/property/unigram_property.h"
2188bc312ad34321fb3e81be2dc939a889d065f4a7Keisuke Kuroyanagi#include "dictionary/structure/pt_common/dynamic_pt_reading_utils.h"
2288bc312ad34321fb3e81be2dc939a889d065f4a7Keisuke Kuroyanagi#include "dictionary/structure/pt_common/dynamic_pt_writing_utils.h"
2388bc312ad34321fb3e81be2dc939a889d065f4a7Keisuke Kuroyanagi#include "dictionary/structure/pt_common/patricia_trie_reading_utils.h"
2488bc312ad34321fb3e81be2dc939a889d065f4a7Keisuke Kuroyanagi#include "dictionary/structure/v4/content/probability_entry.h"
2588bc312ad34321fb3e81be2dc939a889d065f4a7Keisuke Kuroyanagi#include "dictionary/structure/v4/shortcut/ver4_shortcut_list_policy.h"
2688bc312ad34321fb3e81be2dc939a889d065f4a7Keisuke Kuroyanagi#include "dictionary/structure/v4/ver4_patricia_trie_node_reader.h"
2788bc312ad34321fb3e81be2dc939a889d065f4a7Keisuke Kuroyanagi#include "dictionary/structure/v4/ver4_dict_buffers.h"
2888bc312ad34321fb3e81be2dc939a889d065f4a7Keisuke Kuroyanagi#include "dictionary/utils/buffer_with_extendable_buffer.h"
2988bc312ad34321fb3e81be2dc939a889d065f4a7Keisuke Kuroyanagi#include "dictionary/utils/forgetting_curve_utils.h"
302fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa
312fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasanamespace latinime {
322fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa
332fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasaconst int Ver4PatriciaTrieNodeWriter::CHILDREN_POSITION_FIELD_SIZE = 3;
342fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa
352fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasabool Ver4PatriciaTrieNodeWriter::markPtNodeAsDeleted(
362fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa        const PtNodeParams *const toBeUpdatedPtNodeParams) {
372fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa    int pos = toBeUpdatedPtNodeParams->getHeadPos();
382fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa    const bool usesAdditionalBuffer = mTrieBuffer->isInAdditionalBuffer(pos);
392fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa    const uint8_t *const dictBuf = mTrieBuffer->getBuffer(usesAdditionalBuffer);
402fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa    if (usesAdditionalBuffer) {
412fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa        pos -= mTrieBuffer->getOriginalBufferSize();
422fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa    }
432fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa    // Read original flags
442fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa    const PatriciaTrieReadingUtils::NodeFlags originalFlags =
452fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa            PatriciaTrieReadingUtils::getFlagsAndAdvancePosition(dictBuf, &pos);
462fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa    const PatriciaTrieReadingUtils::NodeFlags updatedFlags =
472fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa            DynamicPtReadingUtils::updateAndGetFlags(originalFlags, false /* isMoved */,
482fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa                    true /* isDeleted */, false /* willBecomeNonTerminal */);
492fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa    int writingPos = toBeUpdatedPtNodeParams->getHeadPos();
502fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa    // Update flags.
512fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa    if (!DynamicPtWritingUtils::writeFlagsAndAdvancePosition(mTrieBuffer, updatedFlags,
522fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa            &writingPos)) {
532fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa        return false;
542fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa    }
552fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa    if (toBeUpdatedPtNodeParams->isTerminal()) {
562fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa        // The PtNode is a terminal. Delete entry from the terminal position lookup table.
572fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa        return mBuffers->getMutableTerminalPositionLookupTable()->setTerminalPtNodePosition(
582fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa                toBeUpdatedPtNodeParams->getTerminalId(), NOT_A_DICT_POS /* ptNodePos */);
592fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa    } else {
602fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa        return true;
612fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa    }
622fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa}
632fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa
6479bb37d499ed6fcabe981153d5ff0b5b69509933Keisuke Kuroyanagi// TODO: Quit using bigramLinkedNodePos.
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    }
1459a23f0fba25137760a60e9bfaf6bf20a5889648cKeisuke Kuroyanagi    const ProbabilityEntry probabilityEntryOfUnigramProperty = ProbabilityEntry(unigramProperty);
146851e0458fe460526b1f953e39a1e406a21ab4647Keisuke Kuroyanagi    return mBuffers->getMutableLanguageModelDictContent()->setProbabilityEntry(
1475400701908262c929a77141cc84567646053d032Keisuke Kuroyanagi            toBeUpdatedPtNodeParams->getTerminalId(), &probabilityEntryOfUnigramProperty);
1482fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa}
1492fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa
1502fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasabool Ver4PatriciaTrieNodeWriter::updatePtNodeProbabilityAndGetNeedsToKeepPtNodeAfterGC(
1512fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa        const PtNodeParams *const toBeUpdatedPtNodeParams, bool *const outNeedsToKeepPtNode) {
1522fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa    if (!toBeUpdatedPtNodeParams->isTerminal()) {
1532fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa        AKLOGE("updatePtNodeProbabilityAndGetNeedsToSaveForGC is called for non-terminal PtNode.");
1542fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa        return false;
1552fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa    }
1562fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa    const ProbabilityEntry originalProbabilityEntry =
157851e0458fe460526b1f953e39a1e406a21ab4647Keisuke Kuroyanagi            mBuffers->getLanguageModelDictContent()->getProbabilityEntry(
1582fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa                    toBeUpdatedPtNodeParams->getTerminalId());
1599aa6699107de4da356b8eb89fb3ca38100e19c9dKeisuke Kuroyanagi    if (originalProbabilityEntry.isValid()) {
1602fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa        *outNeedsToKeepPtNode = true;
1619aa6699107de4da356b8eb89fb3ca38100e19c9dKeisuke Kuroyanagi        return true;
1629aa6699107de4da356b8eb89fb3ca38100e19c9dKeisuke Kuroyanagi    }
1639aa6699107de4da356b8eb89fb3ca38100e19c9dKeisuke Kuroyanagi    if (!markPtNodeAsWillBecomeNonTerminal(toBeUpdatedPtNodeParams)) {
1649aa6699107de4da356b8eb89fb3ca38100e19c9dKeisuke Kuroyanagi        AKLOGE("Cannot mark PtNode as willBecomeNonTerminal.");
1659aa6699107de4da356b8eb89fb3ca38100e19c9dKeisuke Kuroyanagi        return false;
1662fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa    }
1679aa6699107de4da356b8eb89fb3ca38100e19c9dKeisuke Kuroyanagi    *outNeedsToKeepPtNode = false;
1682fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa    return true;
1692fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa}
1702fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa
1712fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasabool Ver4PatriciaTrieNodeWriter::updateChildrenPosition(
1722fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa        const PtNodeParams *const toBeUpdatedPtNodeParams, const int newChildrenPosition) {
1732fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa    int childrenPosFieldPos = toBeUpdatedPtNodeParams->getChildrenPosFieldPos();
1742fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa    return DynamicPtWritingUtils::writeChildrenPositionAndAdvancePosition(mTrieBuffer,
1752fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa            newChildrenPosition, &childrenPosFieldPos);
1762fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa}
1772fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa
1782fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasabool Ver4PatriciaTrieNodeWriter::updateTerminalId(const PtNodeParams *const toBeUpdatedPtNodeParams,
1792fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa        const int newTerminalId) {
1802fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa    return mTrieBuffer->writeUint(newTerminalId, Ver4DictConstants::TERMINAL_ID_FIELD_SIZE,
1812fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa            toBeUpdatedPtNodeParams->getTerminalIdFieldPos());
1822fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa}
1832fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa
1842fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasabool Ver4PatriciaTrieNodeWriter::writePtNodeAndAdvancePosition(
1852fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa        const PtNodeParams *const ptNodeParams, int *const ptNodeWritingPos) {
1862fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa    return writePtNodeAndGetTerminalIdAndAdvancePosition(ptNodeParams, 0 /* outTerminalId */,
1872fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa            ptNodeWritingPos);
1882fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa}
1892fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa
1902fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasabool Ver4PatriciaTrieNodeWriter::writeNewTerminalPtNodeAndAdvancePosition(
191b636e25e951e48e071d5348756413d6fc065632dKeisuke Kuroyanagi        const PtNodeParams *const ptNodeParams, const UnigramProperty *const unigramProperty,
192b636e25e951e48e071d5348756413d6fc065632dKeisuke Kuroyanagi        int *const ptNodeWritingPos) {
1932fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa    int terminalId = Ver4DictConstants::NOT_A_TERMINAL_ID;
1942fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa    if (!writePtNodeAndGetTerminalIdAndAdvancePosition(ptNodeParams, &terminalId,
1952fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa            ptNodeWritingPos)) {
1962fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa        return false;
1972fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa    }
1982fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa    // Write probability.
1992fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa    ProbabilityEntry newProbabilityEntry;
2009a23f0fba25137760a60e9bfaf6bf20a5889648cKeisuke Kuroyanagi    const ProbabilityEntry probabilityEntryOfUnigramProperty = ProbabilityEntry(unigramProperty);
201851e0458fe460526b1f953e39a1e406a21ab4647Keisuke Kuroyanagi    return mBuffers->getMutableLanguageModelDictContent()->setProbabilityEntry(
2025400701908262c929a77141cc84567646053d032Keisuke Kuroyanagi            terminalId, &probabilityEntryOfUnigramProperty);
2032fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa}
2042fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa
20579bb37d499ed6fcabe981153d5ff0b5b69509933Keisuke Kuroyanagi// TODO: Support counting ngram entries.
2069069d30043d5182dfd38465ad9bbc11ad73fab7cKeisuke Kuroyanagibool Ver4PatriciaTrieNodeWriter::addNgramEntry(const WordIdArrayView prevWordIds, const int wordId,
20779bb37d499ed6fcabe981153d5ff0b5b69509933Keisuke Kuroyanagi        const NgramProperty *const ngramProperty, bool *const outAddedNewBigram) {
2089a23f0fba25137760a60e9bfaf6bf20a5889648cKeisuke Kuroyanagi    LanguageModelDictContent *const languageModelDictContent =
2099a23f0fba25137760a60e9bfaf6bf20a5889648cKeisuke Kuroyanagi            mBuffers->getMutableLanguageModelDictContent();
2109a23f0fba25137760a60e9bfaf6bf20a5889648cKeisuke Kuroyanagi    const ProbabilityEntry probabilityEntry =
2110c0b8207cdabc1f5c1a81441c1ab0cb715e458eaKeisuke Kuroyanagi            languageModelDictContent->getNgramProbabilityEntry(prevWordIds, wordId);
21279bb37d499ed6fcabe981153d5ff0b5b69509933Keisuke Kuroyanagi    const ProbabilityEntry probabilityEntryOfNgramProperty(ngramProperty);
2139a23f0fba25137760a60e9bfaf6bf20a5889648cKeisuke Kuroyanagi    if (!languageModelDictContent->setNgramProbabilityEntry(
2145400701908262c929a77141cc84567646053d032Keisuke Kuroyanagi            prevWordIds, wordId, &probabilityEntryOfNgramProperty)) {
2150c0b8207cdabc1f5c1a81441c1ab0cb715e458eaKeisuke Kuroyanagi        AKLOGE("Cannot add new ngram entry. prevWordId[0]: %d, prevWordId.size(): %zd, wordId: %d",
2160c0b8207cdabc1f5c1a81441c1ab0cb715e458eaKeisuke Kuroyanagi                prevWordIds[0], prevWordIds.size(), wordId);
2179a23f0fba25137760a60e9bfaf6bf20a5889648cKeisuke Kuroyanagi        return false;
2189a23f0fba25137760a60e9bfaf6bf20a5889648cKeisuke Kuroyanagi    }
2199a23f0fba25137760a60e9bfaf6bf20a5889648cKeisuke Kuroyanagi    if (!probabilityEntry.isValid() && outAddedNewBigram) {
2209a23f0fba25137760a60e9bfaf6bf20a5889648cKeisuke Kuroyanagi        *outAddedNewBigram = true;
2219a23f0fba25137760a60e9bfaf6bf20a5889648cKeisuke Kuroyanagi    }
2222fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa    return true;
2232fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa}
2242fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa
2259069d30043d5182dfd38465ad9bbc11ad73fab7cKeisuke Kuroyanagibool Ver4PatriciaTrieNodeWriter::removeNgramEntry(const WordIdArrayView prevWordIds,
2269069d30043d5182dfd38465ad9bbc11ad73fab7cKeisuke Kuroyanagi        const int wordId) {
227d3097c67ca5da0f01d371f27d1b2dcdf32b80e3eKeisuke Kuroyanagi    LanguageModelDictContent *const languageModelDictContent =
228d3097c67ca5da0f01d371f27d1b2dcdf32b80e3eKeisuke Kuroyanagi            mBuffers->getMutableLanguageModelDictContent();
2295520e84e16f3886548dc11cf888977a6dbbef5f1Keisuke Kuroyanagi    return languageModelDictContent->removeNgramProbabilityEntry(prevWordIds, wordId);
2302fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa}
2312fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa
232fe395232d69df0887863c1cbabe63def2586d29eKeisuke Kuroyanagi// TODO: Remove when we stop supporting v402 format.
2332fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasabool Ver4PatriciaTrieNodeWriter::updateAllBigramEntriesAndDeleteUselessEntries(
2342fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa            const PtNodeParams *const sourcePtNodeParams, int *const outBigramEntryCount) {
235fe395232d69df0887863c1cbabe63def2586d29eKeisuke Kuroyanagi    // Do nothing.
236fe395232d69df0887863c1cbabe63def2586d29eKeisuke Kuroyanagi    return true;
2372fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa}
2382fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa
2392fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasabool Ver4PatriciaTrieNodeWriter::updateAllPositionFields(
2402fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa        const PtNodeParams *const toBeUpdatedPtNodeParams,
2412fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa        const DictPositionRelocationMap *const dictPositionRelocationMap,
2422fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa        int *const outBigramEntryCount) {
2432fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa    int parentPos = toBeUpdatedPtNodeParams->getParentPos();
2442fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa    if (parentPos != NOT_A_DICT_POS) {
2452fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa        PtNodeWriter::PtNodePositionRelocationMap::const_iterator it =
2462fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa                dictPositionRelocationMap->mPtNodePositionRelocationMap.find(parentPos);
2472fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa        if (it != dictPositionRelocationMap->mPtNodePositionRelocationMap.end()) {
2482fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa            parentPos = it->second;
2492fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa        }
2502fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa    }
2512fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa    int writingPos = toBeUpdatedPtNodeParams->getHeadPos()
2522fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa            + DynamicPtWritingUtils::NODE_FLAG_FIELD_SIZE;
2532fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa    // Write updated parent offset.
2542fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa    if (!DynamicPtWritingUtils::writeParentPosOffsetAndAdvancePosition(mTrieBuffer,
2552fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa            parentPos, toBeUpdatedPtNodeParams->getHeadPos(), &writingPos)) {
2562fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa        return false;
2572fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa    }
2582fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa
2592fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa    // Updates children position.
2602fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa    int childrenPos = toBeUpdatedPtNodeParams->getChildrenPos();
2612fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa    if (childrenPos != NOT_A_DICT_POS) {
2622fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa        PtNodeWriter::PtNodeArrayPositionRelocationMap::const_iterator it =
2632fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa                dictPositionRelocationMap->mPtNodeArrayPositionRelocationMap.find(childrenPos);
2642fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa        if (it != dictPositionRelocationMap->mPtNodeArrayPositionRelocationMap.end()) {
2652fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa            childrenPos = it->second;
2662fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa        }
2672fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa    }
2682fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa    if (!updateChildrenPosition(toBeUpdatedPtNodeParams, childrenPos)) {
2692fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa        return false;
2702fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa    }
2712fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa    return true;
2722fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa}
2732fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa
2742fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasabool Ver4PatriciaTrieNodeWriter::addShortcutTarget(const PtNodeParams *const ptNodeParams,
2752fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa        const int *const targetCodePoints, const int targetCodePointCount,
2762fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa        const int shortcutProbability) {
2772fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa    if (!mShortcutPolicy->addNewShortcut(ptNodeParams->getTerminalId(),
2782fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa            targetCodePoints, targetCodePointCount, shortcutProbability)) {
27944efbe64b1ba44f8edf13a52eca630fce3d7c809Adrian Velicu        AKLOGE("Cannot add new shortcut entry. terminalId: %d", ptNodeParams->getTerminalId());
2802fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa        return false;
2812fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa    }
2822fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa    return true;
2832fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa}
2842fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa
2852fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasabool Ver4PatriciaTrieNodeWriter::writePtNodeAndGetTerminalIdAndAdvancePosition(
2862fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa        const PtNodeParams *const ptNodeParams, int *const outTerminalId,
2872fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa        int *const ptNodeWritingPos) {
2882fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa    const int nodePos = *ptNodeWritingPos;
2892fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa    // Write dummy flags. The Node flags are updated with appropriate flags at the last step of the
2902fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa    // PtNode writing.
2912fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa    if (!DynamicPtWritingUtils::writeFlagsAndAdvancePosition(mTrieBuffer,
2922fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa            0 /* nodeFlags */, ptNodeWritingPos)) {
2932fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa        return false;
2942fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa    }
2952fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa    // Calculate a parent offset and write the offset.
2962fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa    if (!DynamicPtWritingUtils::writeParentPosOffsetAndAdvancePosition(mTrieBuffer,
2972fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa            ptNodeParams->getParentPos(), nodePos, ptNodeWritingPos)) {
2982fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa        return false;
2992fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa    }
3002fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa    // Write code points
3012fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa    if (!DynamicPtWritingUtils::writeCodePointsAndAdvancePosition(mTrieBuffer,
3022fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa            ptNodeParams->getCodePoints(), ptNodeParams->getCodePointCount(), ptNodeWritingPos)) {
3032fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa        return false;
3042fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa    }
3052fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa    int terminalId = Ver4DictConstants::NOT_A_TERMINAL_ID;
3062fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa    if (!ptNodeParams->willBecomeNonTerminal()) {
3072fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa        if (ptNodeParams->getTerminalId() != Ver4DictConstants::NOT_A_TERMINAL_ID) {
3082fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa            terminalId = ptNodeParams->getTerminalId();
3092fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa        } else if (ptNodeParams->isTerminal()) {
3102fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa            // Write terminal information using a new terminal id.
3112fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa            // Get a new unused terminal id.
3122fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa            terminalId = mBuffers->getTerminalPositionLookupTable()->getNextTerminalId();
3132fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa        }
3142fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa    }
3152fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa    const int isTerminal = terminalId != Ver4DictConstants::NOT_A_TERMINAL_ID;
3162fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa    if (isTerminal) {
3172fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa        // Update the lookup table.
3182fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa        if (!mBuffers->getMutableTerminalPositionLookupTable()->setTerminalPtNodePosition(
3192fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa                terminalId, nodePos)) {
3202fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa            return false;
3212fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa        }
3222fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa        // Write terminal Id.
3232fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa        if (!mTrieBuffer->writeUintAndAdvancePosition(terminalId,
3242fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa                Ver4DictConstants::TERMINAL_ID_FIELD_SIZE, ptNodeWritingPos)) {
3252fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa            return false;
3262fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa        }
3272fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa        if (outTerminalId) {
3282fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa            *outTerminalId = terminalId;
3292fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa        }
3302fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa    }
3312fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa    // Write children position
3322fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa    if (!DynamicPtWritingUtils::writeChildrenPositionAndAdvancePosition(mTrieBuffer,
3332fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa            ptNodeParams->getChildrenPos(), ptNodeWritingPos)) {
3342fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa        return false;
3352fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa    }
3367d911d6f91af56586fbca40672bfb77b494ee871Keisuke Kuroyanagi    return updatePtNodeFlags(nodePos, isTerminal,
3377d911d6f91af56586fbca40672bfb77b494ee871Keisuke Kuroyanagi            ptNodeParams->getCodePointCount() > 1 /* hasMultipleChars */);
3382fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa}
3392fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa
3407d911d6f91af56586fbca40672bfb77b494ee871Keisuke Kuroyanagibool Ver4PatriciaTrieNodeWriter::updatePtNodeFlags(const int ptNodePos, const bool isTerminal,
34124d49ee577e4e9cc29051d336c10ad4124e0bb96Keisuke Kuroyanagi        const bool hasMultipleChars) {
3422fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa    // Create node flags and write them.
3432fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa    PatriciaTrieReadingUtils::NodeFlags nodeFlags =
3447d911d6f91af56586fbca40672bfb77b494ee871Keisuke Kuroyanagi            PatriciaTrieReadingUtils::createAndGetFlags(false /* isNotAWord */,
34505172bf1a5693c2e108e91436b98ecd35d2dadadAdrian Velicu                    false /* isPossiblyOffensive */, isTerminal, false /* hasShortcutTargets */,
3467d911d6f91af56586fbca40672bfb77b494ee871Keisuke Kuroyanagi                    false /* hasBigrams */, hasMultipleChars, CHILDREN_POSITION_FIELD_SIZE);
3472fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa    if (!DynamicPtWritingUtils::writeFlags(mTrieBuffer, nodeFlags, ptNodePos)) {
3482fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa        AKLOGE("Cannot write PtNode flags. flags: %x, pos: %d", nodeFlags, ptNodePos);
3492fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa        return false;
3502fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa    }
3512fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa    return true;
3522fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa}
3532fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa
3540c8ce96beccc16271a1ad003dcb41772f3df0927Keisuke Kuroyanagi} // namespace latinime
355