diff options
author | 2014-05-08 12:31:32 +0900 | |
---|---|---|
committer | 2014-05-08 12:31:32 +0900 | |
commit | 8a9d9de72a9ab02cb4726c205213d4f0b9f58e07 (patch) | |
tree | bf30c75461e19fc7e39d78481e36d7c738ac2812 /native/jni/com_android_inputmethod_latin_BinaryDictionary.cpp | |
parent | 1471fbad66f68a06494ac3efea5d9d16ea46b322 (diff) | |
download | latinime-8a9d9de72a9ab02cb4726c205213d4f0b9f58e07.tar.gz latinime-8a9d9de72a9ab02cb4726c205213d4f0b9f58e07.tar.xz latinime-8a9d9de72a9ab02cb4726c205213d4f0b9f58e07.zip |
Implement migrateNative().
Bug: 13406708
Change-Id: Ie786a68e780baa298fedf82d21390ba45d871a52
Diffstat (limited to 'native/jni/com_android_inputmethod_latin_BinaryDictionary.cpp')
-rw-r--r-- | native/jni/com_android_inputmethod_latin_BinaryDictionary.cpp | 76 |
1 files changed, 74 insertions, 2 deletions
diff --git a/native/jni/com_android_inputmethod_latin_BinaryDictionary.cpp b/native/jni/com_android_inputmethod_latin_BinaryDictionary.cpp index 8648d8dde..3ac424fea 100644 --- a/native/jni/com_android_inputmethod_latin_BinaryDictionary.cpp +++ b/native/jni/com_android_inputmethod_latin_BinaryDictionary.cpp @@ -32,6 +32,7 @@ #include "suggest/policyimpl/dictionary/structure/dictionary_structure_with_buffer_policy_factory.h" #include "utils/char_utils.h" #include "utils/jni_data_utils.h" +#include "utils/log_utils.h" #include "utils/time_keeper.h" namespace latinime { @@ -489,14 +490,85 @@ static bool latinime_BinaryDictionary_isCorruptedNative(JNIEnv *env, jclass claz return dictionary->getDictionaryStructurePolicy()->isCorrupted(); } +static DictionaryStructureWithBufferPolicy::StructurePolicyPtr runGCAndGetNewStructurePolicy( + DictionaryStructureWithBufferPolicy::StructurePolicyPtr structurePolicy, + const char *const dictFilePath) { + structurePolicy->flushWithGC(dictFilePath); + structurePolicy.release(); + return DictionaryStructureWithBufferPolicyFactory::newPolicyForExistingDictFile( + dictFilePath, 0 /* offset */, 0 /* size */, true /* isUpdatable */); +} + static bool latinime_BinaryDictionary_migrateNative(JNIEnv *env, jclass clazz, jlong dict, jstring dictFilePath, jlong newFormatVersion) { Dictionary *dictionary = reinterpret_cast<Dictionary *>(dict); if (!dictionary) { return false; } - // TODO: Implement. - return false; + const jsize filePathUtf8Length = env->GetStringUTFLength(dictFilePath); + char dictFilePathChars[filePathUtf8Length + 1]; + env->GetStringUTFRegion(dictFilePath, 0, env->GetStringLength(dictFilePath), dictFilePathChars); + dictFilePathChars[filePathUtf8Length] = '\0'; + + const DictionaryHeaderStructurePolicy *const headerPolicy = + dictionary->getDictionaryStructurePolicy()->getHeaderStructurePolicy(); + DictionaryStructureWithBufferPolicy::StructurePolicyPtr dictionaryStructureWithBufferPolicy = + DictionaryStructureWithBufferPolicyFactory::newPolicyForOnMemoryDict( + newFormatVersion, *headerPolicy->getLocale(), headerPolicy->getAttributeMap()); + if (!dictionaryStructureWithBufferPolicy) { + LogUtils::logToJava(env, "Cannot migrate header."); + return false; + } + + // TODO: Migrate historical information. + int wordCodePoints[MAX_WORD_LENGTH]; + int token = 0; + // Add unigrams. + do { + token = dictionary->getNextWordAndNextToken(token, wordCodePoints); + const int wordLength = CharUtils::getCodePointCount(MAX_WORD_LENGTH, wordCodePoints); + const WordProperty wordProperty = dictionary->getWordProperty(wordCodePoints, wordLength); + if (dictionaryStructureWithBufferPolicy->needsToRunGC(true /* mindsBlockByGC */)) { + dictionaryStructureWithBufferPolicy = runGCAndGetNewStructurePolicy( + std::move(dictionaryStructureWithBufferPolicy), dictFilePathChars); + if (!dictionaryStructureWithBufferPolicy) { + LogUtils::logToJava(env, "Cannot open dict after GC."); + return false; + } + } + if (!dictionaryStructureWithBufferPolicy->addUnigramWord(wordCodePoints, wordLength, + wordProperty.getUnigramProperty())) { + LogUtils::logToJava(env, "Cannot add unigram to the new dict."); + return false; + } + } while (token != 0); + + // Add bigrams. + do { + token = dictionary->getNextWordAndNextToken(token, wordCodePoints); + const int wordLength = CharUtils::getCodePointCount(MAX_WORD_LENGTH, wordCodePoints); + const WordProperty wordProperty = dictionary->getWordProperty(wordCodePoints, wordLength); + if (dictionaryStructureWithBufferPolicy->needsToRunGC(true /* mindsBlockByGC */)) { + dictionaryStructureWithBufferPolicy = runGCAndGetNewStructurePolicy( + std::move(dictionaryStructureWithBufferPolicy), dictFilePathChars); + if (!dictionaryStructureWithBufferPolicy) { + LogUtils::logToJava(env, "Cannot open dict after GC."); + return false; + } + } + for (const BigramProperty &bigarmProperty : *wordProperty.getBigramProperties()) { + const std::vector<int> *targetCodePoints = bigarmProperty.getTargetCodePoints(); + if (!dictionaryStructureWithBufferPolicy->addBigramWords(wordCodePoints, wordLength, + targetCodePoints->data(), targetCodePoints->size(), + bigarmProperty.getProbability(), bigarmProperty.getTimestamp())) { + LogUtils::logToJava(env, "Cannot add bigram to the new dict."); + return false; + } + } + } while (token != 0); + // Save to File. + dictionaryStructureWithBufferPolicy->flushWithGC(dictFilePathChars); + return true; } static const JNINativeMethod sMethods[] = { |