Use JNI Region calls also in getSuggestions()
Change-Id: I9cc0208397c202aeb6f7b5bb5ad59e00c5afbd80
This commit is contained in:
parent
f6c2200890
commit
f3850e5543
3 changed files with 73 additions and 52 deletions
|
@ -51,7 +51,8 @@ public class BinaryDictionary extends Dictionary {
|
||||||
private static final int TYPED_LETTER_MULTIPLIER = 2;
|
private static final int TYPED_LETTER_MULTIPLIER = 2;
|
||||||
|
|
||||||
private long mNativeDict;
|
private long mNativeDict;
|
||||||
private final int[] mInputCodes = new int[MAX_WORD_LENGTH];
|
private final int[] mInputCodePoints = new int[MAX_WORD_LENGTH];
|
||||||
|
// TODO: The below should be int[] mOutputCodePoints
|
||||||
private final char[] mOutputChars = new char[MAX_WORD_LENGTH * MAX_RESULTS];
|
private final char[] mOutputChars = new char[MAX_WORD_LENGTH * MAX_RESULTS];
|
||||||
private final int[] mSpaceIndices = new int[MAX_SPACES];
|
private final int[] mSpaceIndices = new int[MAX_SPACES];
|
||||||
private final int[] mOutputScores = new int[MAX_RESULTS];
|
private final int[] mOutputScores = new int[MAX_RESULTS];
|
||||||
|
@ -92,7 +93,7 @@ public class BinaryDictionary extends Dictionary {
|
||||||
private native boolean isValidBigramNative(long dict, int[] word1, int[] word2);
|
private native boolean isValidBigramNative(long dict, int[] word1, int[] word2);
|
||||||
private native int getSuggestionsNative(long dict, long proximityInfo, long traverseSession,
|
private native int getSuggestionsNative(long dict, long proximityInfo, long traverseSession,
|
||||||
int[] xCoordinates, int[] yCoordinates, int[] times, int[] pointerIds,
|
int[] xCoordinates, int[] yCoordinates, int[] times, int[] pointerIds,
|
||||||
int[] inputCodes, int codesSize, int commitPoint, boolean isGesture,
|
int[] inputCodePoints, int codesSize, int commitPoint, boolean isGesture,
|
||||||
int[] prevWordCodePointArray, boolean useFullEditDistance, char[] outputChars,
|
int[] prevWordCodePointArray, boolean useFullEditDistance, char[] outputChars,
|
||||||
int[] outputScores, int[] outputIndices, int[] outputTypes);
|
int[] outputScores, int[] outputIndices, int[] outputTypes);
|
||||||
private static native float calcNormalizedScoreNative(char[] before, char[] after, int score);
|
private static native float calcNormalizedScoreNative(char[] before, char[] after, int score);
|
||||||
|
@ -108,9 +109,7 @@ public class BinaryDictionary extends Dictionary {
|
||||||
public ArrayList<SuggestedWordInfo> getSuggestions(final WordComposer composer,
|
public ArrayList<SuggestedWordInfo> getSuggestions(final WordComposer composer,
|
||||||
final CharSequence prevWord, final ProximityInfo proximityInfo) {
|
final CharSequence prevWord, final ProximityInfo proximityInfo) {
|
||||||
if (!isValidDictionary()) return null;
|
if (!isValidDictionary()) return null;
|
||||||
Arrays.fill(mInputCodes, WordComposer.NOT_A_CODE);
|
Arrays.fill(mInputCodePoints, WordComposer.NOT_A_CODE);
|
||||||
Arrays.fill(mOutputChars, (char) 0);
|
|
||||||
Arrays.fill(mOutputScores, 0);
|
|
||||||
// TODO: toLowerCase in the native code
|
// TODO: toLowerCase in the native code
|
||||||
final int[] prevWordCodePointArray = (null == prevWord)
|
final int[] prevWordCodePointArray = (null == prevWord)
|
||||||
? null : StringUtils.toCodePointArray(prevWord.toString());
|
? null : StringUtils.toCodePointArray(prevWord.toString());
|
||||||
|
@ -120,7 +119,7 @@ public class BinaryDictionary extends Dictionary {
|
||||||
if (composerSize <= 1 || !isGesture) {
|
if (composerSize <= 1 || !isGesture) {
|
||||||
if (composerSize > MAX_WORD_LENGTH - 1) return null;
|
if (composerSize > MAX_WORD_LENGTH - 1) return null;
|
||||||
for (int i = 0; i < composerSize; i++) {
|
for (int i = 0; i < composerSize; i++) {
|
||||||
mInputCodes[i] = composer.getCodeAt(i);
|
mInputCodePoints[i] = composer.getCodeAt(i);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -128,10 +127,9 @@ public class BinaryDictionary extends Dictionary {
|
||||||
final int codesSize = isGesture ? ips.getPointerSize() : composerSize;
|
final int codesSize = isGesture ? ips.getPointerSize() : composerSize;
|
||||||
// proximityInfo and/or prevWordForBigrams may not be null.
|
// proximityInfo and/or prevWordForBigrams may not be null.
|
||||||
final int tmpCount = getSuggestionsNative(mNativeDict,
|
final int tmpCount = getSuggestionsNative(mNativeDict,
|
||||||
proximityInfo.getNativeProximityInfo(),
|
proximityInfo.getNativeProximityInfo(), mDicTraverseSession.getSession(),
|
||||||
mDicTraverseSession.getSession(), ips.getXCoordinates(),
|
ips.getXCoordinates(), ips.getYCoordinates(), ips.getTimes(), ips.getPointerIds(),
|
||||||
ips.getYCoordinates(), ips.getTimes(), ips.getPointerIds(),
|
mInputCodePoints, codesSize, 0 /* commitPoint */, isGesture, prevWordCodePointArray,
|
||||||
mInputCodes, codesSize, 0 /* commitPoint */, isGesture, prevWordCodePointArray,
|
|
||||||
mUseFullEditDistance, mOutputChars, mOutputScores, mSpaceIndices, mOutputTypes);
|
mUseFullEditDistance, mOutputChars, mOutputScores, mSpaceIndices, mOutputTypes);
|
||||||
final int count = Math.min(tmpCount, MAX_PREDICTIONS);
|
final int count = Math.min(tmpCount, MAX_PREDICTIONS);
|
||||||
|
|
||||||
|
|
|
@ -14,15 +14,12 @@
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#include <cstring> // for memset()
|
||||||
|
|
||||||
#define LOG_TAG "LatinIME: jni: BinaryDictionary"
|
#define LOG_TAG "LatinIME: jni: BinaryDictionary"
|
||||||
|
|
||||||
#include "binary_format.h"
|
#include "defines.h" // for macros below
|
||||||
#include "com_android_inputmethod_latin_BinaryDictionary.h"
|
|
||||||
#include "correction.h"
|
|
||||||
#include "defines.h"
|
|
||||||
#include "dictionary.h"
|
|
||||||
#include "jni.h"
|
|
||||||
#include "jni_common.h"
|
|
||||||
|
|
||||||
#ifdef USE_MMAP_FOR_DICTIONARY
|
#ifdef USE_MMAP_FOR_DICTIONARY
|
||||||
#include <cerrno>
|
#include <cerrno>
|
||||||
|
@ -32,6 +29,13 @@
|
||||||
#include <cstdlib>
|
#include <cstdlib>
|
||||||
#endif // USE_MMAP_FOR_DICTIONARY
|
#endif // USE_MMAP_FOR_DICTIONARY
|
||||||
|
|
||||||
|
#include "binary_format.h"
|
||||||
|
#include "com_android_inputmethod_latin_BinaryDictionary.h"
|
||||||
|
#include "correction.h"
|
||||||
|
#include "dictionary.h"
|
||||||
|
#include "jni.h"
|
||||||
|
#include "jni_common.h"
|
||||||
|
|
||||||
namespace latinime {
|
namespace latinime {
|
||||||
|
|
||||||
class ProximityInfo;
|
class ProximityInfo;
|
||||||
|
@ -124,50 +128,71 @@ static jlong latinime_BinaryDictionary_open(JNIEnv *env, jobject object,
|
||||||
|
|
||||||
static int latinime_BinaryDictionary_getSuggestions(JNIEnv *env, jobject object, jlong dict,
|
static int latinime_BinaryDictionary_getSuggestions(JNIEnv *env, jobject object, jlong dict,
|
||||||
jlong proximityInfo, jlong dicTraverseSession, jintArray xCoordinatesArray,
|
jlong proximityInfo, jlong dicTraverseSession, jintArray xCoordinatesArray,
|
||||||
jintArray yCoordinatesArray, jintArray timesArray, jintArray pointerIdArray,
|
jintArray yCoordinatesArray, jintArray timesArray, jintArray pointerIdsArray,
|
||||||
jintArray inputArray, jint arraySize, jint commitPoint, jboolean isGesture,
|
jintArray inputCodePointsArray, jint arraySize, jint commitPoint, jboolean isGesture,
|
||||||
jintArray prevWordForBigrams, jboolean useFullEditDistance, jcharArray outputArray,
|
jintArray prevWordCodePointsForBigrams, jboolean useFullEditDistance,
|
||||||
jintArray frequencyArray, jintArray spaceIndexArray, jintArray outputTypesArray) {
|
jcharArray outputCharsArray, jintArray scoresArray, jintArray spaceIndicesArray,
|
||||||
|
jintArray outputTypesArray) {
|
||||||
Dictionary *dictionary = reinterpret_cast<Dictionary*>(dict);
|
Dictionary *dictionary = reinterpret_cast<Dictionary*>(dict);
|
||||||
if (!dictionary) return 0;
|
if (!dictionary) return 0;
|
||||||
ProximityInfo *pInfo = reinterpret_cast<ProximityInfo*>(proximityInfo);
|
ProximityInfo *pInfo = reinterpret_cast<ProximityInfo*>(proximityInfo);
|
||||||
void *traverseSession = reinterpret_cast<void*>(dicTraverseSession);
|
void *traverseSession = reinterpret_cast<void*>(dicTraverseSession);
|
||||||
int *xCoordinates = env->GetIntArrayElements(xCoordinatesArray, 0);
|
|
||||||
int *yCoordinates = env->GetIntArrayElements(yCoordinatesArray, 0);
|
// Input values
|
||||||
int *times = env->GetIntArrayElements(timesArray, 0);
|
int xCoordinates[arraySize];
|
||||||
int *pointerIds = env->GetIntArrayElements(pointerIdArray, 0);
|
int yCoordinates[arraySize];
|
||||||
int *frequencies = env->GetIntArrayElements(frequencyArray, 0);
|
int times[arraySize];
|
||||||
int *inputCodes = env->GetIntArrayElements(inputArray, 0);
|
int pointerIds[arraySize];
|
||||||
jchar *outputChars = env->GetCharArrayElements(outputArray, 0);
|
const jsize inputCodePointsLength = env->GetArrayLength(inputCodePointsArray);
|
||||||
int *spaceIndices = env->GetIntArrayElements(spaceIndexArray, 0);
|
int inputCodePoints[inputCodePointsLength];
|
||||||
int *outputTypes = env->GetIntArrayElements(outputTypesArray, 0);
|
const jsize prevWordCodePointsLength =
|
||||||
jint *prevWordChars = prevWordForBigrams
|
prevWordCodePointsForBigrams ? env->GetArrayLength(prevWordCodePointsForBigrams) : 0;
|
||||||
? env->GetIntArrayElements(prevWordForBigrams, 0) : 0;
|
int prevWordCodePointsInternal[prevWordCodePointsLength];
|
||||||
jsize prevWordLength = prevWordChars ? env->GetArrayLength(prevWordForBigrams) : 0;
|
int *prevWordCodePoints = 0;
|
||||||
|
env->GetIntArrayRegion(xCoordinatesArray, 0, arraySize, xCoordinates);
|
||||||
|
env->GetIntArrayRegion(yCoordinatesArray, 0, arraySize, yCoordinates);
|
||||||
|
env->GetIntArrayRegion(timesArray, 0, arraySize, times);
|
||||||
|
env->GetIntArrayRegion(pointerIdsArray, 0, arraySize, pointerIds);
|
||||||
|
env->GetIntArrayRegion(inputCodePointsArray, 0, inputCodePointsLength, inputCodePoints);
|
||||||
|
if (prevWordCodePointsForBigrams) {
|
||||||
|
env->GetIntArrayRegion(prevWordCodePointsForBigrams, 0, prevWordCodePointsLength,
|
||||||
|
prevWordCodePointsInternal);
|
||||||
|
prevWordCodePoints = prevWordCodePointsInternal;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Output values
|
||||||
|
// TODO: Should be "outputCodePointsLength" and "int outputCodePoints[]"
|
||||||
|
const jsize outputCharsLength = env->GetArrayLength(outputCharsArray);
|
||||||
|
unsigned short outputChars[outputCharsLength];
|
||||||
|
const jsize scoresLength = env->GetArrayLength(scoresArray);
|
||||||
|
int scores[scoresLength];
|
||||||
|
const jsize spaceIndicesLength = env->GetArrayLength(spaceIndicesArray);
|
||||||
|
int spaceIndices[spaceIndicesLength];
|
||||||
|
const jsize outputTypesLength = env->GetArrayLength(outputTypesArray);
|
||||||
|
int outputTypes[outputTypesLength];
|
||||||
|
memset(outputChars, 0, outputCharsLength);
|
||||||
|
memset(scores, 0, scoresLength);
|
||||||
|
memset(spaceIndices, 0, spaceIndicesLength);
|
||||||
|
memset(outputTypes, 0, outputTypesLength);
|
||||||
|
|
||||||
int count;
|
int count;
|
||||||
if (isGesture || arraySize > 1) {
|
if (isGesture || arraySize > 1) {
|
||||||
count = dictionary->getSuggestions(pInfo, traverseSession, xCoordinates, yCoordinates,
|
count = dictionary->getSuggestions(pInfo, traverseSession, xCoordinates, yCoordinates,
|
||||||
times, pointerIds, inputCodes, arraySize, prevWordChars, prevWordLength,
|
times, pointerIds, inputCodePoints, arraySize, prevWordCodePoints,
|
||||||
commitPoint, isGesture, useFullEditDistance, (unsigned short*) outputChars,
|
prevWordCodePointsLength, commitPoint, isGesture, useFullEditDistance, outputChars,
|
||||||
frequencies, spaceIndices, outputTypes);
|
scores, spaceIndices, outputTypes);
|
||||||
} else {
|
} else {
|
||||||
count = dictionary->getBigrams(prevWordChars, prevWordLength, inputCodes,
|
count = dictionary->getBigrams(prevWordCodePoints, prevWordCodePointsLength,
|
||||||
arraySize, (unsigned short*) outputChars, frequencies, outputTypes);
|
inputCodePoints, arraySize, outputChars, scores, outputTypes);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (prevWordChars) {
|
// Copy back the output values
|
||||||
env->ReleaseIntArrayElements(prevWordForBigrams, prevWordChars, JNI_ABORT);
|
// TODO: Should be SetIntArrayRegion()
|
||||||
}
|
env->SetCharArrayRegion(outputCharsArray, 0, outputCharsLength, outputChars);
|
||||||
env->ReleaseIntArrayElements(outputTypesArray, outputTypes, 0);
|
env->SetIntArrayRegion(scoresArray, 0, scoresLength, scores);
|
||||||
env->ReleaseIntArrayElements(spaceIndexArray, spaceIndices, 0);
|
env->SetIntArrayRegion(spaceIndicesArray, 0, spaceIndicesLength, spaceIndices);
|
||||||
env->ReleaseCharArrayElements(outputArray, outputChars, 0);
|
env->SetIntArrayRegion(outputTypesArray, 0, outputTypesLength, outputTypes);
|
||||||
env->ReleaseIntArrayElements(inputArray, inputCodes, JNI_ABORT);
|
|
||||||
env->ReleaseIntArrayElements(frequencyArray, frequencies, 0);
|
|
||||||
env->ReleaseIntArrayElements(pointerIdArray, pointerIds, 0);
|
|
||||||
env->ReleaseIntArrayElements(timesArray, times, 0);
|
|
||||||
env->ReleaseIntArrayElements(yCoordinatesArray, yCoordinates, 0);
|
|
||||||
env->ReleaseIntArrayElements(xCoordinatesArray, xCoordinates, 0);
|
|
||||||
return count;
|
return count;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -154,8 +154,6 @@ void Correction::checkState() {
|
||||||
if (mSkipPos >= 0) ++inputCount;
|
if (mSkipPos >= 0) ++inputCount;
|
||||||
if (mExcessivePos >= 0) ++inputCount;
|
if (mExcessivePos >= 0) ++inputCount;
|
||||||
if (mTransposedPos >= 0) ++inputCount;
|
if (mTransposedPos >= 0) ++inputCount;
|
||||||
// TODO: remove this assert
|
|
||||||
assert(inputCount <= 1);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue