Merge "Introduce SuggestionResults and use it for predictions."
commit
ee5d8441d1
|
@ -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;
|
||||||
|
|
|
@ -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 \
|
||||||
|
|
|
@ -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)
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|
|
@ -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.
|
||||||
|
|
|
@ -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;
|
||||||
|
|
||||||
|
|
|
@ -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 {
|
||||||
|
|
|
@ -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;
|
||||||
|
|
||||||
|
|
|
@ -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 */
|
|
@ -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
|
|
@ -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
|
Loading…
Reference in New Issue