ver4_dict_buffers.cpp revision c0c674cdc0721a374e140ad5ee1409c0498b3262
1/*
2 * Copyright (C) 2013 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17/*
18 * !!!!! DO NOT EDIT THIS FILE !!!!!
19 *
20 * This file was generated from
21 *   suggest/policyimpl/dictionary/structure/v4/ver4_dict_buffers.cpp
22 */
23
24#include "suggest/policyimpl/dictionary/structure/backward/v402/ver4_dict_buffers.h"
25
26#include <cerrno>
27#include <cstring>
28#include <sys/stat.h>
29#include <sys/types.h>
30
31#include "suggest/policyimpl/dictionary/utils/dict_file_writing_utils.h"
32#include "suggest/policyimpl/dictionary/utils/file_utils.h"
33#include "utils/byte_array_view.h"
34
35namespace latinime {
36namespace backward {
37namespace v402 {
38
39/* static */ Ver4DictBuffers::Ver4DictBuffersPtr Ver4DictBuffers::openVer4DictBuffers(
40        const char *const dictPath, MmappedBuffer::MmappedBufferPtr headerBuffer,
41        const FormatUtils::FORMAT_VERSION formatVersion) {
42    if (!headerBuffer) {
43        ASSERT(false);
44        AKLOGE("The header buffer must be valid to open ver4 dict buffers.");
45        return Ver4DictBuffersPtr(nullptr);
46    }
47    // TODO: take only dictDirPath, and open both header and trie files in the constructor below
48    const bool isUpdatable = headerBuffer->isUpdatable();
49    return Ver4DictBuffersPtr(new Ver4DictBuffers(dictPath, std::move(headerBuffer), isUpdatable,
50            formatVersion));
51}
52
53bool Ver4DictBuffers::flushHeaderAndDictBuffers(const char *const dictDirPath,
54        const BufferWithExtendableBuffer *const headerBuffer) const {
55    // Create temporary directory.
56    const int tmpDirPathBufSize = FileUtils::getFilePathWithSuffixBufSize(dictDirPath,
57            DictFileWritingUtils::TEMP_FILE_SUFFIX_FOR_WRITING_DICT_FILE);
58    char tmpDirPath[tmpDirPathBufSize];
59    FileUtils::getFilePathWithSuffix(dictDirPath,
60            DictFileWritingUtils::TEMP_FILE_SUFFIX_FOR_WRITING_DICT_FILE, tmpDirPathBufSize,
61            tmpDirPath);
62    if (FileUtils::existsDir(tmpDirPath)) {
63        if (!FileUtils::removeDirAndFiles(tmpDirPath)) {
64            AKLOGE("Existing directory %s cannot be removed.", tmpDirPath);
65            ASSERT(false);
66            return false;
67        }
68    }
69    umask(S_IWGRP | S_IWOTH);
70    if (mkdir(tmpDirPath, S_IRWXU) == -1) {
71        AKLOGE("Cannot create directory: %s. errno: %d.", tmpDirPath, errno);
72        return false;
73    }
74    // Get dictionary base path.
75    const int dictNameBufSize = strlen(dictDirPath) + 1 /* terminator */;
76    char dictName[dictNameBufSize];
77    FileUtils::getBasename(dictDirPath, dictNameBufSize, dictName);
78    const int dictPathBufSize = FileUtils::getFilePathBufSize(tmpDirPath, dictName);
79    char dictPath[dictPathBufSize];
80    FileUtils::getFilePath(tmpDirPath, dictName, dictPathBufSize, dictPath);
81
82    // Write header file.
83    if (!DictFileWritingUtils::flushBufferToFileWithSuffix(dictPath,
84            Ver4DictConstants::HEADER_FILE_EXTENSION, headerBuffer)) {
85        AKLOGE("Dictionary header file %s%s cannot be written.", tmpDirPath,
86                Ver4DictConstants::HEADER_FILE_EXTENSION);
87        return false;
88    }
89    // Write trie file.
90    if (!DictFileWritingUtils::flushBufferToFileWithSuffix(dictPath,
91            Ver4DictConstants::TRIE_FILE_EXTENSION, &mExpandableTrieBuffer)) {
92        AKLOGE("Dictionary trie file %s%s cannot be written.", tmpDirPath,
93                Ver4DictConstants::TRIE_FILE_EXTENSION);
94        return false;
95    }
96    // Write dictionary contents.
97    if (!mTerminalPositionLookupTable.flushToFile(dictPath)) {
98        AKLOGE("Terminal position lookup table cannot be written. %s", tmpDirPath);
99        return false;
100    }
101    if (!mProbabilityDictContent.flushToFile(dictPath)) {
102        AKLOGE("Probability dict content cannot be written. %s", tmpDirPath);
103        return false;
104    }
105    if (!mBigramDictContent.flushToFile(dictPath)) {
106        AKLOGE("Bigram dict content cannot be written. %s", tmpDirPath);
107        return false;
108    }
109    if (!mShortcutDictContent.flushToFile(dictPath)) {
110        AKLOGE("Shortcut dict content cannot be written. %s", tmpDirPath);
111        return false;
112    }
113    // Remove existing dictionary.
114    if (!FileUtils::removeDirAndFiles(dictDirPath)) {
115        AKLOGE("Existing directory %s cannot be removed.", dictDirPath);
116        ASSERT(false);
117        return false;
118    }
119    // Rename temporary directory.
120    if (rename(tmpDirPath, dictDirPath) != 0) {
121        AKLOGE("%s cannot be renamed to %s", tmpDirPath, dictDirPath);
122        ASSERT(false);
123        return false;
124    }
125    return true;
126}
127
128Ver4DictBuffers::Ver4DictBuffers(const char *const dictPath,
129        MmappedBuffer::MmappedBufferPtr headerBuffer, const bool isUpdatable,
130        const FormatUtils::FORMAT_VERSION formatVersion)
131        : mHeaderBuffer(std::move(headerBuffer)),
132          mDictBuffer(MmappedBuffer::openBuffer(dictPath,
133                  Ver4DictConstants::TRIE_FILE_EXTENSION, isUpdatable)),
134          mHeaderPolicy(mHeaderBuffer->getReadOnlyByteArrayView().data(), formatVersion),
135          mExpandableHeaderBuffer(mHeaderBuffer->getReadWriteByteArrayView(),
136                  BufferWithExtendableBuffer::DEFAULT_MAX_ADDITIONAL_BUFFER_SIZE),
137          mExpandableTrieBuffer(
138                  mDictBuffer ? mDictBuffer->getReadWriteByteArrayView() :
139                          ReadWriteByteArrayView(),
140                  BufferWithExtendableBuffer::DEFAULT_MAX_ADDITIONAL_BUFFER_SIZE),
141          mTerminalPositionLookupTable(dictPath, isUpdatable),
142          mProbabilityDictContent(dictPath, mHeaderPolicy.hasHistoricalInfoOfWords(), isUpdatable),
143          mBigramDictContent(dictPath, mHeaderPolicy.hasHistoricalInfoOfWords(), isUpdatable),
144          mShortcutDictContent(dictPath, isUpdatable),
145          mIsUpdatable(isUpdatable) {}
146
147Ver4DictBuffers::Ver4DictBuffers(const HeaderPolicy *const headerPolicy, const int maxTrieSize)
148        : mHeaderBuffer(nullptr), mDictBuffer(nullptr), mHeaderPolicy(headerPolicy),
149          mExpandableHeaderBuffer(Ver4DictConstants::MAX_DICTIONARY_SIZE),
150          mExpandableTrieBuffer(maxTrieSize), mTerminalPositionLookupTable(),
151          mProbabilityDictContent(headerPolicy->hasHistoricalInfoOfWords()),
152          mBigramDictContent(headerPolicy->hasHistoricalInfoOfWords()), mShortcutDictContent(),
153          mIsUpdatable(true) {}
154
155} // namespace v402
156} // namespace backward
157} // namespace latinime
158