From 5bf1be71629607e7206e6203489cf742d2f8ed79 Mon Sep 17 00:00:00 2001 From: Keisuke Kuroynagi Date: Wed, 26 Jun 2013 12:51:33 +0900 Subject: [PATCH] Add jni methods for dynamically handling a dictionary. Bug: 6669677 Change-Id: I8a26623adbb41a78e3c023c652be635c635e3b47 --- .../inputmethod/latin/BinaryDictionary.java | 6 +- ...oid_inputmethod_latin_BinaryDictionary.cpp | 80 ++++++++++++++++--- .../core/dictionary/bigram_dictionary.cpp | 8 +- .../suggest/core/dictionary/dictionary.cpp | 33 +++++++- .../src/suggest/core/dictionary/dictionary.h | 13 ++- 5 files changed, 119 insertions(+), 21 deletions(-) diff --git a/java/src/com/android/inputmethod/latin/BinaryDictionary.java b/java/src/com/android/inputmethod/latin/BinaryDictionary.java index f36c9e878..c355fd60a 100644 --- a/java/src/com/android/inputmethod/latin/BinaryDictionary.java +++ b/java/src/com/android/inputmethod/latin/BinaryDictionary.java @@ -97,7 +97,7 @@ public final class BinaryDictionary extends Dictionary { 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); + private static native boolean isValidBigramNative(long dict, int[] word0, int[] word1); private static native int getSuggestionsNative(long dict, long proximityInfo, long traverseSession, int[] xCoordinates, int[] yCoordinates, int[] times, int[] pointerIds, int[] inputCodePoints, int inputSize, int commitPoint, @@ -105,6 +105,10 @@ public final class BinaryDictionary extends Dictionary { int[] outputCodePoints, int[] outputScores, int[] outputIndices, int[] outputTypes); private static native float calcNormalizedScoreNative(int[] before, int[] after, int score); private static native int editDistanceNative(int[] before, int[] after); + private static native void addUnigramWordNative(long dict, int[] word, int probability); + private static native void addBigramWordsNative(long dict, int[] word0, int[] word1, + int probability); + private static native void removeBigramWordsNative(long dict, int[] word0, int[] word1); // TODO: Move native dict into session private final void loadDictionary(final String path, final long startOffset, diff --git a/native/jni/com_android_inputmethod_latin_BinaryDictionary.cpp b/native/jni/com_android_inputmethod_latin_BinaryDictionary.cpp index b856718c6..33b6a6f1b 100644 --- a/native/jni/com_android_inputmethod_latin_BinaryDictionary.cpp +++ b/native/jni/com_android_inputmethod_latin_BinaryDictionary.cpp @@ -176,26 +176,26 @@ static int latinime_BinaryDictionary_getSuggestions(JNIEnv *env, jclass clazz, j } static jint latinime_BinaryDictionary_getProbability(JNIEnv *env, jclass clazz, jlong dict, - jintArray wordArray) { + jintArray word) { Dictionary *dictionary = reinterpret_cast(dict); if (!dictionary) return 0; - const jsize codePointLength = env->GetArrayLength(wordArray); - int codePoints[codePointLength]; - env->GetIntArrayRegion(wordArray, 0, codePointLength, codePoints); - return dictionary->getProbability(codePoints, codePointLength); + const jsize wordLength = env->GetArrayLength(word); + int codePoints[wordLength]; + env->GetIntArrayRegion(word, 0, wordLength, codePoints); + return dictionary->getProbability(codePoints, wordLength); } static jboolean latinime_BinaryDictionary_isValidBigram(JNIEnv *env, jclass clazz, jlong dict, - jintArray wordArray1, jintArray wordArray2) { + jintArray word0, jintArray word1) { Dictionary *dictionary = reinterpret_cast(dict); if (!dictionary) return JNI_FALSE; - const jsize codePointLength1 = env->GetArrayLength(wordArray1); - const jsize codePointLength2 = env->GetArrayLength(wordArray2); - int codePoints1[codePointLength1]; - int codePoints2[codePointLength2]; - env->GetIntArrayRegion(wordArray1, 0, codePointLength1, codePoints1); - env->GetIntArrayRegion(wordArray2, 0, codePointLength2, codePoints2); - return dictionary->isValidBigram(codePoints1, codePointLength1, codePoints2, codePointLength2); + const jsize word0Length = env->GetArrayLength(word0); + const jsize word1Length = env->GetArrayLength(word1); + int word0CodePoints[word0Length]; + int word1CodePoints[word1Length]; + env->GetIntArrayRegion(word0, 0, word0Length, word0CodePoints); + env->GetIntArrayRegion(word1, 0, word1Length, word1CodePoints); + return dictionary->isValidBigram(word0CodePoints, word0Length, word1CodePoints, word1Length); } static jfloat latinime_BinaryDictionary_calcNormalizedScore(JNIEnv *env, jclass clazz, @@ -246,6 +246,45 @@ static void releaseDictBuf(const void *dictBuf, const size_t length, const int f } } +static void latinime_BinaryDictionary_addUnigramWord(JNIEnv *env, jclass clazz, jlong dict, + jintArray word, jint probability) { + Dictionary *dictionary = reinterpret_cast(dict); + if (!dictionary) { + return; + } + jsize wordLength = env->GetArrayLength(word); + int codePoints[wordLength]; + dictionary->addUnigramWord(codePoints, wordLength, probability); +} + +static void latinime_BinaryDictionary_addBigramWords(JNIEnv *env, jclass clazz, jlong dict, + jintArray word0, jintArray word1, jint probability) { + Dictionary *dictionary = reinterpret_cast(dict); + if (!dictionary) { + return; + } + jsize word0Length = env->GetArrayLength(word0); + int word0CodePoints[word0Length]; + jsize word1Length = env->GetArrayLength(word1); + int word1CodePoints[word1Length]; + dictionary->addBigramWords(word0CodePoints, word0Length, word1CodePoints, + word1Length, probability); +} + +static void latinime_BinaryDictionary_removeBigramWords(JNIEnv *env, jclass clazz, jlong dict, + jintArray word0, jintArray word1) { + Dictionary *dictionary = reinterpret_cast(dict); + if (!dictionary) { + return; + } + jsize word0Length = env->GetArrayLength(word0); + int word0CodePoints[word0Length]; + jsize word1Length = env->GetArrayLength(word1); + int word1CodePoints[word1Length]; + dictionary->removeBigramWords(word0CodePoints, word0Length, word1CodePoints, + word1Length); +} + static const JNINativeMethod sMethods[] = { { const_cast("openNative"), @@ -281,6 +320,21 @@ static const JNINativeMethod sMethods[] = { const_cast("editDistanceNative"), const_cast("([I[I)I"), reinterpret_cast(latinime_BinaryDictionary_editDistance) + }, + { + const_cast("addUnigramWordNative"), + const_cast("(J[II)V"), + reinterpret_cast(latinime_BinaryDictionary_addUnigramWord) + }, + { + const_cast("addBigramWordsNative"), + const_cast("(J[I[II)V"), + reinterpret_cast(latinime_BinaryDictionary_addBigramWords) + }, + { + const_cast("removeBigramWordsNative"), + const_cast("(J[I[I)V"), + reinterpret_cast(latinime_BinaryDictionary_removeBigramWords) } }; diff --git a/native/jni/src/suggest/core/dictionary/bigram_dictionary.cpp b/native/jni/src/suggest/core/dictionary/bigram_dictionary.cpp index 6e02100fc..242a9bdd6 100644 --- a/native/jni/src/suggest/core/dictionary/bigram_dictionary.cpp +++ b/native/jni/src/suggest/core/dictionary/bigram_dictionary.cpp @@ -184,13 +184,13 @@ bool BigramDictionary::checkFirstCharacter(int *word, int *inputCodePoints) cons return false; } -bool BigramDictionary::isValidBigram(const int *word1, int length1, const int *word2, - int length2) const { - int pos = getBigramListPositionForWord(word1, length1, false /* forceLowerCaseSearch */); +bool BigramDictionary::isValidBigram(const int *word0, int length0, const int *word1, + int length1) const { + int pos = getBigramListPositionForWord(word0, length0, false /* forceLowerCaseSearch */); // getBigramListPositionForWord returns 0 if this word isn't in the dictionary or has no bigrams if (0 == pos) return false; int nextWordPos = BinaryFormat::getTerminalPosition(mBinaryDictionaryInfo->getDictRoot(), - word2, length2, false /* forceLowerCaseSearch */); + word1, length1, false /* forceLowerCaseSearch */); if (NOT_VALID_WORD == nextWordPos) return false; for (BinaryDictionaryBigramsIterator bigramsIt(mBinaryDictionaryInfo, pos); diff --git a/native/jni/src/suggest/core/dictionary/dictionary.cpp b/native/jni/src/suggest/core/dictionary/dictionary.cpp index 028b61506..51f23dc55 100644 --- a/native/jni/src/suggest/core/dictionary/dictionary.cpp +++ b/native/jni/src/suggest/core/dictionary/dictionary.cpp @@ -106,8 +106,37 @@ int Dictionary::getProbability(const int *word, int length) const { return unigramProbability; } -bool Dictionary::isValidBigram(const int *word1, int length1, const int *word2, int length2) const { - return mBigramDictionary->isValidBigram(word1, length1, word2, length2); +bool Dictionary::isValidBigram(const int *word0, int length0, const int *word1, int length1) const { + return mBigramDictionary->isValidBigram(word0, length0, word1, length1); +} + +void Dictionary::addUnigramWord(const int *const word, const int length, const int probability) { + if (!mBinaryDictionaryInfo.isDynamicallyUpdatable()) { + // This method should not be called for non-updatable dictionary. + AKLOGI("Warning: Dictionary::addUnigramWord() is called for non-updatable dictionary."); + return; + } + // TODO: Support dynamic update +} + +void Dictionary::addBigramWords(const int *const word0, const int length0, const int *const word1, + const int length1, const int probability) { + if (!mBinaryDictionaryInfo.isDynamicallyUpdatable()) { + // This method should not be called for non-updatable dictionary. + AKLOGI("Warning: Dictionary::addBigramWords() is called for non-updatable dictionary."); + return; + } + // TODO: Support dynamic update +} + +void Dictionary::removeBigramWords(const int *const word0, const int length0, + const int *const word1, const int length1) { + if (!mBinaryDictionaryInfo.isDynamicallyUpdatable()) { + // This method should not be called for non-updatable dictionary. + AKLOGI("Warning: Dictionary::removeBigramWords() is called for non-updatable dictionary."); + return; + } + // TODO: Support dynamic update } } // namespace latinime diff --git a/native/jni/src/suggest/core/dictionary/dictionary.h b/native/jni/src/suggest/core/dictionary/dictionary.h index afd081841..94579c200 100644 --- a/native/jni/src/suggest/core/dictionary/dictionary.h +++ b/native/jni/src/suggest/core/dictionary/dictionary.h @@ -64,10 +64,21 @@ class Dictionary { int *frequencies, int *outputTypes) const; int getProbability(const int *word, int length) const; - bool isValidBigram(const int *word1, int length1, const int *word2, int length2) const; + + bool isValidBigram(const int *word0, int length0, const int *word1, int length1) const; + + void addUnigramWord(const int *const word, const int length, const int probability); + + void addBigramWords(const int *const word0, const int length0, const int *const word1, + const int length1, const int probability); + + void removeBigramWords(const int *const word0, const int length0, const int *const word1, + const int length1); + const BinaryDictionaryInfo *getBinaryDictionaryInfo() const { return &mBinaryDictionaryInfo; } + virtual ~Dictionary(); private: