dictionary_structure_with_buffer_policy_factory.cpp revision 455dc84cf2c6526329b535f30000ea45b7d4d4d7
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/dictionary_structure_with_buffer_policy_factory.h" 182fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa 192fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa#include <climits> 202fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa 212fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa#include "defines.h" 223b7984752c88bff157016a09158dc92d94ed401dKeisuke Kuroyanagi#include "suggest/policyimpl/dictionary/structure/pt_common/dynamic_pt_writing_utils.h" 232fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa#include "suggest/policyimpl/dictionary/structure/v2/patricia_trie_policy.h" 242fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa#include "suggest/policyimpl/dictionary/structure/v4/ver4_dict_buffers.h" 252fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa#include "suggest/policyimpl/dictionary/structure/v4/ver4_dict_constants.h" 262fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa#include "suggest/policyimpl/dictionary/structure/v4/ver4_patricia_trie_policy.h" 273b7984752c88bff157016a09158dc92d94ed401dKeisuke Kuroyanagi#include "suggest/policyimpl/dictionary/utils/dict_file_writing_utils.h" 282fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa#include "suggest/policyimpl/dictionary/utils/file_utils.h" 292fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa#include "suggest/policyimpl/dictionary/utils/format_utils.h" 302fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa#include "suggest/policyimpl/dictionary/utils/mmapped_buffer.h" 312fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa 322fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasanamespace latinime { 332fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa 342fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa/* static */ DictionaryStructureWithBufferPolicy::StructurePolicyPtr 35903be5bbd33b664c7e691d8bee0dd4d6376947bcKeisuke Kuroyanagi DictionaryStructureWithBufferPolicyFactory::newPolicyForExistingDictFile( 36903be5bbd33b664c7e691d8bee0dd4d6376947bcKeisuke Kuroyanagi const char *const path, const int bufOffset, const int size, 37903be5bbd33b664c7e691d8bee0dd4d6376947bcKeisuke Kuroyanagi const bool isUpdatable) { 382fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa if (FileUtils::existsDir(path)) { 392fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa // Given path represents a directory. 40903be5bbd33b664c7e691d8bee0dd4d6376947bcKeisuke Kuroyanagi return newPolicyForDirectoryDict(path, isUpdatable); 412fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa } else { 422fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa if (isUpdatable) { 432fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa AKLOGE("One file dictionaries don't support updating. path: %s", path); 442fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa ASSERT(false); 454ce480d5ce2d47f607448ce439aaf2cefba1bdd8Keisuke Kuroyanagi return DictionaryStructureWithBufferPolicy::StructurePolicyPtr(nullptr); 462fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa } 47903be5bbd33b664c7e691d8bee0dd4d6376947bcKeisuke Kuroyanagi return newPolicyForFileDict(path, bufOffset, size); 482fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa } 492fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa} 502fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa 512fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa/* static */ DictionaryStructureWithBufferPolicy::StructurePolicyPtr 52903be5bbd33b664c7e691d8bee0dd4d6376947bcKeisuke Kuroyanagi DictionaryStructureWithBufferPolicyFactory:: newPolicyForOnMemoryDict( 53903be5bbd33b664c7e691d8bee0dd4d6376947bcKeisuke Kuroyanagi const int formatVersion, const std::vector<int> &locale, 54903be5bbd33b664c7e691d8bee0dd4d6376947bcKeisuke Kuroyanagi const DictionaryHeaderStructurePolicy::AttributeMap *const attributeMap) { 55455dc84cf2c6526329b535f30000ea45b7d4d4d7Keisuke Kuroyanagi FormatUtils::FORMAT_VERSION dictFormatVersion = FormatUtils::getFormatVersion(formatVersion); 56455dc84cf2c6526329b535f30000ea45b7d4d4d7Keisuke Kuroyanagi switch (dictFormatVersion) { 57455dc84cf2c6526329b535f30000ea45b7d4d4d7Keisuke Kuroyanagi case FormatUtils::VERSION_4_ONLY_FOR_TESTING: 58903be5bbd33b664c7e691d8bee0dd4d6376947bcKeisuke Kuroyanagi case FormatUtils::VERSION_4: { 59455dc84cf2c6526329b535f30000ea45b7d4d4d7Keisuke Kuroyanagi HeaderPolicy headerPolicy(dictFormatVersion, locale, attributeMap); 60903be5bbd33b664c7e691d8bee0dd4d6376947bcKeisuke Kuroyanagi Ver4DictBuffers::Ver4DictBuffersPtr dictBuffers = 61903be5bbd33b664c7e691d8bee0dd4d6376947bcKeisuke Kuroyanagi Ver4DictBuffers::createVer4DictBuffers(&headerPolicy, 62903be5bbd33b664c7e691d8bee0dd4d6376947bcKeisuke Kuroyanagi Ver4DictConstants::MAX_DICT_EXTENDED_REGION_SIZE); 633b7984752c88bff157016a09158dc92d94ed401dKeisuke Kuroyanagi if (!DynamicPtWritingUtils::writeEmptyDictionary( 643b7984752c88bff157016a09158dc92d94ed401dKeisuke Kuroyanagi dictBuffers->getWritableTrieBuffer(), 0 /* rootPos */)) { 653b7984752c88bff157016a09158dc92d94ed401dKeisuke Kuroyanagi AKLOGE("Empty ver4 dictionary structure cannot be created on memory."); 663b7984752c88bff157016a09158dc92d94ed401dKeisuke Kuroyanagi return DictionaryStructureWithBufferPolicy::StructurePolicyPtr(nullptr); 673b7984752c88bff157016a09158dc92d94ed401dKeisuke Kuroyanagi } 68903be5bbd33b664c7e691d8bee0dd4d6376947bcKeisuke Kuroyanagi return DictionaryStructureWithBufferPolicy::StructurePolicyPtr( 69903be5bbd33b664c7e691d8bee0dd4d6376947bcKeisuke Kuroyanagi new Ver4PatriciaTriePolicy(std::move(dictBuffers))); 70903be5bbd33b664c7e691d8bee0dd4d6376947bcKeisuke Kuroyanagi } 71903be5bbd33b664c7e691d8bee0dd4d6376947bcKeisuke Kuroyanagi default: 72903be5bbd33b664c7e691d8bee0dd4d6376947bcKeisuke Kuroyanagi AKLOGE("DICT: dictionary format %d is not supported for on memory dictionary", 73903be5bbd33b664c7e691d8bee0dd4d6376947bcKeisuke Kuroyanagi formatVersion); 74903be5bbd33b664c7e691d8bee0dd4d6376947bcKeisuke Kuroyanagi break; 75903be5bbd33b664c7e691d8bee0dd4d6376947bcKeisuke Kuroyanagi } 76903be5bbd33b664c7e691d8bee0dd4d6376947bcKeisuke Kuroyanagi return DictionaryStructureWithBufferPolicy::StructurePolicyPtr(nullptr); 77903be5bbd33b664c7e691d8bee0dd4d6376947bcKeisuke Kuroyanagi} 78903be5bbd33b664c7e691d8bee0dd4d6376947bcKeisuke Kuroyanagi 79903be5bbd33b664c7e691d8bee0dd4d6376947bcKeisuke Kuroyanagi/* static */ DictionaryStructureWithBufferPolicy::StructurePolicyPtr 80903be5bbd33b664c7e691d8bee0dd4d6376947bcKeisuke Kuroyanagi DictionaryStructureWithBufferPolicyFactory::newPolicyForDirectoryDict( 812fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa const char *const path, const bool isUpdatable) { 822fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa const int headerFilePathBufSize = PATH_MAX + 1 /* terminator */; 832fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa char headerFilePath[headerFilePathBufSize]; 842fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa getHeaderFilePathInDictDir(path, headerFilePathBufSize, headerFilePath); 852fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa // Allocated buffer in MmapedBuffer::openBuffer() will be freed in the destructor of 862fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa // MmappedBufferPtr if the instance has the responsibility. 874ce480d5ce2d47f607448ce439aaf2cefba1bdd8Keisuke Kuroyanagi MmappedBuffer::MmappedBufferPtr mmappedBuffer( 884ce480d5ce2d47f607448ce439aaf2cefba1bdd8Keisuke Kuroyanagi MmappedBuffer::openBuffer(headerFilePath, isUpdatable)); 894ce480d5ce2d47f607448ce439aaf2cefba1bdd8Keisuke Kuroyanagi if (!mmappedBuffer) { 904ce480d5ce2d47f607448ce439aaf2cefba1bdd8Keisuke Kuroyanagi return DictionaryStructureWithBufferPolicy::StructurePolicyPtr(nullptr); 912fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa } 92455dc84cf2c6526329b535f30000ea45b7d4d4d7Keisuke Kuroyanagi const FormatUtils::FORMAT_VERSION formatVersion = FormatUtils::detectFormatVersion( 93455dc84cf2c6526329b535f30000ea45b7d4d4d7Keisuke Kuroyanagi mmappedBuffer->getBuffer(), mmappedBuffer->getBufferSize()); 94455dc84cf2c6526329b535f30000ea45b7d4d4d7Keisuke Kuroyanagi switch (formatVersion) { 952fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa case FormatUtils::VERSION_2: 962fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa AKLOGE("Given path is a directory but the format is version 2. path: %s", path); 972fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa break; 98455dc84cf2c6526329b535f30000ea45b7d4d4d7Keisuke Kuroyanagi case FormatUtils::VERSION_4_ONLY_FOR_TESTING: 992fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa case FormatUtils::VERSION_4: { 1002fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa const int dictDirPathBufSize = strlen(headerFilePath) + 1 /* terminator */; 1012fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa char dictPath[dictDirPathBufSize]; 1022fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa if (!FileUtils::getFilePathWithoutSuffix(headerFilePath, 1032fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa Ver4DictConstants::HEADER_FILE_EXTENSION, dictDirPathBufSize, dictPath)) { 1042fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa AKLOGE("Dictionary file name is not valid as a ver4 dictionary. path: %s", path); 1052fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa ASSERT(false); 1064ce480d5ce2d47f607448ce439aaf2cefba1bdd8Keisuke Kuroyanagi return DictionaryStructureWithBufferPolicy::StructurePolicyPtr(nullptr); 1072fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa } 1084ce480d5ce2d47f607448ce439aaf2cefba1bdd8Keisuke Kuroyanagi Ver4DictBuffers::Ver4DictBuffersPtr dictBuffers( 109455dc84cf2c6526329b535f30000ea45b7d4d4d7Keisuke Kuroyanagi Ver4DictBuffers::openVer4DictBuffers(dictPath, std::move(mmappedBuffer), 110455dc84cf2c6526329b535f30000ea45b7d4d4d7Keisuke Kuroyanagi formatVersion)); 1114ce480d5ce2d47f607448ce439aaf2cefba1bdd8Keisuke Kuroyanagi if (!dictBuffers || !dictBuffers->isValid()) { 1122fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa AKLOGE("DICT: The dictionary doesn't satisfy ver4 format requirements. path: %s", 1132fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa path); 1142fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa ASSERT(false); 1154ce480d5ce2d47f607448ce439aaf2cefba1bdd8Keisuke Kuroyanagi return DictionaryStructureWithBufferPolicy::StructurePolicyPtr(nullptr); 1162fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa } 1172fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa return DictionaryStructureWithBufferPolicy::StructurePolicyPtr( 1184ce480d5ce2d47f607448ce439aaf2cefba1bdd8Keisuke Kuroyanagi new Ver4PatriciaTriePolicy(std::move(dictBuffers))); 1192fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa } 1202fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa default: 1212fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa AKLOGE("DICT: dictionary format is unknown, bad magic number. path: %s", path); 1222fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa break; 1232fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa } 1242fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa ASSERT(false); 1254ce480d5ce2d47f607448ce439aaf2cefba1bdd8Keisuke Kuroyanagi return DictionaryStructureWithBufferPolicy::StructurePolicyPtr(nullptr); 1262fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa} 1272fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa 1282fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa/* static */ DictionaryStructureWithBufferPolicy::StructurePolicyPtr 129903be5bbd33b664c7e691d8bee0dd4d6376947bcKeisuke Kuroyanagi DictionaryStructureWithBufferPolicyFactory::newPolicyForFileDict( 1302fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa const char *const path, const int bufOffset, const int size) { 1312fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa // Allocated buffer in MmapedBuffer::openBuffer() will be freed in the destructor of 1322fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa // MmappedBufferPtr if the instance has the responsibility. 1334ce480d5ce2d47f607448ce439aaf2cefba1bdd8Keisuke Kuroyanagi MmappedBuffer::MmappedBufferPtr mmappedBuffer( 1344ce480d5ce2d47f607448ce439aaf2cefba1bdd8Keisuke Kuroyanagi MmappedBuffer::openBuffer(path, bufOffset, size, false /* isUpdatable */)); 1354ce480d5ce2d47f607448ce439aaf2cefba1bdd8Keisuke Kuroyanagi if (!mmappedBuffer) { 1364ce480d5ce2d47f607448ce439aaf2cefba1bdd8Keisuke Kuroyanagi return DictionaryStructureWithBufferPolicy::StructurePolicyPtr(nullptr); 1372fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa } 1384ce480d5ce2d47f607448ce439aaf2cefba1bdd8Keisuke Kuroyanagi switch (FormatUtils::detectFormatVersion(mmappedBuffer->getBuffer(), 1394ce480d5ce2d47f607448ce439aaf2cefba1bdd8Keisuke Kuroyanagi mmappedBuffer->getBufferSize())) { 1402fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa case FormatUtils::VERSION_2: 1412fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa return DictionaryStructureWithBufferPolicy::StructurePolicyPtr( 1424ce480d5ce2d47f607448ce439aaf2cefba1bdd8Keisuke Kuroyanagi new PatriciaTriePolicy(std::move(mmappedBuffer))); 143455dc84cf2c6526329b535f30000ea45b7d4d4d7Keisuke Kuroyanagi case FormatUtils::VERSION_4_ONLY_FOR_TESTING: 1442fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa case FormatUtils::VERSION_4: 1452fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa AKLOGE("Given path is a file but the format is version 4. path: %s", path); 1462fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa break; 1472fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa default: 1482fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa AKLOGE("DICT: dictionary format is unknown, bad magic number. path: %s", path); 1492fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa break; 1502fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa } 1512fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa ASSERT(false); 1524ce480d5ce2d47f607448ce439aaf2cefba1bdd8Keisuke Kuroyanagi return DictionaryStructureWithBufferPolicy::StructurePolicyPtr(nullptr); 1532fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa} 1542fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa 1552fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa/* static */ void DictionaryStructureWithBufferPolicyFactory::getHeaderFilePathInDictDir( 1562fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa const char *const dictDirPath, const int outHeaderFileBufSize, 1572fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa char *const outHeaderFilePath) { 1582fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa const int dictNameBufSize = strlen(dictDirPath) + 1 /* terminator */; 1592fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa char dictName[dictNameBufSize]; 1602fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa FileUtils::getBasename(dictDirPath, dictNameBufSize, dictName); 1612fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa snprintf(outHeaderFilePath, outHeaderFileBufSize, "%s/%s%s", dictDirPath, 1622fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa dictName, Ver4DictConstants::HEADER_FILE_EXTENSION); 1632fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa} 1642fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa 1652fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa} // namespace latinime 166