From f3b62900c7bcb0d6434f45ec7b467b7b4bad6f9a Mon Sep 17 00:00:00 2001 From: Keisuke Kuroynagi Date: Tue, 25 Jun 2013 14:25:01 +0900 Subject: [PATCH] Allow mmapping dictionary file in writable mode in openNative. Bug: 6669677 Change-Id: I447668932de118b158fa029ddc977b3f3cc06cb8 --- .../inputmethod/latin/BinaryDictionary.java | 5 +++-- ..._android_inputmethod_latin_BinaryDictionary.cpp | 14 +++++++++----- .../core/dictionary/binary_dictionary_info.h | 5 +++-- .../jni/src/suggest/core/dictionary/dictionary.cpp | 6 +++--- .../jni/src/suggest/core/dictionary/dictionary.h | 2 +- 5 files changed, 19 insertions(+), 13 deletions(-) diff --git a/java/src/com/android/inputmethod/latin/BinaryDictionary.java b/java/src/com/android/inputmethod/latin/BinaryDictionary.java index 05b1a2ee1..4425d7d25 100644 --- a/java/src/com/android/inputmethod/latin/BinaryDictionary.java +++ b/java/src/com/android/inputmethod/latin/BinaryDictionary.java @@ -91,7 +91,8 @@ public final class BinaryDictionary extends Dictionary { JniUtils.loadNativeLibrary(); } - private static native long openNative(String sourceDir, long dictOffset, long dictSize); + private static native long openNative(String sourceDir, long dictOffset, long dictSize, + boolean isUpdatable); private static native void closeNative(long dict); private static native int getProbabilityNative(long dict, int[] word); private static native boolean isValidBigramNative(long dict, int[] word1, int[] word2); @@ -106,7 +107,7 @@ public final class BinaryDictionary extends Dictionary { // TODO: Move native dict into session private final void loadDictionary(final String path, final long startOffset, final long length) { - mNativeDict = openNative(path, startOffset, length); + mNativeDict = openNative(path, startOffset, length, false /* isUpdatable */); } @Override diff --git a/native/jni/com_android_inputmethod_latin_BinaryDictionary.cpp b/native/jni/com_android_inputmethod_latin_BinaryDictionary.cpp index cbe7ce451..b856718c6 100644 --- a/native/jni/com_android_inputmethod_latin_BinaryDictionary.cpp +++ b/native/jni/com_android_inputmethod_latin_BinaryDictionary.cpp @@ -40,7 +40,7 @@ class ProximityInfo; static void releaseDictBuf(const void *dictBuf, const size_t length, const int fd); static jlong latinime_BinaryDictionary_open(JNIEnv *env, jclass clazz, jstring sourceDir, - jlong dictOffset, jlong dictSize) { + jlong dictOffset, jlong dictSize, jboolean isUpdatable) { PROF_OPEN; PROF_START(66); const jsize sourceDirUtf8Length = env->GetStringUTFLength(sourceDir); @@ -54,7 +54,9 @@ static jlong latinime_BinaryDictionary_open(JNIEnv *env, jclass clazz, jstring s int fd = 0; void *dictBuf = 0; int offset = 0; - fd = open(sourceDirChars, O_RDONLY); + const bool updatableMmap = (isUpdatable == JNI_TRUE); + const int openMode = updatableMmap ? O_RDWR : O_RDONLY; + fd = open(sourceDirChars, openMode); if (fd < 0) { AKLOGE("DICT: Can't open sourceDir. sourceDirChars=%s errno=%d", sourceDirChars, errno); return 0; @@ -63,7 +65,8 @@ static jlong latinime_BinaryDictionary_open(JNIEnv *env, jclass clazz, jstring s offset = static_cast(dictOffset) % pagesize; int adjDictOffset = static_cast(dictOffset) - offset; int adjDictSize = static_cast(dictSize) + offset; - dictBuf = mmap(0, adjDictSize, PROT_READ, MAP_PRIVATE, fd, adjDictOffset); + const int protMode = updatableMmap ? PROT_READ | PROT_WRITE : PROT_READ; + dictBuf = mmap(0, adjDictSize, protMode, MAP_PRIVATE, fd, adjDictOffset); if (dictBuf == MAP_FAILED) { AKLOGE("DICT: Can't mmap dictionary. errno=%d", errno); return 0; @@ -80,7 +83,8 @@ static jlong latinime_BinaryDictionary_open(JNIEnv *env, jclass clazz, jstring s AKLOGE("DICT: dictionary format is unknown, bad magic number"); releaseDictBuf(static_cast(dictBuf) - offset, adjDictSize, fd); } else { - dictionary = new Dictionary(dictBuf, static_cast(dictSize), fd, offset); + dictionary = new Dictionary( + dictBuf, static_cast(dictSize), fd, offset, updatableMmap); } PROF_END(66); PROF_CLOSE; @@ -245,7 +249,7 @@ static void releaseDictBuf(const void *dictBuf, const size_t length, const int f static const JNINativeMethod sMethods[] = { { const_cast("openNative"), - const_cast("(Ljava/lang/String;JJ)J"), + const_cast("(Ljava/lang/String;JJZ)J"), reinterpret_cast(latinime_BinaryDictionary_open) }, { diff --git a/native/jni/src/suggest/core/dictionary/binary_dictionary_info.h b/native/jni/src/suggest/core/dictionary/binary_dictionary_info.h index c16b5310d..399817981 100644 --- a/native/jni/src/suggest/core/dictionary/binary_dictionary_info.h +++ b/native/jni/src/suggest/core/dictionary/binary_dictionary_info.h @@ -30,9 +30,9 @@ class BinaryDictionaryHeader; class BinaryDictionaryInfo { public: BinaryDictionaryInfo(const uint8_t *const dictBuf, const int dictSize, const int mmapFd, - const int dictBufOffset) + const int dictBufOffset, const bool isUpdatable) : mDictBuf(dictBuf), mDictSize(dictSize), mMmapFd(mmapFd), - mDictBufOffset(dictBufOffset), + mDictBufOffset(dictBufOffset), mIsUpdatable(isUpdatable), mDictionaryFormat(BinaryDictionaryFormat::detectFormatVersion(mDictBuf, mDictSize)), mDictionaryHeader(this), mDictRoot(mDictBuf + mDictionaryHeader.getSize()) {} @@ -75,6 +75,7 @@ class BinaryDictionaryInfo { const int mDictSize; const int mMmapFd; const int mDictBufOffset; + const bool mIsUpdatable; const BinaryDictionaryFormat::FORMAT_VERSION mDictionaryFormat; const BinaryDictionaryHeader mDictionaryHeader; const uint8_t *const mDictRoot; diff --git a/native/jni/src/suggest/core/dictionary/dictionary.cpp b/native/jni/src/suggest/core/dictionary/dictionary.cpp index b92e5644c..028b61506 100644 --- a/native/jni/src/suggest/core/dictionary/dictionary.cpp +++ b/native/jni/src/suggest/core/dictionary/dictionary.cpp @@ -32,9 +32,9 @@ namespace latinime { -Dictionary::Dictionary(void *dict, int dictSize, int mmapFd, int dictBufOffset) - : mBinaryDictionaryInfo( - static_cast(dict), dictSize, mmapFd, dictBufOffset), +Dictionary::Dictionary(void *dict, int dictSize, int mmapFd, int dictBufOffset, bool isUpdatable) + : mBinaryDictionaryInfo(static_cast(dict), dictSize, mmapFd, + dictBufOffset, isUpdatable), mBigramDictionary(new BigramDictionary(&mBinaryDictionaryInfo)), mGestureSuggest(new Suggest(GestureSuggestPolicyFactory::getGestureSuggestPolicy())), mTypingSuggest(new Suggest(TypingSuggestPolicyFactory::getTypingSuggestPolicy())) { diff --git a/native/jni/src/suggest/core/dictionary/dictionary.h b/native/jni/src/suggest/core/dictionary/dictionary.h index 12884a430..afd081841 100644 --- a/native/jni/src/suggest/core/dictionary/dictionary.h +++ b/native/jni/src/suggest/core/dictionary/dictionary.h @@ -52,7 +52,7 @@ class Dictionary { static const int KIND_FLAG_POSSIBLY_OFFENSIVE = 0x80000000; static const int KIND_FLAG_EXACT_MATCH = 0x40000000; - Dictionary(void *dict, int dictSize, int mmapFd, int dictBufOffset); + Dictionary(void *dict, int dictSize, int mmapFd, int dictBufOffset, bool isUpdatable); int getSuggestions(ProximityInfo *proximityInfo, DicTraverseSession *traverseSession, int *xcoordinates, int *ycoordinates, int *times, int *pointerIds, int *inputCodePoints,