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_dict_buffers.h"
182fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa
192fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa#include <cerrno>
202fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa#include <cstring>
212ac934296c0571ea252f3fb5a23fba29eb89c666Keisuke Kuroyanagi#include <fcntl.h>
222fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa#include <sys/stat.h>
232fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa#include <sys/types.h>
242ac934296c0571ea252f3fb5a23fba29eb89c666Keisuke Kuroyanagi#include <vector>
252fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa
2688bc312ad34321fb3e81be2dc939a889d065f4a7Keisuke Kuroyanagi#include "dictionary/utils/byte_array_utils.h"
2788bc312ad34321fb3e81be2dc939a889d065f4a7Keisuke Kuroyanagi#include "dictionary/utils/dict_file_writing_utils.h"
2888bc312ad34321fb3e81be2dc939a889d065f4a7Keisuke Kuroyanagi#include "dictionary/utils/file_utils.h"
29c0c674cdc0721a374e140ad5ee1409c0498b3262Keisuke Kuroyanagi#include "utils/byte_array_view.h"
302fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa
312fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasanamespace latinime {
322fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa
332fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa/* static */ Ver4DictBuffers::Ver4DictBuffersPtr Ver4DictBuffers::openVer4DictBuffers(
342ac934296c0571ea252f3fb5a23fba29eb89c666Keisuke Kuroyanagi        const char *const dictPath, MmappedBuffer::MmappedBufferPtr &&headerBuffer,
35455dc84cf2c6526329b535f30000ea45b7d4d4d7Keisuke Kuroyanagi        const FormatUtils::FORMAT_VERSION formatVersion) {
364ce480d5ce2d47f607448ce439aaf2cefba1bdd8Keisuke Kuroyanagi    if (!headerBuffer) {
37303e767728656566e57c499fa745297f6a7b60c2Keisuke Kuroyanagi        ASSERT(false);
38303e767728656566e57c499fa745297f6a7b60c2Keisuke Kuroyanagi        AKLOGE("The header buffer must be valid to open ver4 dict buffers.");
396c7ebc4023086fd61dcc19688663616c4781672aKeisuke Kuroyanagi        return Ver4DictBuffersPtr(nullptr);
40303e767728656566e57c499fa745297f6a7b60c2Keisuke Kuroyanagi    }
412fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa    // TODO: take only dictDirPath, and open both header and trie files in the constructor below
424ce480d5ce2d47f607448ce439aaf2cefba1bdd8Keisuke Kuroyanagi    const bool isUpdatable = headerBuffer->isUpdatable();
432ac934296c0571ea252f3fb5a23fba29eb89c666Keisuke Kuroyanagi    MmappedBuffer::MmappedBufferPtr bodyBuffer = MmappedBuffer::openBuffer(dictPath,
442ac934296c0571ea252f3fb5a23fba29eb89c666Keisuke Kuroyanagi            Ver4DictConstants::BODY_FILE_EXTENSION, isUpdatable);
452ac934296c0571ea252f3fb5a23fba29eb89c666Keisuke Kuroyanagi    if (!bodyBuffer) {
462ac934296c0571ea252f3fb5a23fba29eb89c666Keisuke Kuroyanagi        return Ver4DictBuffersPtr(nullptr);
472ac934296c0571ea252f3fb5a23fba29eb89c666Keisuke Kuroyanagi    }
481f6e52ef029e7807b6998d397556fac30b2b7ff4Keisuke Kuroyanagi    std::vector<ReadWriteByteArrayView> buffers;
49c0c674cdc0721a374e140ad5ee1409c0498b3262Keisuke Kuroyanagi    const ReadWriteByteArrayView buffer = bodyBuffer->getReadWriteByteArrayView();
502ac934296c0571ea252f3fb5a23fba29eb89c666Keisuke Kuroyanagi    int position = 0;
51c0c674cdc0721a374e140ad5ee1409c0498b3262Keisuke Kuroyanagi    while (position < static_cast<int>(buffer.size())) {
52c0c674cdc0721a374e140ad5ee1409c0498b3262Keisuke Kuroyanagi        const int bufferSize = ByteArrayUtils::readUint32AndAdvancePosition(
53c0c674cdc0721a374e140ad5ee1409c0498b3262Keisuke Kuroyanagi                buffer.data(), &position);
541f6e52ef029e7807b6998d397556fac30b2b7ff4Keisuke Kuroyanagi        buffers.push_back(buffer.subView(position, bufferSize));
552ac934296c0571ea252f3fb5a23fba29eb89c666Keisuke Kuroyanagi        position += bufferSize;
56c0c674cdc0721a374e140ad5ee1409c0498b3262Keisuke Kuroyanagi        if (bufferSize < 0 || position < 0 || position > static_cast<int>(buffer.size())) {
572ac934296c0571ea252f3fb5a23fba29eb89c666Keisuke Kuroyanagi            AKLOGE("The dict body file is corrupted.");
582ac934296c0571ea252f3fb5a23fba29eb89c666Keisuke Kuroyanagi            return Ver4DictBuffersPtr(nullptr);
592ac934296c0571ea252f3fb5a23fba29eb89c666Keisuke Kuroyanagi        }
602ac934296c0571ea252f3fb5a23fba29eb89c666Keisuke Kuroyanagi    }
612ac934296c0571ea252f3fb5a23fba29eb89c666Keisuke Kuroyanagi    if (buffers.size() != Ver4DictConstants::NUM_OF_CONTENT_BUFFERS_IN_BODY_FILE) {
622ac934296c0571ea252f3fb5a23fba29eb89c666Keisuke Kuroyanagi        AKLOGE("The dict body file is corrupted.");
632ac934296c0571ea252f3fb5a23fba29eb89c666Keisuke Kuroyanagi        return Ver4DictBuffersPtr(nullptr);
642ac934296c0571ea252f3fb5a23fba29eb89c666Keisuke Kuroyanagi    }
652ac934296c0571ea252f3fb5a23fba29eb89c666Keisuke Kuroyanagi    return Ver4DictBuffersPtr(new Ver4DictBuffers(std::move(headerBuffer), std::move(bodyBuffer),
661f6e52ef029e7807b6998d397556fac30b2b7ff4Keisuke Kuroyanagi            formatVersion, buffers));
672fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa}
682fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa
692fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasabool Ver4DictBuffers::flushHeaderAndDictBuffers(const char *const dictDirPath,
702fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa        const BufferWithExtendableBuffer *const headerBuffer) const {
712fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa    // Create temporary directory.
722fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa    const int tmpDirPathBufSize = FileUtils::getFilePathWithSuffixBufSize(dictDirPath,
732fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa            DictFileWritingUtils::TEMP_FILE_SUFFIX_FOR_WRITING_DICT_FILE);
742fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa    char tmpDirPath[tmpDirPathBufSize];
752fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa    FileUtils::getFilePathWithSuffix(dictDirPath,
762fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa            DictFileWritingUtils::TEMP_FILE_SUFFIX_FOR_WRITING_DICT_FILE, tmpDirPathBufSize,
772fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa            tmpDirPath);
782fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa    if (FileUtils::existsDir(tmpDirPath)) {
792fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa        if (!FileUtils::removeDirAndFiles(tmpDirPath)) {
802fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa            AKLOGE("Existing directory %s cannot be removed.", tmpDirPath);
812fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa            ASSERT(false);
822fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa            return false;
832fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa        }
842fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa    }
85ed16af72e3a3eeea3b6a0b4bfbe39332a114af99Keisuke Kuroyanagi    umask(S_IWGRP | S_IWOTH);
862fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa    if (mkdir(tmpDirPath, S_IRWXU) == -1) {
872fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa        AKLOGE("Cannot create directory: %s. errno: %d.", tmpDirPath, errno);
882fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa        return false;
892fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa    }
902fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa    // Get dictionary base path.
912fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa    const int dictNameBufSize = strlen(dictDirPath) + 1 /* terminator */;
922fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa    char dictName[dictNameBufSize];
932fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa    FileUtils::getBasename(dictDirPath, dictNameBufSize, dictName);
942fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa    const int dictPathBufSize = FileUtils::getFilePathBufSize(tmpDirPath, dictName);
952fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa    char dictPath[dictPathBufSize];
962fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa    FileUtils::getFilePath(tmpDirPath, dictName, dictPathBufSize, dictPath);
972fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa
982fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa    // Write header file.
992fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa    if (!DictFileWritingUtils::flushBufferToFileWithSuffix(dictPath,
1002fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa            Ver4DictConstants::HEADER_FILE_EXTENSION, headerBuffer)) {
1012fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa        AKLOGE("Dictionary header file %s%s cannot be written.", tmpDirPath,
1022fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa                Ver4DictConstants::HEADER_FILE_EXTENSION);
1032fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa        return false;
1042fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa    }
1052ac934296c0571ea252f3fb5a23fba29eb89c666Keisuke Kuroyanagi
1062ac934296c0571ea252f3fb5a23fba29eb89c666Keisuke Kuroyanagi    // Write body file.
1072ac934296c0571ea252f3fb5a23fba29eb89c666Keisuke Kuroyanagi    const int bodyFilePathBufSize = FileUtils::getFilePathWithSuffixBufSize(dictPath,
1082ac934296c0571ea252f3fb5a23fba29eb89c666Keisuke Kuroyanagi            Ver4DictConstants::BODY_FILE_EXTENSION);
1092ac934296c0571ea252f3fb5a23fba29eb89c666Keisuke Kuroyanagi    char bodyFilePath[bodyFilePathBufSize];
1102ac934296c0571ea252f3fb5a23fba29eb89c666Keisuke Kuroyanagi    FileUtils::getFilePathWithSuffix(dictPath, Ver4DictConstants::BODY_FILE_EXTENSION,
1112ac934296c0571ea252f3fb5a23fba29eb89c666Keisuke Kuroyanagi            bodyFilePathBufSize, bodyFilePath);
1122ac934296c0571ea252f3fb5a23fba29eb89c666Keisuke Kuroyanagi
1132ac934296c0571ea252f3fb5a23fba29eb89c666Keisuke Kuroyanagi    const int fd = open(bodyFilePath, O_WRONLY | O_CREAT | O_EXCL, S_IRUSR | S_IWUSR);
1142ac934296c0571ea252f3fb5a23fba29eb89c666Keisuke Kuroyanagi    if (fd == -1) {
1152ac934296c0571ea252f3fb5a23fba29eb89c666Keisuke Kuroyanagi        AKLOGE("File %s cannot be opened. errno: %d", bodyFilePath, errno);
1162ac934296c0571ea252f3fb5a23fba29eb89c666Keisuke Kuroyanagi        ASSERT(false);
1172fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa        return false;
1182fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa    }
1192ac934296c0571ea252f3fb5a23fba29eb89c666Keisuke Kuroyanagi    FILE *const file = fdopen(fd, "wb");
1202ac934296c0571ea252f3fb5a23fba29eb89c666Keisuke Kuroyanagi    if (!file) {
121d3d7c31ca996d4d7eecbb1dafc549363bef6448eKeisuke Kuroyanagi        AKLOGE("fdopen failed for the file %s. errno: %d", bodyFilePath, errno);
1222ac934296c0571ea252f3fb5a23fba29eb89c666Keisuke Kuroyanagi        ASSERT(false);
1232fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa        return false;
1242fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa    }
1252ac934296c0571ea252f3fb5a23fba29eb89c666Keisuke Kuroyanagi
1262ac934296c0571ea252f3fb5a23fba29eb89c666Keisuke Kuroyanagi    if (!flushDictBuffers(file)) {
1272ac934296c0571ea252f3fb5a23fba29eb89c666Keisuke Kuroyanagi        fclose(file);
1282fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa        return false;
1292fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa    }
1302ac934296c0571ea252f3fb5a23fba29eb89c666Keisuke Kuroyanagi    fclose(file);
1312fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa    // Remove existing dictionary.
1322fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa    if (!FileUtils::removeDirAndFiles(dictDirPath)) {
1332fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa        AKLOGE("Existing directory %s cannot be removed.", dictDirPath);
1342fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa        ASSERT(false);
1352fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa        return false;
1362fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa    }
1372fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa    // Rename temporary directory.
1382fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa    if (rename(tmpDirPath, dictDirPath) != 0) {
1392fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa        AKLOGE("%s cannot be renamed to %s", tmpDirPath, dictDirPath);
1402fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa        ASSERT(false);
1412fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa        return false;
1422fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa    }
1432fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa    return true;
1442fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa}
1452fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa
1462ac934296c0571ea252f3fb5a23fba29eb89c666Keisuke Kuroyanagibool Ver4DictBuffers::flushDictBuffers(FILE *const file) const {
1472ac934296c0571ea252f3fb5a23fba29eb89c666Keisuke Kuroyanagi    // Write trie.
1482ac934296c0571ea252f3fb5a23fba29eb89c666Keisuke Kuroyanagi    if (!DictFileWritingUtils::writeBufferToFileTail(file, &mExpandableTrieBuffer)) {
149d3d7c31ca996d4d7eecbb1dafc549363bef6448eKeisuke Kuroyanagi        AKLOGE("Trie cannot be written.");
1502ac934296c0571ea252f3fb5a23fba29eb89c666Keisuke Kuroyanagi        return false;
1512ac934296c0571ea252f3fb5a23fba29eb89c666Keisuke Kuroyanagi    }
1522ac934296c0571ea252f3fb5a23fba29eb89c666Keisuke Kuroyanagi    // Write terminal position lookup table.
1532ac934296c0571ea252f3fb5a23fba29eb89c666Keisuke Kuroyanagi    if (!mTerminalPositionLookupTable.flushToFile(file)) {
154d3d7c31ca996d4d7eecbb1dafc549363bef6448eKeisuke Kuroyanagi        AKLOGE("Terminal position lookup table cannot be written.");
1552ac934296c0571ea252f3fb5a23fba29eb89c666Keisuke Kuroyanagi        return false;
1562ac934296c0571ea252f3fb5a23fba29eb89c666Keisuke Kuroyanagi    }
157c4696b2eb6b25eea4d5c869683104ab99aec0421Keisuke Kuroyanagi    // Write language model content.
158c4696b2eb6b25eea4d5c869683104ab99aec0421Keisuke Kuroyanagi    if (!mLanguageModelDictContent.save(file)) {
159c4696b2eb6b25eea4d5c869683104ab99aec0421Keisuke Kuroyanagi        AKLOGE("Language model dict content cannot be written.");
160c4696b2eb6b25eea4d5c869683104ab99aec0421Keisuke Kuroyanagi        return false;
161c4696b2eb6b25eea4d5c869683104ab99aec0421Keisuke Kuroyanagi    }
1622ac934296c0571ea252f3fb5a23fba29eb89c666Keisuke Kuroyanagi    // Write shortcut dict content.
1632ac934296c0571ea252f3fb5a23fba29eb89c666Keisuke Kuroyanagi    if (!mShortcutDictContent.flushToFile(file)) {
164d3d7c31ca996d4d7eecbb1dafc549363bef6448eKeisuke Kuroyanagi        AKLOGE("Shortcut dict content cannot be written.");
1652ac934296c0571ea252f3fb5a23fba29eb89c666Keisuke Kuroyanagi        return false;
1662ac934296c0571ea252f3fb5a23fba29eb89c666Keisuke Kuroyanagi    }
1672ac934296c0571ea252f3fb5a23fba29eb89c666Keisuke Kuroyanagi    return true;
1682ac934296c0571ea252f3fb5a23fba29eb89c666Keisuke Kuroyanagi}
1692ac934296c0571ea252f3fb5a23fba29eb89c666Keisuke Kuroyanagi
1702ac934296c0571ea252f3fb5a23fba29eb89c666Keisuke KuroyanagiVer4DictBuffers::Ver4DictBuffers(MmappedBuffer::MmappedBufferPtr &&headerBuffer,
1712ac934296c0571ea252f3fb5a23fba29eb89c666Keisuke Kuroyanagi        MmappedBuffer::MmappedBufferPtr &&bodyBuffer,
172b22f95ec8a8325e65b95e7b0d57156854f7984f6Keisuke Kuroyanagi        const FormatUtils::FORMAT_VERSION formatVersion,
1731f6e52ef029e7807b6998d397556fac30b2b7ff4Keisuke Kuroyanagi        const std::vector<ReadWriteByteArrayView> &contentBuffers)
1742ac934296c0571ea252f3fb5a23fba29eb89c666Keisuke Kuroyanagi        : mHeaderBuffer(std::move(headerBuffer)), mDictBuffer(std::move(bodyBuffer)),
175c0c674cdc0721a374e140ad5ee1409c0498b3262Keisuke Kuroyanagi          mHeaderPolicy(mHeaderBuffer->getReadOnlyByteArrayView().data(), formatVersion),
176c0c674cdc0721a374e140ad5ee1409c0498b3262Keisuke Kuroyanagi          mExpandableHeaderBuffer(mHeaderBuffer->getReadWriteByteArrayView(),
1772fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa                  BufferWithExtendableBuffer::DEFAULT_MAX_ADDITIONAL_BUFFER_SIZE),
1781f6e52ef029e7807b6998d397556fac30b2b7ff4Keisuke Kuroyanagi          mExpandableTrieBuffer(contentBuffers[Ver4DictConstants::TRIE_BUFFER_INDEX],
1792fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa                  BufferWithExtendableBuffer::DEFAULT_MAX_ADDITIONAL_BUFFER_SIZE),
1802ac934296c0571ea252f3fb5a23fba29eb89c666Keisuke Kuroyanagi          mTerminalPositionLookupTable(
1811f6e52ef029e7807b6998d397556fac30b2b7ff4Keisuke Kuroyanagi                  contentBuffers[Ver4DictConstants::TERMINAL_ADDRESS_LOOKUP_TABLE_BUFFER_INDEX]),
1826b0561f9d26215209e8e8895f5c35982af5158f0Keisuke Kuroyanagi          mLanguageModelDictContent(&contentBuffers[Ver4DictConstants::LANGUAGE_MODEL_BUFFER_INDEX],
183c4696b2eb6b25eea4d5c869683104ab99aec0421Keisuke Kuroyanagi                  mHeaderPolicy.hasHistoricalInfoOfWords()),
1841f6e52ef029e7807b6998d397556fac30b2b7ff4Keisuke Kuroyanagi          mShortcutDictContent(&contentBuffers[Ver4DictConstants::SHORTCUT_BUFFERS_INDEX]),
185b22f95ec8a8325e65b95e7b0d57156854f7984f6Keisuke Kuroyanagi          mIsUpdatable(mDictBuffer->isUpdatable()) {}
1862fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa
1877b43d987fa9d225c4305f4681dc8e27f244279a8Keisuke KuroyanagiVer4DictBuffers::Ver4DictBuffers(const HeaderPolicy *const headerPolicy, const int maxTrieSize)
1883b7984752c88bff157016a09158dc92d94ed401dKeisuke Kuroyanagi        : mHeaderBuffer(nullptr), mDictBuffer(nullptr), mHeaderPolicy(headerPolicy),
1892fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa          mExpandableHeaderBuffer(Ver4DictConstants::MAX_DICTIONARY_SIZE),
1907b43d987fa9d225c4305f4681dc8e27f244279a8Keisuke Kuroyanagi          mExpandableTrieBuffer(maxTrieSize), mTerminalPositionLookupTable(),
191dc3856d7589aa3cf3dcfdee8360fa48a85983273Keisuke Kuroyanagi          mLanguageModelDictContent(headerPolicy->hasHistoricalInfoOfWords()),
192fe395232d69df0887863c1cbabe63def2586d29eKeisuke Kuroyanagi          mShortcutDictContent(),  mIsUpdatable(true) {}
1932fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa
1942fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa} // namespace latinime
195