Use JNI Region calls also in getSuggestions()

Change-Id: I9cc0208397c202aeb6f7b5bb5ad59e00c5afbd80
This commit is contained in:
Ken Wakasa 2012-08-10 17:16:39 +09:00
parent f6c2200890
commit f3850e5543
3 changed files with 73 additions and 52 deletions

View File

@ -51,7 +51,8 @@ public class BinaryDictionary extends Dictionary {
private static final int TYPED_LETTER_MULTIPLIER = 2;
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 int[] mSpaceIndices = new int[MAX_SPACES];
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 int getSuggestionsNative(long dict, long proximityInfo, long traverseSession,
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[] outputScores, int[] outputIndices, int[] outputTypes);
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,
final CharSequence prevWord, final ProximityInfo proximityInfo) {
if (!isValidDictionary()) return null;
Arrays.fill(mInputCodes, WordComposer.NOT_A_CODE);
Arrays.fill(mOutputChars, (char) 0);
Arrays.fill(mOutputScores, 0);
Arrays.fill(mInputCodePoints, WordComposer.NOT_A_CODE);
// TODO: toLowerCase in the native code
final int[] prevWordCodePointArray = (null == prevWord)
? null : StringUtils.toCodePointArray(prevWord.toString());
@ -120,7 +119,7 @@ public class BinaryDictionary extends Dictionary {
if (composerSize <= 1 || !isGesture) {
if (composerSize > MAX_WORD_LENGTH - 1) return null;
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;
// proximityInfo and/or prevWordForBigrams may not be null.
final int tmpCount = getSuggestionsNative(mNativeDict,
proximityInfo.getNativeProximityInfo(),
mDicTraverseSession.getSession(), ips.getXCoordinates(),
ips.getYCoordinates(), ips.getTimes(), ips.getPointerIds(),
mInputCodes, codesSize, 0 /* commitPoint */, isGesture, prevWordCodePointArray,
proximityInfo.getNativeProximityInfo(), mDicTraverseSession.getSession(),
ips.getXCoordinates(), ips.getYCoordinates(), ips.getTimes(), ips.getPointerIds(),
mInputCodePoints, codesSize, 0 /* commitPoint */, isGesture, prevWordCodePointArray,
mUseFullEditDistance, mOutputChars, mOutputScores, mSpaceIndices, mOutputTypes);
final int count = Math.min(tmpCount, MAX_PREDICTIONS);

View File

@ -14,15 +14,12 @@
* limitations under the License.
*/
#include <cstring> // for memset()
#define LOG_TAG "LatinIME: jni: BinaryDictionary"
#include "binary_format.h"
#include "com_android_inputmethod_latin_BinaryDictionary.h"
#include "correction.h"
#include "defines.h"
#include "dictionary.h"
#include "jni.h"
#include "jni_common.h"
#include "defines.h" // for macros below
#ifdef USE_MMAP_FOR_DICTIONARY
#include <cerrno>
@ -32,6 +29,13 @@
#include <cstdlib>
#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 {
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,
jlong proximityInfo, jlong dicTraverseSession, jintArray xCoordinatesArray,
jintArray yCoordinatesArray, jintArray timesArray, jintArray pointerIdArray,
jintArray inputArray, jint arraySize, jint commitPoint, jboolean isGesture,
jintArray prevWordForBigrams, jboolean useFullEditDistance, jcharArray outputArray,
jintArray frequencyArray, jintArray spaceIndexArray, jintArray outputTypesArray) {
jintArray yCoordinatesArray, jintArray timesArray, jintArray pointerIdsArray,
jintArray inputCodePointsArray, jint arraySize, jint commitPoint, jboolean isGesture,
jintArray prevWordCodePointsForBigrams, jboolean useFullEditDistance,
jcharArray outputCharsArray, jintArray scoresArray, jintArray spaceIndicesArray,
jintArray outputTypesArray) {
Dictionary *dictionary = reinterpret_cast<Dictionary*>(dict);
if (!dictionary) return 0;
ProximityInfo *pInfo = reinterpret_cast<ProximityInfo*>(proximityInfo);
void *traverseSession = reinterpret_cast<void*>(dicTraverseSession);
int *xCoordinates = env->GetIntArrayElements(xCoordinatesArray, 0);
int *yCoordinates = env->GetIntArrayElements(yCoordinatesArray, 0);
int *times = env->GetIntArrayElements(timesArray, 0);
int *pointerIds = env->GetIntArrayElements(pointerIdArray, 0);
int *frequencies = env->GetIntArrayElements(frequencyArray, 0);
int *inputCodes = env->GetIntArrayElements(inputArray, 0);
jchar *outputChars = env->GetCharArrayElements(outputArray, 0);
int *spaceIndices = env->GetIntArrayElements(spaceIndexArray, 0);
int *outputTypes = env->GetIntArrayElements(outputTypesArray, 0);
jint *prevWordChars = prevWordForBigrams
? env->GetIntArrayElements(prevWordForBigrams, 0) : 0;
jsize prevWordLength = prevWordChars ? env->GetArrayLength(prevWordForBigrams) : 0;
// Input values
int xCoordinates[arraySize];
int yCoordinates[arraySize];
int times[arraySize];
int pointerIds[arraySize];
const jsize inputCodePointsLength = env->GetArrayLength(inputCodePointsArray);
int inputCodePoints[inputCodePointsLength];
const jsize prevWordCodePointsLength =
prevWordCodePointsForBigrams ? env->GetArrayLength(prevWordCodePointsForBigrams) : 0;
int prevWordCodePointsInternal[prevWordCodePointsLength];
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;
if (isGesture || arraySize > 1) {
count = dictionary->getSuggestions(pInfo, traverseSession, xCoordinates, yCoordinates,
times, pointerIds, inputCodes, arraySize, prevWordChars, prevWordLength,
commitPoint, isGesture, useFullEditDistance, (unsigned short*) outputChars,
frequencies, spaceIndices, outputTypes);
times, pointerIds, inputCodePoints, arraySize, prevWordCodePoints,
prevWordCodePointsLength, commitPoint, isGesture, useFullEditDistance, outputChars,
scores, spaceIndices, outputTypes);
} else {
count = dictionary->getBigrams(prevWordChars, prevWordLength, inputCodes,
arraySize, (unsigned short*) outputChars, frequencies, outputTypes);
count = dictionary->getBigrams(prevWordCodePoints, prevWordCodePointsLength,
inputCodePoints, arraySize, outputChars, scores, outputTypes);
}
if (prevWordChars) {
env->ReleaseIntArrayElements(prevWordForBigrams, prevWordChars, JNI_ABORT);
}
env->ReleaseIntArrayElements(outputTypesArray, outputTypes, 0);
env->ReleaseIntArrayElements(spaceIndexArray, spaceIndices, 0);
env->ReleaseCharArrayElements(outputArray, outputChars, 0);
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);
// Copy back the output values
// TODO: Should be SetIntArrayRegion()
env->SetCharArrayRegion(outputCharsArray, 0, outputCharsLength, outputChars);
env->SetIntArrayRegion(scoresArray, 0, scoresLength, scores);
env->SetIntArrayRegion(spaceIndicesArray, 0, spaceIndicesLength, spaceIndices);
env->SetIntArrayRegion(outputTypesArray, 0, outputTypesLength, outputTypes);
return count;
}

View File

@ -154,8 +154,6 @@ void Correction::checkState() {
if (mSkipPos >= 0) ++inputCount;
if (mExcessivePos >= 0) ++inputCount;
if (mTransposedPos >= 0) ++inputCount;
// TODO: remove this assert
assert(inputCount <= 1);
}
}