Merge "Introduce SuggestionResults and use it for predictions."

main
Keisuke Kuroyanagi 2014-03-07 10:38:22 +00:00 committed by Android (Google) Code Review
commit ee5d8441d1
10 changed files with 274 additions and 109 deletions

View File

@ -87,6 +87,7 @@ public final class BinaryDictionary extends Dictionary {
private final String mDictFilePath; private final String mDictFilePath;
private final boolean mIsUpdatable; private final boolean mIsUpdatable;
private final int[] mInputCodePoints = new int[MAX_WORD_LENGTH]; private final int[] mInputCodePoints = new int[MAX_WORD_LENGTH];
private final int[] mOutputSuggestionCount = new int[1];
private final int[] mOutputCodePoints = new int[MAX_WORD_LENGTH * MAX_RESULTS]; private final int[] mOutputCodePoints = new int[MAX_WORD_LENGTH * MAX_RESULTS];
private final int[] mSpaceIndices = new int[MAX_RESULTS]; private final int[] mSpaceIndices = new int[MAX_RESULTS];
private final int[] mOutputScores = new int[MAX_RESULTS]; private final int[] mOutputScores = new int[MAX_RESULTS];
@ -158,10 +159,10 @@ public final class BinaryDictionary extends Dictionary {
ArrayList<int[]> outBigramTargets, ArrayList<int[]> outBigramProbabilityInfo, ArrayList<int[]> outBigramTargets, ArrayList<int[]> outBigramProbabilityInfo,
ArrayList<int[]> outShortcutTargets, ArrayList<Integer> outShortcutProbabilities); ArrayList<int[]> outShortcutTargets, ArrayList<Integer> outShortcutProbabilities);
private static native int getNextWordNative(long dict, int token, int[] outCodePoints); private static native int getNextWordNative(long dict, int token, int[] outCodePoints);
private static native int getSuggestionsNative(long dict, long proximityInfo, private static native void getSuggestionsNative(long dict, long proximityInfo,
long traverseSession, int[] xCoordinates, int[] yCoordinates, int[] times, long traverseSession, int[] xCoordinates, int[] yCoordinates, int[] times,
int[] pointerIds, int[] inputCodePoints, int inputSize, int commitPoint, int[] pointerIds, int[] inputCodePoints, int inputSize, int commitPoint,
int[] suggestOptions, int[] prevWordCodePointArray, int[] suggestOptions, int[] prevWordCodePointArray, int[] outputSuggestionCount,
int[] outputCodePoints, int[] outputScores, int[] outputIndices, int[] outputTypes, int[] outputCodePoints, int[] outputScores, int[] outputIndices, int[] outputTypes,
int[] outputAutoCommitFirstWordConfidence); int[] outputAutoCommitFirstWordConfidence);
private static native void addUnigramWordNative(long dict, int[] word, int probability, private static native void addUnigramWordNative(long dict, int[] word, int probability,
@ -258,12 +259,13 @@ public final class BinaryDictionary extends Dictionary {
mNativeSuggestOptions.setIsGesture(isGesture); mNativeSuggestOptions.setIsGesture(isGesture);
mNativeSuggestOptions.setAdditionalFeaturesOptions(additionalFeaturesOptions); mNativeSuggestOptions.setAdditionalFeaturesOptions(additionalFeaturesOptions);
// proximityInfo and/or prevWordForBigrams may not be null. // proximityInfo and/or prevWordForBigrams may not be null.
final int count = getSuggestionsNative(mNativeDict, proximityInfo.getNativeProximityInfo(), getSuggestionsNative(mNativeDict, proximityInfo.getNativeProximityInfo(),
getTraverseSession(sessionId).getSession(), ips.getXCoordinates(), getTraverseSession(sessionId).getSession(), ips.getXCoordinates(),
ips.getYCoordinates(), ips.getTimes(), ips.getPointerIds(), mInputCodePoints, ips.getYCoordinates(), ips.getTimes(), ips.getPointerIds(), mInputCodePoints,
inputSize, 0 /* commitPoint */, mNativeSuggestOptions.getOptions(), inputSize, 0 /* commitPoint */, mNativeSuggestOptions.getOptions(),
prevWordCodePointArray, mOutputCodePoints, mOutputScores, mSpaceIndices, prevWordCodePointArray, mOutputSuggestionCount, mOutputCodePoints, mOutputScores,
mOutputTypes, mOutputAutoCommitFirstWordConfidence); mSpaceIndices, mOutputTypes, mOutputAutoCommitFirstWordConfidence);
final int count = mOutputSuggestionCount[0];
final ArrayList<SuggestedWordInfo> suggestions = CollectionUtils.newArrayList(); final ArrayList<SuggestedWordInfo> suggestions = CollectionUtils.newArrayList();
for (int j = 0; j < count; ++j) { for (int j = 0; j < count; ++j) {
final int start = j * MAX_WORD_LENGTH; final int start = j * MAX_WORD_LENGTH;

View File

@ -40,8 +40,10 @@ LATIN_IME_CORE_SRC_FILES := \
proximity_info_state.cpp \ proximity_info_state.cpp \
proximity_info_state_utils.cpp) \ proximity_info_state_utils.cpp) \
suggest/core/policy/weighting.cpp \ suggest/core/policy/weighting.cpp \
suggest/core/result/suggestions_output_utils.cpp \
suggest/core/session/dic_traverse_session.cpp \ suggest/core/session/dic_traverse_session.cpp \
$(addprefix suggest/core/result/, \
suggestion_results.cpp \
suggestions_output_utils.cpp) \
$(addprefix suggest/policyimpl/dictionary/, \ $(addprefix suggest/policyimpl/dictionary/, \
header/header_policy.cpp \ header/header_policy.cpp \
header/header_read_write_utils.cpp \ header/header_read_write_utils.cpp \

View File

@ -25,6 +25,7 @@
#include "jni_common.h" #include "jni_common.h"
#include "suggest/core/dictionary/dictionary.h" #include "suggest/core/dictionary/dictionary.h"
#include "suggest/core/dictionary/word_property.h" #include "suggest/core/dictionary/word_property.h"
#include "suggest/core/result/suggestion_results.h"
#include "suggest/core/suggest_options.h" #include "suggest/core/suggest_options.h"
#include "suggest/policyimpl/dictionary/structure/dictionary_structure_with_buffer_policy_factory.h" #include "suggest/policyimpl/dictionary/structure/dictionary_structure_with_buffer_policy_factory.h"
#include "utils/char_utils.h" #include "utils/char_utils.h"
@ -139,15 +140,20 @@ static int latinime_BinaryDictionary_getFormatVersion(JNIEnv *env, jclass clazz,
return headerPolicy->getFormatVersionNumber(); return headerPolicy->getFormatVersionNumber();
} }
static int latinime_BinaryDictionary_getSuggestions(JNIEnv *env, jclass clazz, jlong dict, static void latinime_BinaryDictionary_getSuggestions(JNIEnv *env, jclass clazz, jlong dict,
jlong proximityInfo, jlong dicTraverseSession, jintArray xCoordinatesArray, jlong proximityInfo, jlong dicTraverseSession, jintArray xCoordinatesArray,
jintArray yCoordinatesArray, jintArray timesArray, jintArray pointerIdsArray, jintArray yCoordinatesArray, jintArray timesArray, jintArray pointerIdsArray,
jintArray inputCodePointsArray, jint inputSize, jint commitPoint, jintArray suggestOptions, jintArray inputCodePointsArray, jint inputSize, jint commitPoint, jintArray suggestOptions,
jintArray prevWordCodePointsForBigrams, jintArray outputCodePointsArray, jintArray prevWordCodePointsForBigrams, jintArray outSuggestionCount,
jintArray scoresArray, jintArray spaceIndicesArray, jintArray outputTypesArray, jintArray outCodePointsArray, jintArray outScoresArray, jintArray outSpaceIndicesArray,
jintArray outputAutoCommitFirstWordConfidenceArray) { jintArray outTypesArray, jintArray outAutoCommitFirstWordConfidenceArray) {
Dictionary *dictionary = reinterpret_cast<Dictionary *>(dict); Dictionary *dictionary = reinterpret_cast<Dictionary *>(dict);
if (!dictionary) return 0; // Assign 0 to outSuggestionCount here in case of returning earlier in this method.
int count = 0;
env->SetIntArrayRegion(outSuggestionCount, 0, 1 /* len */, &count);
if (!dictionary) {
return;
}
ProximityInfo *pInfo = reinterpret_cast<ProximityInfo *>(proximityInfo); ProximityInfo *pInfo = reinterpret_cast<ProximityInfo *>(proximityInfo);
DicTraverseSession *traverseSession = DicTraverseSession *traverseSession =
reinterpret_cast<DicTraverseSession *>(dicTraverseSession); reinterpret_cast<DicTraverseSession *>(dicTraverseSession);
@ -181,26 +187,26 @@ static int latinime_BinaryDictionary_getSuggestions(JNIEnv *env, jclass clazz, j
// Output values // Output values
/* By the way, let's check the output array length here to make sure */ /* By the way, let's check the output array length here to make sure */
const jsize outputCodePointsLength = env->GetArrayLength(outputCodePointsArray); const jsize outputCodePointsLength = env->GetArrayLength(outCodePointsArray);
if (outputCodePointsLength != (MAX_WORD_LENGTH * MAX_RESULTS)) { if (outputCodePointsLength != (MAX_WORD_LENGTH * MAX_RESULTS)) {
AKLOGE("Invalid outputCodePointsLength: %d", outputCodePointsLength); AKLOGE("Invalid outputCodePointsLength: %d", outputCodePointsLength);
ASSERT(false); ASSERT(false);
return 0; return;
} }
const jsize scoresLength = env->GetArrayLength(scoresArray); const jsize scoresLength = env->GetArrayLength(outScoresArray);
if (scoresLength != MAX_RESULTS) { if (scoresLength != MAX_RESULTS) {
AKLOGE("Invalid scoresLength: %d", scoresLength); AKLOGE("Invalid scoresLength: %d", scoresLength);
ASSERT(false); ASSERT(false);
return 0; return;
} }
int outputCodePoints[outputCodePointsLength]; int outputCodePoints[outputCodePointsLength];
int scores[scoresLength]; int scores[scoresLength];
const jsize spaceIndicesLength = env->GetArrayLength(spaceIndicesArray); const jsize spaceIndicesLength = env->GetArrayLength(outSpaceIndicesArray);
int spaceIndices[spaceIndicesLength]; int spaceIndices[spaceIndicesLength];
const jsize outputTypesLength = env->GetArrayLength(outputTypesArray); const jsize outputTypesLength = env->GetArrayLength(outTypesArray);
int outputTypes[outputTypesLength]; int outputTypes[outputTypesLength];
const jsize outputAutoCommitFirstWordConfidenceLength = const jsize outputAutoCommitFirstWordConfidenceLength =
env->GetArrayLength(outputAutoCommitFirstWordConfidenceArray); env->GetArrayLength(outAutoCommitFirstWordConfidenceArray);
// We only use the first result, as obviously we will only ever autocommit the first one // We only use the first result, as obviously we will only ever autocommit the first one
ASSERT(outputAutoCommitFirstWordConfidenceLength == 1); ASSERT(outputAutoCommitFirstWordConfidenceLength == 1);
int outputAutoCommitFirstWordConfidence[outputAutoCommitFirstWordConfidenceLength]; int outputAutoCommitFirstWordConfidence[outputAutoCommitFirstWordConfidenceLength];
@ -210,26 +216,30 @@ static int latinime_BinaryDictionary_getSuggestions(JNIEnv *env, jclass clazz, j
memset(outputTypes, 0, sizeof(outputTypes)); memset(outputTypes, 0, sizeof(outputTypes));
memset(outputAutoCommitFirstWordConfidence, 0, sizeof(outputAutoCommitFirstWordConfidence)); memset(outputAutoCommitFirstWordConfidence, 0, sizeof(outputAutoCommitFirstWordConfidence));
int count;
if (givenSuggestOptions.isGesture() || inputSize > 0) { if (givenSuggestOptions.isGesture() || inputSize > 0) {
// TODO: Use SuggestionResults to return suggestions.
count = dictionary->getSuggestions(pInfo, traverseSession, xCoordinates, yCoordinates, count = dictionary->getSuggestions(pInfo, traverseSession, xCoordinates, yCoordinates,
times, pointerIds, inputCodePoints, inputSize, prevWordCodePoints, times, pointerIds, inputCodePoints, inputSize, prevWordCodePoints,
prevWordCodePointsLength, commitPoint, &givenSuggestOptions, outputCodePoints, prevWordCodePointsLength, commitPoint, &givenSuggestOptions, outputCodePoints,
scores, spaceIndices, outputTypes, outputAutoCommitFirstWordConfidence); scores, spaceIndices, outputTypes, outputAutoCommitFirstWordConfidence);
} else { } else {
count = dictionary->getBigrams(prevWordCodePoints, prevWordCodePointsLength, SuggestionResults suggestionResults(MAX_RESULTS);
outputCodePoints, scores, outputTypes); dictionary->getPredictions(prevWordCodePoints, prevWordCodePointsLength,
&suggestionResults);
suggestionResults.outputSuggestions(env, outSuggestionCount, outCodePointsArray,
outScoresArray, outSpaceIndicesArray, outTypesArray,
outAutoCommitFirstWordConfidenceArray);
return;
} }
// Copy back the output values // Copy back the output values
env->SetIntArrayRegion(outputCodePointsArray, 0, outputCodePointsLength, outputCodePoints); env->SetIntArrayRegion(outSuggestionCount, 0, 1 /* len */, &count);
env->SetIntArrayRegion(scoresArray, 0, scoresLength, scores); env->SetIntArrayRegion(outCodePointsArray, 0, outputCodePointsLength, outputCodePoints);
env->SetIntArrayRegion(spaceIndicesArray, 0, spaceIndicesLength, spaceIndices); env->SetIntArrayRegion(outScoresArray, 0, scoresLength, scores);
env->SetIntArrayRegion(outputTypesArray, 0, outputTypesLength, outputTypes); env->SetIntArrayRegion(outSpaceIndicesArray, 0, spaceIndicesLength, spaceIndices);
env->SetIntArrayRegion(outputAutoCommitFirstWordConfidenceArray, 0, env->SetIntArrayRegion(outTypesArray, 0, outputTypesLength, outputTypes);
env->SetIntArrayRegion(outAutoCommitFirstWordConfidenceArray, 0,
outputAutoCommitFirstWordConfidenceLength, outputAutoCommitFirstWordConfidence); outputAutoCommitFirstWordConfidenceLength, outputAutoCommitFirstWordConfidence);
return count;
} }
static jint latinime_BinaryDictionary_getProbability(JNIEnv *env, jclass clazz, jlong dict, static jint latinime_BinaryDictionary_getProbability(JNIEnv *env, jclass clazz, jlong dict,
@ -496,7 +506,7 @@ static const JNINativeMethod sMethods[] = {
}, },
{ {
const_cast<char *>("getSuggestionsNative"), const_cast<char *>("getSuggestionsNative"),
const_cast<char *>("(JJJ[I[I[I[I[III[I[I[I[I[I[I[I)I"), const_cast<char *>("(JJJ[I[I[I[I[III[I[I[I[I[I[I[I[I)V"),
reinterpret_cast<void *>(latinime_BinaryDictionary_getSuggestions) reinterpret_cast<void *>(latinime_BinaryDictionary_getSuggestions)
}, },
{ {

View File

@ -25,6 +25,7 @@
#include "suggest/core/dictionary/binary_dictionary_bigrams_iterator.h" #include "suggest/core/dictionary/binary_dictionary_bigrams_iterator.h"
#include "suggest/core/dictionary/dictionary.h" #include "suggest/core/dictionary/dictionary.h"
#include "suggest/core/policy/dictionary_structure_with_buffer_policy.h" #include "suggest/core/policy/dictionary_structure_with_buffer_policy.h"
#include "suggest/core/result/suggestion_results.h"
#include "utils/char_utils.h" #include "utils/char_utils.h"
namespace latinime { namespace latinime {
@ -40,71 +41,13 @@ BigramDictionary::BigramDictionary(
BigramDictionary::~BigramDictionary() { BigramDictionary::~BigramDictionary() {
} }
void BigramDictionary::addWordBigram(int *word, int length, int probability, int *bigramProbability,
int *bigramCodePoints, int *outputTypes) const {
if (length >= MAX_WORD_LENGTH) {
length = MAX_WORD_LENGTH - 1;
}
word[length] = 0;
if (DEBUG_DICT_FULL) {
#ifdef FLAG_DBG
char s[length + 1];
for (int i = 0; i <= length; i++) s[i] = static_cast<char>(word[i]);
AKLOGI("Bigram: Found word = %s, freq = %d :", s, probability);
#endif
}
// Find the right insertion point
int insertAt = 0;
while (insertAt < MAX_RESULTS) {
if (probability > bigramProbability[insertAt] || (bigramProbability[insertAt] == probability
&& length < CharUtils::getCodePointCount(MAX_WORD_LENGTH,
bigramCodePoints + insertAt * MAX_WORD_LENGTH))) {
break;
}
insertAt++;
}
if (DEBUG_DICT_FULL) {
AKLOGI("Bigram: InsertAt -> %d MAX_RESULTS: %d", insertAt, MAX_RESULTS);
}
if (insertAt >= MAX_RESULTS) {
return;
}
// Shift result buffers to insert the new entry.
memmove(bigramProbability + (insertAt + 1), bigramProbability + insertAt,
(MAX_RESULTS - insertAt - 1) * sizeof(bigramProbability[0]));
memmove(outputTypes + (insertAt + 1), outputTypes + insertAt,
(MAX_RESULTS - insertAt - 1) * sizeof(outputTypes[0]));
memmove(bigramCodePoints + (insertAt + 1) * MAX_WORD_LENGTH,
bigramCodePoints + insertAt * MAX_WORD_LENGTH,
(MAX_RESULTS - insertAt - 1) * sizeof(bigramCodePoints[0]) * MAX_WORD_LENGTH);
// Put the result.
bigramProbability[insertAt] = probability;
outputTypes[insertAt] = Dictionary::KIND_PREDICTION;
int *dest = bigramCodePoints + insertAt * MAX_WORD_LENGTH;
while (length--) {
*dest++ = *word++;
}
*dest = 0; // NULL terminate
if (DEBUG_DICT_FULL) {
AKLOGI("Bigram: Added word at %d", insertAt);
}
}
/* Parameters : /* Parameters :
* prevWord: the word before, the one for which we need to look up bigrams. * prevWord: the word before, the one for which we need to look up bigrams.
* prevWordLength: its length. * prevWordLength: its length.
* outBigramCodePoints: an array for output, at the same format as outwords for getSuggestions. * outSuggestionResults: SuggestionResults to put the predictions.
* outBigramProbability: an array to output frequencies.
* outputTypes: an array to output types.
* This method returns the number of bigrams this word has, for backward compatibility.
*/ */
int BigramDictionary::getPredictions(const int *prevWord, const int prevWordLength, void BigramDictionary::getPredictions(const int *prevWord, const int prevWordLength,
int *const outBigramCodePoints, int *const outBigramProbability, SuggestionResults *const outSuggestionResults) const {
int *const outputTypes) const {
// TODO: remove unused arguments, and refrain from storing stuff in members of this class
// TODO: have "in" arguments before "out" ones, and make out args explicit in the name
int pos = getBigramListPositionForWord(prevWord, prevWordLength, int pos = getBigramListPositionForWord(prevWord, prevWordLength,
false /* forceLowerCaseSearch */); false /* forceLowerCaseSearch */);
// getBigramListPositionForWord returns 0 if this word isn't in the dictionary or has no bigrams // getBigramListPositionForWord returns 0 if this word isn't in the dictionary or has no bigrams
@ -114,11 +57,10 @@ int BigramDictionary::getPredictions(const int *prevWord, const int prevWordLeng
true /* forceLowerCaseSearch */); true /* forceLowerCaseSearch */);
} }
// If still no bigrams, we really don't have them! // If still no bigrams, we really don't have them!
if (NOT_A_DICT_POS == pos) return 0; if (NOT_A_DICT_POS == pos) return;
int bigramCount = 0;
int unigramProbability = 0; int unigramProbability = 0;
int bigramBuffer[MAX_WORD_LENGTH]; int bigramCodePoints[MAX_WORD_LENGTH];
BinaryDictionaryBigramsIterator bigramsIt( BinaryDictionaryBigramsIterator bigramsIt(
mDictionaryStructurePolicy->getBigramsStructurePolicy(), pos); mDictionaryStructurePolicy->getBigramsStructurePolicy(), pos);
while (bigramsIt.hasNext()) { while (bigramsIt.hasNext()) {
@ -128,7 +70,7 @@ int BigramDictionary::getPredictions(const int *prevWord, const int prevWordLeng
} }
const int codePointCount = mDictionaryStructurePolicy-> const int codePointCount = mDictionaryStructurePolicy->
getCodePointsAndProbabilityAndReturnCodePointCount(bigramsIt.getBigramPos(), getCodePointsAndProbabilityAndReturnCodePointCount(bigramsIt.getBigramPos(),
MAX_WORD_LENGTH, bigramBuffer, &unigramProbability); MAX_WORD_LENGTH, bigramCodePoints, &unigramProbability);
if (codePointCount <= 0) { if (codePointCount <= 0) {
continue; continue;
} }
@ -139,11 +81,8 @@ int BigramDictionary::getPredictions(const int *prevWord, const int prevWordLeng
// here, but it can't get too bad. // here, but it can't get too bad.
const int probability = mDictionaryStructurePolicy->getProbability( const int probability = mDictionaryStructurePolicy->getProbability(
unigramProbability, bigramsIt.getProbability()); unigramProbability, bigramsIt.getProbability());
addWordBigram(bigramBuffer, codePointCount, probability, outBigramProbability, outSuggestionResults->addPrediction(bigramCodePoints, codePointCount, probability);
outBigramCodePoints, outputTypes);
++bigramCount;
} }
return std::min(bigramCount, MAX_RESULTS);
} }
// Returns a pointer to the start of the bigram list. // Returns a pointer to the start of the bigram list.

View File

@ -22,21 +22,20 @@
namespace latinime { namespace latinime {
class DictionaryStructureWithBufferPolicy; class DictionaryStructureWithBufferPolicy;
class SuggestionResults;
class BigramDictionary { class BigramDictionary {
public: public:
BigramDictionary(const DictionaryStructureWithBufferPolicy *const dictionaryStructurePolicy); BigramDictionary(const DictionaryStructureWithBufferPolicy *const dictionaryStructurePolicy);
int getPredictions(const int *word, int length, int *outBigramCodePoints, void getPredictions(const int *word, int length,
int *outBigramProbability, int *outputTypes) const; SuggestionResults *const outSuggestionResults) const;
int getBigramProbability(const int *word1, int length1, const int *word2, int length2) const; int getBigramProbability(const int *word1, int length1, const int *word2, int length2) const;
~BigramDictionary(); ~BigramDictionary();
private: private:
DISALLOW_IMPLICIT_CONSTRUCTORS(BigramDictionary); DISALLOW_IMPLICIT_CONSTRUCTORS(BigramDictionary);
void addWordBigram(int *word, int length, int probability, int *bigramProbability,
int *bigramCodePoints, int *outputTypes) const;
int getBigramListPositionForWord(const int *prevWord, const int prevWordLength, int getBigramListPositionForWord(const int *prevWord, const int prevWordLength,
const bool forceLowerCaseSearch) const; const bool forceLowerCaseSearch) const;

View File

@ -74,12 +74,11 @@ int Dictionary::getSuggestions(ProximityInfo *proximityInfo, DicTraverseSession
} }
} }
int Dictionary::getBigrams(const int *word, int length, int *outWords, int *outputScores, void Dictionary::getPredictions(const int *word, int length,
int *outputTypes) const { SuggestionResults *const outSuggestionResults) const {
TimeKeeper::setCurrentTime(); TimeKeeper::setCurrentTime();
if (length <= 0) return 0; if (length <= 0) return;
return mBigramDictionary->getPredictions(word, length, outWords, outputScores, mBigramDictionary->getPredictions(word, length, outSuggestionResults);
outputTypes);
} }
int Dictionary::getProbability(const int *word, int length) const { int Dictionary::getProbability(const int *word, int length) const {

View File

@ -33,6 +33,7 @@ namespace latinime {
class DictionaryStructureWithBufferPolicy; class DictionaryStructureWithBufferPolicy;
class DicTraverseSession; class DicTraverseSession;
class ProximityInfo; class ProximityInfo;
class SuggestionResults;
class SuggestOptions; class SuggestOptions;
class WordProperty; class WordProperty;
@ -67,8 +68,8 @@ class Dictionary {
const SuggestOptions *const suggestOptions, int *outWords, int *outputScores, const SuggestOptions *const suggestOptions, int *outWords, int *outputScores,
int *spaceIndices, int *outputTypes, int *outputAutoCommitFirstWordConfidence) const; int *spaceIndices, int *outputTypes, int *outputAutoCommitFirstWordConfidence) const;
int getBigrams(const int *word, int length, int *outWords, int *outputScores, void getPredictions(const int *word, int length,
int *outputTypes) const; SuggestionResults *const outSuggestionResults) const;
int getProbability(const int *word, int length) const; int getProbability(const int *word, int length) const;

View File

@ -0,0 +1,83 @@
/*
* Copyright (C) 2014 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef LATINIME_SUGGESTED_WORD_H
#define LATINIME_SUGGESTED_WORD_H
#include <vector>
#include "defines.h"
#include "suggest/core/dictionary/dictionary.h"
namespace latinime {
class SuggestedWord {
public:
class Comparator {
public:
bool operator()(const SuggestedWord &left, const SuggestedWord &right) {
if (left.getScore() != right.getScore()) {
return left.getScore() < right.getScore();
}
return left.getCodePointCount() > right.getCodePointCount();
}
private:
DISALLOW_ASSIGNMENT_OPERATOR(Comparator);
};
SuggestedWord(const int *const codePoints, const int codePointCount,
const int score, const int type, const int indexToPartialCommit,
const int autoCommitFirstWordConfidence)
: mCodePoints(codePoints, codePoints + codePointCount), mScore(score),
mType(type), mIndexToPartialCommit(indexToPartialCommit),
mAutoCommitFirstWordConfidence(autoCommitFirstWordConfidence) {}
const int *getCodePoint() const {
return &mCodePoints.at(0);
}
int getCodePointCount() const {
return mCodePoints.size();
}
int getScore() const {
return mScore;
}
int getType() const {
return mType;
}
int getIndexToPartialCommit() const {
return mIndexToPartialCommit;
}
int getAutoCommitFirstWordConfidence() const {
return mAutoCommitFirstWordConfidence;
}
private:
DISALLOW_DEFAULT_CONSTRUCTOR(SuggestedWord);
std::vector<int> mCodePoints;
int mScore;
int mType;
int mIndexToPartialCommit;
int mAutoCommitFirstWordConfidence;
};
} // namespace latinime
#endif /* LATINIME_SUGGESTED_WORD_H */

View File

@ -0,0 +1,77 @@
/*
* Copyright (C) 2014 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "suggest/core/result/suggestion_results.h"
namespace latinime {
void SuggestionResults::outputSuggestions(JNIEnv *env, jintArray outSuggestionCount,
jintArray outputCodePointsArray, jintArray outScoresArray, jintArray outSpaceIndicesArray,
jintArray outTypesArray, jintArray outAutoCommitFirstWordConfidenceArray) {
int outputIndex = 0;
while (!mSuggestedWords.empty()) {
const SuggestedWord &suggestedWord = mSuggestedWords.top();
suggestedWord.getCodePointCount();
const int start = outputIndex * MAX_WORD_LENGTH;
env->SetIntArrayRegion(outputCodePointsArray, start, suggestedWord.getCodePointCount(),
suggestedWord.getCodePoint());
if (suggestedWord.getCodePointCount() < MAX_WORD_LENGTH) {
const int terminal = 0;
env->SetIntArrayRegion(outputCodePointsArray, start + suggestedWord.getCodePointCount(),
1 /* len */, &terminal);
}
const int score = suggestedWord.getScore();
env->SetIntArrayRegion(outScoresArray, outputIndex, 1 /* len */, &score);
const int indexToPartialCommit = suggestedWord.getIndexToPartialCommit();
env->SetIntArrayRegion(outSpaceIndicesArray, outputIndex, 1 /* len */,
&indexToPartialCommit);
const int type = suggestedWord.getType();
env->SetIntArrayRegion(outTypesArray, outputIndex, 1 /* len */, &type);
if (mSuggestedWords.size() == 1) {
const int autoCommitFirstWordConfidence =
suggestedWord.getAutoCommitFirstWordConfidence();
env->SetIntArrayRegion(outAutoCommitFirstWordConfidenceArray, 0 /* start */,
1 /* len */, &autoCommitFirstWordConfidence);
}
++outputIndex;
mSuggestedWords.pop();
}
env->SetIntArrayRegion(outSuggestionCount, 0 /* start */, 1 /* len */, &outputIndex);
}
void SuggestionResults::addPrediction(const int *const codePoints, const int codePointCount,
const int probability) {
if (codePointCount <= 0 || codePointCount > MAX_WORD_LENGTH
|| probability == NOT_A_PROBABILITY) {
// Invalid word.
return;
}
// Use probability as a score of the word.
const int score = probability;
if (getSuggestionCount() >= mMaxSuggestionCount) {
const SuggestedWord &mWorstSuggestion = mSuggestedWords.top();
if (score > mWorstSuggestion.getScore() || (score == mWorstSuggestion.getScore()
&& codePointCount < mWorstSuggestion.getCodePointCount())) {
mSuggestedWords.pop();
} else {
return;
}
}
mSuggestedWords.push(SuggestedWord(codePoints, codePointCount, score,
Dictionary::KIND_PREDICTION, NOT_AN_INDEX, NOT_A_FIRST_WORD_CONFIDENCE));
}
} // namespace latinime

View File

@ -0,0 +1,53 @@
/*
* Copyright (C) 2013 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef LATINIME_SUGGESTION_RESULTS_H
#define LATINIME_SUGGESTION_RESULTS_H
#include <queue>
#include <vector>
#include "defines.h"
#include "jni.h"
#include "suggest/core/result/suggested_word.h"
namespace latinime {
class SuggestionResults {
public:
explicit SuggestionResults(const int maxSuggestionCount)
: mMaxSuggestionCount(maxSuggestionCount), mSuggestedWords() {}
// Returns suggestion count.
void outputSuggestions(JNIEnv *env, jintArray outSuggestionCount, jintArray outCodePointsArray,
jintArray outScoresArray, jintArray outSpaceIndicesArray, jintArray outTypesArray,
jintArray outAutoCommitFirstWordConfidenceArray);
void addPrediction(const int *const codePoints, const int codePointCount, const int score);
int getSuggestionCount() const {
return mSuggestedWords.size();
}
private:
DISALLOW_IMPLICIT_CONSTRUCTORS(SuggestionResults);
const int mMaxSuggestionCount;
std::priority_queue<
SuggestedWord, std::vector<SuggestedWord>, SuggestedWord::Comparator> mSuggestedWords;
};
} // namespace latinime
#endif // LATINIME_SUGGESTION_RESULTS_H