Merge "Use SuggestionResults to get suggestion."

This commit is contained in:
Keisuke Kuroyanagi 2014-03-27 12:07:28 +00:00 committed by Android (Google) Code Review
commit 618a949f9d
13 changed files with 128 additions and 175 deletions

View file

@ -199,47 +199,30 @@ static void latinime_BinaryDictionary_getSuggestions(JNIEnv *env, jclass clazz,
ASSERT(false); ASSERT(false);
return; return;
} }
int outputCodePoints[outputCodePointsLength];
int scores[scoresLength];
const jsize spaceIndicesLength = env->GetArrayLength(outSpaceIndicesArray);
int spaceIndices[spaceIndicesLength];
const jsize outputTypesLength = env->GetArrayLength(outTypesArray);
int outputTypes[outputTypesLength];
const jsize outputAutoCommitFirstWordConfidenceLength = const jsize outputAutoCommitFirstWordConfidenceLength =
env->GetArrayLength(outAutoCommitFirstWordConfidenceArray); env->GetArrayLength(outAutoCommitFirstWordConfidenceArray);
// 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]; if (outputAutoCommitFirstWordConfidenceLength != 1) {
memset(outputCodePoints, 0, sizeof(outputCodePoints)); // We only use the first result, as obviously we will only ever autocommit the first one
memset(scores, 0, sizeof(scores)); AKLOGE("Invalid outputAutoCommitFirstWordConfidenceLength: %d",
memset(spaceIndices, 0, sizeof(spaceIndices)); outputAutoCommitFirstWordConfidenceLength);
memset(outputTypes, 0, sizeof(outputTypes)); ASSERT(false);
memset(outputAutoCommitFirstWordConfidence, 0, sizeof(outputAutoCommitFirstWordConfidence));
if (givenSuggestOptions.isGesture() || inputSize > 0) {
// TODO: Use SuggestionResults to return suggestions.
count = dictionary->getSuggestions(pInfo, traverseSession, xCoordinates, yCoordinates,
times, pointerIds, inputCodePoints, inputSize, prevWordCodePoints,
prevWordCodePointsLength, &givenSuggestOptions, outputCodePoints,
scores, spaceIndices, outputTypes, outputAutoCommitFirstWordConfidence);
} else {
SuggestionResults suggestionResults(MAX_RESULTS);
dictionary->getPredictions(prevWordCodePoints, prevWordCodePointsLength,
&suggestionResults);
suggestionResults.outputSuggestions(env, outSuggestionCount, outCodePointsArray,
outScoresArray, outSpaceIndicesArray, outTypesArray,
outAutoCommitFirstWordConfidenceArray);
return; return;
} }
// Copy back the output values SuggestionResults suggestionResults(MAX_RESULTS);
env->SetIntArrayRegion(outSuggestionCount, 0, 1 /* len */, &count); if (givenSuggestOptions.isGesture() || inputSize > 0) {
env->SetIntArrayRegion(outCodePointsArray, 0, outputCodePointsLength, outputCodePoints); // TODO: Use SuggestionResults to return suggestions.
env->SetIntArrayRegion(outScoresArray, 0, scoresLength, scores); dictionary->getSuggestions(pInfo, traverseSession, xCoordinates, yCoordinates,
env->SetIntArrayRegion(outSpaceIndicesArray, 0, spaceIndicesLength, spaceIndices); times, pointerIds, inputCodePoints, inputSize, prevWordCodePoints,
env->SetIntArrayRegion(outTypesArray, 0, outputTypesLength, outputTypes); prevWordCodePointsLength, &givenSuggestOptions, &suggestionResults);
env->SetIntArrayRegion(outAutoCommitFirstWordConfidenceArray, 0, } else {
outputAutoCommitFirstWordConfidenceLength, outputAutoCommitFirstWordConfidence); dictionary->getPredictions(prevWordCodePoints, prevWordCodePointsLength,
&suggestionResults);
}
suggestionResults.outputSuggestions(env, outSuggestionCount, outCodePointsArray,
outScoresArray, outSpaceIndicesArray, outTypesArray,
outAutoCommitFirstWordConfidenceArray);
} }
static jint latinime_BinaryDictionary_getProbability(JNIEnv *env, jclass clazz, jlong dict, static jint latinime_BinaryDictionary_getProbability(JNIEnv *env, jclass clazz, jlong dict,

View file

@ -103,7 +103,8 @@ AK_FORCE_INLINE static int intArrayToCharArray(const int *const source, const in
#define AKLOGI(fmt, ...) __android_log_print(ANDROID_LOG_INFO, LOG_TAG, fmt, ##__VA_ARGS__) #define AKLOGI(fmt, ...) __android_log_print(ANDROID_LOG_INFO, LOG_TAG, fmt, ##__VA_ARGS__)
#endif // defined(HOST_TOOL) #endif // defined(HOST_TOOL)
#define DUMP_RESULT(words, frequencies) do { dumpResult(words, frequencies); } while (0) #define DUMP_SUGGESTION(words, frequencies, index, score) \
do { dumpWordInfo(words, frequencies, index, score); } while (0)
#define DUMP_WORD(word, length) do { dumpWord(word, length); } while (0) #define DUMP_WORD(word, length) do { dumpWord(word, length); } while (0)
#define INTS_TO_CHARS(input, length, output, outlength) do { \ #define INTS_TO_CHARS(input, length, output, outlength) do { \
intArrayToCharArray(input, length, output, outlength); } while (0) intArrayToCharArray(input, length, output, outlength); } while (0)
@ -165,7 +166,7 @@ static inline void showStackTrace() {
#else // defined(FLAG_DO_PROFILE) || defined(FLAG_DBG) #else // defined(FLAG_DO_PROFILE) || defined(FLAG_DBG)
#define AKLOGE(fmt, ...) #define AKLOGE(fmt, ...)
#define AKLOGI(fmt, ...) #define AKLOGI(fmt, ...)
#define DUMP_RESULT(words, frequencies) #define DUMP_SUGGESTION(words, frequencies, index, score)
#define DUMP_WORD(word, length) #define DUMP_WORD(word, length)
#undef DO_ASSERT_TEST #undef DO_ASSERT_TEST
#define ASSERT(success) #define ASSERT(success)

View file

@ -22,6 +22,7 @@
#include "defines.h" #include "defines.h"
#include "suggest/core/policy/dictionary_header_structure_policy.h" #include "suggest/core/policy/dictionary_header_structure_policy.h"
#include "suggest/core/result/suggestion_results.h"
#include "suggest/core/session/dic_traverse_session.h" #include "suggest/core/session/dic_traverse_session.h"
#include "suggest/core/suggest.h" #include "suggest/core/suggest.h"
#include "suggest/core/suggest_options.h" #include "suggest/core/suggest_options.h"
@ -43,34 +44,25 @@ Dictionary::Dictionary(JNIEnv *env, DictionaryStructureWithBufferPolicy::Structu
logDictionaryInfo(env); logDictionaryInfo(env);
} }
int Dictionary::getSuggestions(ProximityInfo *proximityInfo, DicTraverseSession *traverseSession, void Dictionary::getSuggestions(ProximityInfo *proximityInfo, DicTraverseSession *traverseSession,
int *xcoordinates, int *ycoordinates, int *times, int *pointerIds, int *inputCodePoints, int *xcoordinates, int *ycoordinates, int *times, int *pointerIds, int *inputCodePoints,
int inputSize, int *prevWordCodePoints, int prevWordLength, int inputSize, int *prevWordCodePoints, int prevWordLength,
const SuggestOptions *const suggestOptions, int *outWords, int *outputScores, const SuggestOptions *const suggestOptions,
int *spaceIndices, int *outputTypes, int *outputAutoCommitFirstWordConfidence) const { SuggestionResults *const outSuggestionResults) const {
TimeKeeper::setCurrentTime(); TimeKeeper::setCurrentTime();
int result = 0; DicTraverseSession::initSessionInstance(
traverseSession, this, prevWordCodePoints, prevWordLength, suggestOptions);
if (suggestOptions->isGesture()) { if (suggestOptions->isGesture()) {
DicTraverseSession::initSessionInstance( mGestureSuggest->getSuggestions(proximityInfo, traverseSession, xcoordinates,
traverseSession, this, prevWordCodePoints, prevWordLength, suggestOptions);
result = mGestureSuggest->getSuggestions(proximityInfo, traverseSession, xcoordinates,
ycoordinates, times, pointerIds, inputCodePoints, inputSize, outWords,
outputScores, spaceIndices, outputTypes, outputAutoCommitFirstWordConfidence);
if (DEBUG_DICT) {
DUMP_RESULT(outWords, outputScores);
}
return result;
} else {
DicTraverseSession::initSessionInstance(
traverseSession, this, prevWordCodePoints, prevWordLength, suggestOptions);
result = mTypingSuggest->getSuggestions(proximityInfo, traverseSession, xcoordinates,
ycoordinates, times, pointerIds, inputCodePoints, inputSize, ycoordinates, times, pointerIds, inputCodePoints, inputSize,
outWords, outputScores, spaceIndices, outputTypes, outSuggestionResults);
outputAutoCommitFirstWordConfidence); } else {
if (DEBUG_DICT) { mTypingSuggest->getSuggestions(proximityInfo, traverseSession, xcoordinates,
DUMP_RESULT(outWords, outputScores); ycoordinates, times, pointerIds, inputCodePoints, inputSize,
} outSuggestionResults);
return result; }
if (DEBUG_DICT) {
outSuggestionResults->dumpSuggestions();
} }
} }

View file

@ -62,11 +62,11 @@ class Dictionary {
Dictionary(JNIEnv *env, DictionaryStructureWithBufferPolicy::StructurePolicyPtr Dictionary(JNIEnv *env, DictionaryStructureWithBufferPolicy::StructurePolicyPtr
dictionaryStructureWithBufferPolicy); dictionaryStructureWithBufferPolicy);
int getSuggestions(ProximityInfo *proximityInfo, DicTraverseSession *traverseSession, void getSuggestions(ProximityInfo *proximityInfo, DicTraverseSession *traverseSession,
int *xcoordinates, int *ycoordinates, int *times, int *pointerIds, int *inputCodePoints, int *xcoordinates, int *ycoordinates, int *times, int *pointerIds, int *inputCodePoints,
int inputSize, int *prevWordCodePoints, int prevWordLength, int inputSize, int *prevWordCodePoints, int prevWordLength,
const SuggestOptions *const suggestOptions, int *outWords, int *outputScores, const SuggestOptions *const suggestOptions,
int *spaceIndices, int *outputTypes, int *outputAutoCommitFirstWordConfidence) const; SuggestionResults *const outSuggestionResults) const;
void getPredictions(const int *word, int length, void getPredictions(const int *word, int length,
SuggestionResults *const outSuggestionResults) const; SuggestionResults *const outSuggestionResults) const;

View file

@ -23,6 +23,7 @@ namespace latinime {
class DicNode; class DicNode;
class DicTraverseSession; class DicTraverseSession;
class SuggestionResults;
// This class basically tweaks suggestions and distances apart from CompoundDistance // This class basically tweaks suggestions and distances apart from CompoundDistance
class Scoring { class Scoring {
@ -30,11 +31,8 @@ class Scoring {
virtual int calculateFinalScore(const float compoundDistance, const int inputSize, virtual int calculateFinalScore(const float compoundDistance, const int inputSize,
const ErrorTypeUtils::ErrorType containedErrorTypes, const bool forceCommit, const ErrorTypeUtils::ErrorType containedErrorTypes, const bool forceCommit,
const bool boostExactMatches) const = 0; const bool boostExactMatches) const = 0;
virtual bool getMostProbableString(const DicTraverseSession *const traverseSession, virtual void getMostProbableString(const DicTraverseSession *const traverseSession,
const int terminalSize, const float languageWeight, int *const outputCodePoints, const float languageWeight, SuggestionResults *const outSuggestionResults) const = 0;
int *const type, int *const freq) const = 0;
virtual void safetyNetForMostProbableString(const int scoreCount,
const int maxScore, int *const outputCodePoints, int *const scores) const = 0;
virtual float getAdjustedLanguageWeight(DicTraverseSession *const traverseSession, virtual float getAdjustedLanguageWeight(DicTraverseSession *const traverseSession,
DicNode *const terminals, const int size) const = 0; DicNode *const terminals, const int size) const = 0;
virtual float getDoubleLetterDemotionDistanceCost( virtual float getDoubleLetterDemotionDistanceCost(

View file

@ -54,13 +54,23 @@ void SuggestionResults::outputSuggestions(JNIEnv *env, jintArray outSuggestionCo
void SuggestionResults::addPrediction(const int *const codePoints, const int codePointCount, void SuggestionResults::addPrediction(const int *const codePoints, const int codePointCount,
const int probability) { const int probability) {
if (codePointCount <= 0 || codePointCount > MAX_WORD_LENGTH if (probability == NOT_A_PROBABILITY) {
|| probability == NOT_A_PROBABILITY) {
// Invalid word. // Invalid word.
return; return;
} }
// Use probability as a score of the word. addSuggestion(codePoints, codePointCount, probability, Dictionary::KIND_PREDICTION,
const int score = probability; NOT_AN_INDEX, NOT_A_FIRST_WORD_CONFIDENCE);
}
void SuggestionResults::addSuggestion(const int *const codePoints, const int codePointCount,
const int score, const int type, const int indexToPartialCommit,
const int autocimmitFirstWordConfindence) {
if (codePointCount <= 0 || codePointCount > MAX_WORD_LENGTH) {
// Invalid word.
AKLOGE("Invalid word is added to the suggestion results. codePointCount: %d",
codePointCount);
return;
}
if (getSuggestionCount() >= mMaxSuggestionCount) { if (getSuggestionCount() >= mMaxSuggestionCount) {
const SuggestedWord &mWorstSuggestion = mSuggestedWords.top(); const SuggestedWord &mWorstSuggestion = mSuggestedWords.top();
if (score > mWorstSuggestion.getScore() || (score == mWorstSuggestion.getScore() if (score > mWorstSuggestion.getScore() || (score == mWorstSuggestion.getScore()
@ -70,8 +80,31 @@ void SuggestionResults::addPrediction(const int *const codePoints, const int cod
return; return;
} }
} }
mSuggestedWords.push(SuggestedWord(codePoints, codePointCount, score, mSuggestedWords.push(SuggestedWord(codePoints, codePointCount, score, type,
Dictionary::KIND_PREDICTION, NOT_AN_INDEX, NOT_A_FIRST_WORD_CONFIDENCE)); indexToPartialCommit, autocimmitFirstWordConfindence));
}
void SuggestionResults::getSortedScores(int *const outScores) const {
auto copyOfSuggestedWords = mSuggestedWords;
while (!copyOfSuggestedWords.empty()) {
const SuggestedWord &suggestedWord = copyOfSuggestedWords.top();
outScores[copyOfSuggestedWords.size() - 1] = suggestedWord.getScore();
copyOfSuggestedWords.pop();
}
}
void SuggestionResults::dumpSuggestions() const {
std::vector<SuggestedWord> suggestedWords;
auto copyOfSuggestedWords = mSuggestedWords;
while (!copyOfSuggestedWords.empty()) {
suggestedWords.push_back(copyOfSuggestedWords.top());
copyOfSuggestedWords.pop();
}
int index = 0;
for (auto it = suggestedWords.rbegin(); it != suggestedWords.rend(); ++it) {
DUMP_SUGGESTION(it->getCodePoint(), it->getCodePointCount(), index, it->getScore());
index++;
}
} }
} // namespace latinime } // namespace latinime

View file

@ -35,8 +35,12 @@ class SuggestionResults {
void outputSuggestions(JNIEnv *env, jintArray outSuggestionCount, jintArray outCodePointsArray, void outputSuggestions(JNIEnv *env, jintArray outSuggestionCount, jintArray outCodePointsArray,
jintArray outScoresArray, jintArray outSpaceIndicesArray, jintArray outTypesArray, jintArray outScoresArray, jintArray outSpaceIndicesArray, jintArray outTypesArray,
jintArray outAutoCommitFirstWordConfidenceArray); jintArray outAutoCommitFirstWordConfidenceArray);
void addPrediction(const int *const codePoints, const int codePointCount, const int score); void addPrediction(const int *const codePoints, const int codePointCount, const int score);
void addSuggestion(const int *const codePoints, const int codePointCount,
const int score, const int type, const int indexToPartialCommit,
const int autocimmitFirstWordConfindence);
void getSortedScores(int *const outScores) const;
void dumpSuggestions() const;
int getSuggestionCount() const { int getSuggestionCount() const {
return mSuggestedWords.size(); return mSuggestedWords.size();

View file

@ -24,6 +24,7 @@
#include "suggest/core/dictionary/dictionary.h" #include "suggest/core/dictionary/dictionary.h"
#include "suggest/core/dictionary/error_type_utils.h" #include "suggest/core/dictionary/error_type_utils.h"
#include "suggest/core/policy/scoring.h" #include "suggest/core/policy/scoring.h"
#include "suggest/core/result/suggestion_results.h"
#include "suggest/core/session/dic_traverse_session.h" #include "suggest/core/session/dic_traverse_session.h"
namespace latinime { namespace latinime {
@ -31,10 +32,9 @@ namespace latinime {
const int SuggestionsOutputUtils::MIN_LEN_FOR_MULTI_WORD_AUTOCORRECT = 16; const int SuggestionsOutputUtils::MIN_LEN_FOR_MULTI_WORD_AUTOCORRECT = 16;
// TODO: Split this method. // TODO: Split this method.
/* static */ int SuggestionsOutputUtils::outputSuggestions( /* static */ void SuggestionsOutputUtils::outputSuggestions(
const Scoring *const scoringPolicy, DicTraverseSession *traverseSession, const Scoring *const scoringPolicy, DicTraverseSession *traverseSession,
int *outputScores, int *outputCodePoints, int *outputIndicesToPartialCommit, SuggestionResults *const outSuggestionResults) {
int *outputTypes, int *outputAutoCommitFirstWordConfidence) {
#if DEBUG_EVALUATE_MOST_PROBABLE_STRING #if DEBUG_EVALUATE_MOST_PROBABLE_STRING
const int terminalSize = 0; const int terminalSize = 0;
#else #else
@ -49,18 +49,6 @@ const int SuggestionsOutputUtils::MIN_LEN_FOR_MULTI_WORD_AUTOCORRECT = 16;
const float languageWeight = scoringPolicy->getAdjustedLanguageWeight( const float languageWeight = scoringPolicy->getAdjustedLanguageWeight(
traverseSession, terminals, terminalSize); traverseSession, terminals, terminalSize);
int outputWordIndex = 0;
// Insert most probable word at index == 0 as long as there is one terminal at least
const bool hasMostProbableString =
scoringPolicy->getMostProbableString(traverseSession, terminalSize, languageWeight,
&outputCodePoints[0], &outputTypes[0], &outputScores[0]);
if (hasMostProbableString) {
outputIndicesToPartialCommit[outputWordIndex] = NOT_AN_INDEX;
++outputWordIndex;
}
int maxScore = S_INT_MIN;
// Force autocorrection for obvious long multi-word suggestions when the top suggestion is // Force autocorrection for obvious long multi-word suggestions when the top suggestion is
// a long multiple words suggestion. // a long multiple words suggestion.
// TODO: Implement a smarter auto-commit method for handling multi-word suggestions. // TODO: Implement a smarter auto-commit method for handling multi-word suggestions.
@ -75,16 +63,12 @@ const int SuggestionsOutputUtils::MIN_LEN_FOR_MULTI_WORD_AUTOCORRECT = 16;
// TODO: have partial commit work even with multiple pointers. // TODO: have partial commit work even with multiple pointers.
const bool outputSecondWordFirstLetterInputIndex = const bool outputSecondWordFirstLetterInputIndex =
traverseSession->isOnlyOnePointerUsed(0 /* pointerId */); traverseSession->isOnlyOnePointerUsed(0 /* pointerId */);
if (terminalSize > 0) {
// If we have no suggestions, don't write this
outputAutoCommitFirstWordConfidence[0] =
computeFirstWordConfidence(&terminals[0]);
}
const bool boostExactMatches = traverseSession->getDictionaryStructurePolicy()-> const bool boostExactMatches = traverseSession->getDictionaryStructurePolicy()->
getHeaderStructurePolicy()->shouldBoostExactMatches(); getHeaderStructurePolicy()->shouldBoostExactMatches();
int codePoints[MAX_WORD_LENGTH];
// Output suggestion results here // Output suggestion results here
for (int terminalIndex = 0; terminalIndex < terminalSize && outputWordIndex < MAX_RESULTS; for (int terminalIndex = 0; terminalIndex < terminalSize; ++terminalIndex) {
++terminalIndex) {
DicNode *terminalDicNode = &terminals[terminalIndex]; DicNode *terminalDicNode = &terminals[terminalIndex];
if (DEBUG_GEO_FULL) { if (DEBUG_GEO_FULL) {
terminalDicNode->dump("OUT:"); terminalDicNode->dump("OUT:");
@ -118,25 +102,18 @@ const int SuggestionsOutputUtils::MIN_LEN_FOR_MULTI_WORD_AUTOCORRECT = 16;
(forceCommitMultiWords && terminalDicNode->hasMultipleWords()) (forceCommitMultiWords && terminalDicNode->hasMultipleWords())
|| (isValidWord && scoringPolicy->doesAutoCorrectValidWord()), || (isValidWord && scoringPolicy->doesAutoCorrectValidWord()),
boostExactMatches); boostExactMatches);
if (maxScore < finalScore && isValidWord) {
maxScore = finalScore;
}
// Don't output invalid words. However, we still need to submit their shortcuts if any. // Don't output invalid words. However, we still need to submit their shortcuts if any.
if (isValidWord) { if (isValidWord) {
outputTypes[outputWordIndex] = Dictionary::KIND_CORRECTION | outputTypeFlags; terminalDicNode->outputResult(codePoints);
outputScores[outputWordIndex] = finalScore; const int indexToPartialCommit = outputSecondWordFirstLetterInputIndex ?
if (outputSecondWordFirstLetterInputIndex) { terminalDicNode->getSecondWordFirstInputIndex(
outputIndicesToPartialCommit[outputWordIndex] = traverseSession->getProximityInfoState(0)) :
terminalDicNode->getSecondWordFirstInputIndex( NOT_AN_INDEX;
traverseSession->getProximityInfoState(0)); outSuggestionResults->addSuggestion(codePoints,
} else { terminalDicNode->getTotalNodeCodePointCount(),
outputIndicesToPartialCommit[outputWordIndex] = NOT_AN_INDEX; finalScore, Dictionary::KIND_CORRECTION | outputTypeFlags,
} indexToPartialCommit, computeFirstWordConfidence(terminalDicNode));
// Populate the outputChars array with the suggested word.
const int startIndex = outputWordIndex * MAX_WORD_LENGTH;
terminalDicNode->outputResult(&outputCodePoints[startIndex]);
++outputWordIndex;
} }
if (!terminalDicNode->hasMultipleWords()) { if (!terminalDicNode->hasMultipleWords()) {
@ -152,28 +129,11 @@ const int SuggestionsOutputUtils::MIN_LEN_FOR_MULTI_WORD_AUTOCORRECT = 16;
traverseSession->getInputSize(), traverseSession->getInputSize(),
terminalDicNode->getContainedErrorTypes(), terminalDicNode->getContainedErrorTypes(),
true /* forceCommit */, boostExactMatches) : finalScore; true /* forceCommit */, boostExactMatches) : finalScore;
const int updatedOutputWordIndex = outputShortcuts(&shortcutIt, outputShortcuts(&shortcutIt, shortcutBaseScore, sameAsTyped, outSuggestionResults);
outputWordIndex, shortcutBaseScore, outputCodePoints, outputScores, outputTypes,
sameAsTyped);
const int secondWordFirstInputIndex = terminalDicNode->getSecondWordFirstInputIndex(
traverseSession->getProximityInfoState(0));
for (int i = outputWordIndex; i < updatedOutputWordIndex; ++i) {
if (outputSecondWordFirstLetterInputIndex) {
outputIndicesToPartialCommit[i] = secondWordFirstInputIndex;
} else {
outputIndicesToPartialCommit[i] = NOT_AN_INDEX;
}
}
outputWordIndex = updatedOutputWordIndex;
} }
DicNode::managedDelete(terminalDicNode); DicNode::managedDelete(terminalDicNode);
} }
scoringPolicy->getMostProbableString(traverseSession, languageWeight, outSuggestionResults);
if (hasMostProbableString) {
scoringPolicy->safetyNetForMostProbableString(outputWordIndex, maxScore,
&outputCodePoints[0], outputScores);
}
return outputWordIndex;
} }
/* static */ int SuggestionsOutputUtils::computeFirstWordConfidence( /* static */ int SuggestionsOutputUtils::computeFirstWordConfidence(
@ -228,12 +188,11 @@ const int SuggestionsOutputUtils::MIN_LEN_FOR_MULTI_WORD_AUTOCORRECT = 16;
return distanceContribution + lengthContribution + spaceContribution; return distanceContribution + lengthContribution + spaceContribution;
} }
/* static */ int SuggestionsOutputUtils::outputShortcuts( /* static */ void SuggestionsOutputUtils::outputShortcuts(
BinaryDictionaryShortcutIterator *const shortcutIt, BinaryDictionaryShortcutIterator *const shortcutIt, const int finalScore,
int outputWordIndex, const int finalScore, int *const outputCodePoints, const bool sameAsTyped, SuggestionResults *const outSuggestionResults) {
int *const outputScores, int *const outputTypes, const bool sameAsTyped) {
int shortcutTarget[MAX_WORD_LENGTH]; int shortcutTarget[MAX_WORD_LENGTH];
while (shortcutIt->hasNextShortcutTarget() && outputWordIndex < MAX_RESULTS) { while (shortcutIt->hasNextShortcutTarget()) {
bool isWhilelist; bool isWhilelist;
int shortcutTargetStringLength; int shortcutTargetStringLength;
shortcutIt->nextShortcutTarget(MAX_WORD_LENGTH, shortcutTarget, shortcutIt->nextShortcutTarget(MAX_WORD_LENGTH, shortcutTarget,
@ -250,15 +209,9 @@ const int SuggestionsOutputUtils::MIN_LEN_FOR_MULTI_WORD_AUTOCORRECT = 16;
shortcutScore = std::max(S_INT_MIN + 1, shortcutScore) - 1; shortcutScore = std::max(S_INT_MIN + 1, shortcutScore) - 1;
kind = Dictionary::KIND_SHORTCUT; kind = Dictionary::KIND_SHORTCUT;
} }
outputTypes[outputWordIndex] = kind; outSuggestionResults->addSuggestion(shortcutTarget, shortcutTargetStringLength,
outputScores[outputWordIndex] = shortcutScore; std::max(S_INT_MIN + 1, shortcutScore) - 1, kind, NOT_AN_INDEX,
outputScores[outputWordIndex] = std::max(S_INT_MIN + 1, shortcutScore) - 1; NOT_A_FIRST_WORD_CONFIDENCE);
const int startIndex2 = outputWordIndex * MAX_WORD_LENGTH;
// Copy shortcut target code points to the output buffer.
memmove(&outputCodePoints[startIndex2], shortcutTarget,
shortcutTargetStringLength * sizeof(shortcutTarget[0]));
++outputWordIndex;
} }
return outputWordIndex;
} }
} // namespace latinime } // namespace latinime

View file

@ -25,16 +25,15 @@ class BinaryDictionaryShortcutIterator;
class DicNode; class DicNode;
class DicTraverseSession; class DicTraverseSession;
class Scoring; class Scoring;
class SuggestionResults;
class SuggestionsOutputUtils { class SuggestionsOutputUtils {
public: public:
/** /**
* Outputs the final list of suggestions (i.e., terminal nodes). * Outputs the final list of suggestions (i.e., terminal nodes).
*/ */
static int outputSuggestions(const Scoring *const scoringPolicy, static void outputSuggestions(const Scoring *const scoringPolicy,
DicTraverseSession *traverseSession, int *outputScores, int *outputCodePoints, DicTraverseSession *traverseSession, SuggestionResults *const outSuggestionResults);
int *outputIndicesToPartialCommit, int *outputTypes,
int *outputAutoCommitFirstWordConfidence);
private: private:
DISALLOW_IMPLICIT_CONSTRUCTORS(SuggestionsOutputUtils); DISALLOW_IMPLICIT_CONSTRUCTORS(SuggestionsOutputUtils);
@ -44,9 +43,9 @@ class SuggestionsOutputUtils {
static int computeFirstWordConfidence(const DicNode *const terminalDicNode); static int computeFirstWordConfidence(const DicNode *const terminalDicNode);
static int outputShortcuts(BinaryDictionaryShortcutIterator *const shortcutIt, static void outputShortcuts(BinaryDictionaryShortcutIterator *const shortcutIt,
int outputWordIndex, const int finalScore, int *const outputCodePoints, const int finalScore, const bool sameAsTyped,
int *const outputScores, int *const outputTypes, const bool sameAsTyped); SuggestionResults *const outSuggestionResults);
}; };
} // namespace latinime } // namespace latinime
#endif // LATINIME_SUGGESTIONS_OUTPUT_UTILS #endif // LATINIME_SUGGESTIONS_OUTPUT_UTILS

View file

@ -42,10 +42,9 @@ const int Suggest::MIN_CONTINUOUS_SUGGESTION_INPUT_SIZE = 2;
* automatically activated for sequential calls that share the same starting input. * automatically activated for sequential calls that share the same starting input.
* TODO: Stop detecting continuous suggestion. Start using traverseSession instead. * TODO: Stop detecting continuous suggestion. Start using traverseSession instead.
*/ */
int Suggest::getSuggestions(ProximityInfo *pInfo, void *traverseSession, void Suggest::getSuggestions(ProximityInfo *pInfo, void *traverseSession,
int *inputXs, int *inputYs, int *times, int *pointerIds, int *inputCodePoints, int *inputXs, int *inputYs, int *times, int *pointerIds, int *inputCodePoints,
int inputSize, int *outWords, int *outputScores, int *outputIndices, int inputSize, SuggestionResults *const outSuggestionResults) const {
int *outputTypes, int *outputAutoCommitFirstWordConfidence) const {
PROF_OPEN; PROF_OPEN;
PROF_START(0); PROF_START(0);
const float maxSpatialDistance = TRAVERSAL->getMaxSpatialDistance(); const float maxSpatialDistance = TRAVERSAL->getMaxSpatialDistance();
@ -66,11 +65,9 @@ int Suggest::getSuggestions(ProximityInfo *pInfo, void *traverseSession,
} }
PROF_END(1); PROF_END(1);
PROF_START(2); PROF_START(2);
const int size = SuggestionsOutputUtils::outputSuggestions(SCORING, tSession, outputScores, SuggestionsOutputUtils::outputSuggestions(SCORING, tSession, outSuggestionResults);
outWords, outputIndices, outputTypes, outputAutoCommitFirstWordConfidence);
PROF_END(2); PROF_END(2);
PROF_CLOSE; PROF_CLOSE;
return size;
} }
/** /**

View file

@ -36,6 +36,7 @@ class DicNode;
class DicTraverseSession; class DicTraverseSession;
class ProximityInfo; class ProximityInfo;
class Scoring; class Scoring;
class SuggestionResults;
class Traversal; class Traversal;
class Weighting; class Weighting;
@ -46,10 +47,9 @@ class Suggest : public SuggestInterface {
SCORING(suggestPolicy ? suggestPolicy->getScoring() : nullptr), SCORING(suggestPolicy ? suggestPolicy->getScoring() : nullptr),
WEIGHTING(suggestPolicy ? suggestPolicy->getWeighting() : nullptr) {} WEIGHTING(suggestPolicy ? suggestPolicy->getWeighting() : nullptr) {}
AK_FORCE_INLINE virtual ~Suggest() {} AK_FORCE_INLINE virtual ~Suggest() {}
int getSuggestions(ProximityInfo *pInfo, void *traverseSession, int *inputXs, int *inputYs, void getSuggestions(ProximityInfo *pInfo, void *traverseSession, int *inputXs, int *inputYs,
int *times, int *pointerIds, int *inputCodePoints, int inputSize, int *outWords, int *times, int *pointerIds, int *inputCodePoints, int inputSize,
int *outputScores, int *outputIndices, int *outputTypes, SuggestionResults *const outSuggestionResults) const;
int *outputAutoCommitFirstWordConfidence) const;
private: private:
DISALLOW_IMPLICIT_CONSTRUCTORS(Suggest); DISALLOW_IMPLICIT_CONSTRUCTORS(Suggest);

View file

@ -22,13 +22,13 @@
namespace latinime { namespace latinime {
class ProximityInfo; class ProximityInfo;
class SuggestionResults;
class SuggestInterface { class SuggestInterface {
public: public:
virtual int getSuggestions(ProximityInfo *pInfo, void *traverseSession, int *inputXs, virtual void getSuggestions(ProximityInfo *pInfo, void *traverseSession, int *inputXs,
int *inputYs, int *times, int *pointerIds, int *inputCodePoints, int inputSize, int *inputYs, int *times, int *pointerIds, int *inputCodePoints, int inputSize,
int *outWords, int *outputScores, int *outputIndices, int *outputTypes, SuggestionResults *const suggestionResults) const = 0;
int *outputAutoCommitFirstWordConfidence) const = 0;
SuggestInterface() {} SuggestInterface() {}
virtual ~SuggestInterface() {} virtual ~SuggestInterface() {}
private: private:

View file

@ -32,15 +32,8 @@ class TypingScoring : public Scoring {
public: public:
static const TypingScoring *getInstance() { return &sInstance; } static const TypingScoring *getInstance() { return &sInstance; }
AK_FORCE_INLINE bool getMostProbableString(const DicTraverseSession *const traverseSession, AK_FORCE_INLINE void getMostProbableString(const DicTraverseSession *const traverseSession,
const int terminalSize, const float languageWeight, int *const outputCodePoints, const float languageWeight, SuggestionResults *const outSuggestionResults) const {}
int *const type, int *const freq) const {
return false;
}
AK_FORCE_INLINE void safetyNetForMostProbableString(const int scoreCount, const int maxScore,
int *const outputCodePoints, int *const scores) const {
}
AK_FORCE_INLINE float getAdjustedLanguageWeight(DicTraverseSession *const traverseSession, AK_FORCE_INLINE float getAdjustedLanguageWeight(DicTraverseSession *const traverseSession,
DicNode *const terminals, const int size) const { DicNode *const terminals, const int size) const {