Make no-recursive getWordRec

Change-Id: Id90f3ca86ef490834cefa92f0d6958b1289fc633
main
satok 2010-12-07 13:08:39 +09:00
parent e00b7c5f7b
commit d299792368
2 changed files with 68 additions and 10 deletions

View File

@ -179,7 +179,8 @@ bool UnigramDictionary::sameAsTyped(unsigned short *word, int length) {
static const char QUOTE = '\''; static const char QUOTE = '\'';
void UnigramDictionary::getWords(const int initialPos, const int inputLength, const int skipPos, // Keep this for comparing spec to new getWords
void UnigramDictionary::getWordsOld(const int initialPos, const int inputLength, const int skipPos,
int *nextLetters, const int nextLettersSize) { int *nextLetters, const int nextLettersSize) {
int initialPosition = initialPos; int initialPosition = initialPos;
const int count = Dictionary::getCount(DICT, &initialPosition); const int count = Dictionary::getCount(DICT, &initialPosition);
@ -188,6 +189,55 @@ void UnigramDictionary::getWords(const int initialPos, const int inputLength, co
mInputLength <= 0, 1, 0, 0, skipPos, nextLetters, nextLettersSize); mInputLength <= 0, 1, 0, 0, skipPos, nextLetters, nextLettersSize);
} }
void UnigramDictionary::getWords(const int rootPos, const int inputLength, const int skipPos,
int *nextLetters, const int nextLettersSize) {
int rootPosition = rootPos;
const int MAX_DEPTH = min(inputLength * MAX_DEPTH_MULTIPLIER, MAX_WORD_LENGTH);
// Get the number of child of root, then increment the position
int childCount = Dictionary::getCount(DICT, &rootPosition);
int depth = 0;
mStackChildCount[0] = childCount;
mStackTraverseAll[0] = (mInputLength <= 0);
mStackNodeFreq[0] = 1;
mStackInputIndex[0] = 0;
mStackDiffs[0] = 0;
mStackSiblingPos[0] = rootPosition;
while (depth >= 0) {
if (mStackChildCount[depth] > 0) {
--mStackChildCount[depth];
bool traverseAllNodes = mStackTraverseAll[depth];
int snr = mStackNodeFreq[depth];
int inputIndex = mStackInputIndex[depth];
int diffs = mStackDiffs[depth];
int siblingPos = mStackSiblingPos[depth];
int firstChildPos;
// depth will never be greater than MAX_DEPTH because in that case,
// needsToTraverseChildrenNodes should be false
const bool needsToTraverseChildrenNodes = processCurrentNode(siblingPos, depth,
MAX_DEPTH, traverseAllNodes, snr, inputIndex, diffs, skipPos, nextLetters,
nextLettersSize, &childCount, &firstChildPos, &traverseAllNodes, &snr,
&inputIndex, &diffs, &siblingPos);
// Next sibling pos
mStackSiblingPos[depth] = siblingPos;
if (needsToTraverseChildrenNodes) {
// Goes to child node
++depth;
mStackChildCount[depth] = childCount;
mStackTraverseAll[depth] = traverseAllNodes;
mStackNodeFreq[depth] = snr;
mStackInputIndex[depth] = inputIndex;
mStackDiffs[depth] = diffs;
mStackSiblingPos[depth] = firstChildPos;
}
} else {
// Goes to parent node
--depth;
}
}
}
// snr : frequency? // snr : frequency?
void UnigramDictionary::getWordsRec(const int childrenCount, const int pos, const int depth, void UnigramDictionary::getWordsRec(const int childrenCount, const int pos, const int depth,
const int maxDepth, const bool traverseAllNodes, const int snr, const int inputIndex, const int maxDepth, const bool traverseAllNodes, const int snr, const int inputIndex,
@ -196,7 +246,7 @@ void UnigramDictionary::getWordsRec(const int childrenCount, const int pos, cons
for (int i = 0; i < childrenCount; ++i) { for (int i = 0; i < childrenCount; ++i) {
int newCount; int newCount;
int newChildPosition; int newChildPosition;
int newDepth; const int newDepth = depth + 1;
bool newTraverseAllNodes; bool newTraverseAllNodes;
int newSnr; int newSnr;
int newInputIndex; int newInputIndex;
@ -204,7 +254,7 @@ void UnigramDictionary::getWordsRec(const int childrenCount, const int pos, cons
int newSiblingPos; int newSiblingPos;
const bool needsToTraverseChildrenNodes = processCurrentNode(siblingPos, depth, maxDepth, const bool needsToTraverseChildrenNodes = processCurrentNode(siblingPos, depth, maxDepth,
traverseAllNodes, snr, inputIndex, diffs, skipPos, nextLetters, nextLettersSize, traverseAllNodes, snr, inputIndex, diffs, skipPos, nextLetters, nextLettersSize,
&newCount, &newChildPosition, &newDepth, &newTraverseAllNodes, &newSnr, &newCount, &newChildPosition, &newTraverseAllNodes, &newSnr,
&newInputIndex, &newDiffs, &newSiblingPos); &newInputIndex, &newDiffs, &newSiblingPos);
siblingPos = newSiblingPos; siblingPos = newSiblingPos;
@ -264,7 +314,7 @@ inline int UnigramDictionary::getMatchedProximityId(const int *currentChars,
inline bool UnigramDictionary::processCurrentNode(const int pos, const int depth, inline bool UnigramDictionary::processCurrentNode(const int pos, const int depth,
const int maxDepth, const bool traverseAllNodes, const int snr, const int inputIndex, const int maxDepth, const bool traverseAllNodes, const int snr, const int inputIndex,
const int diffs, const int skipPos, int *nextLetters, const int nextLettersSize, const int diffs, const int skipPos, int *nextLetters, const int nextLettersSize,
int *newCount, int *newChildPosition, int *newDepth, bool *newTraverseAllNodes, int *newCount, int *newChildPosition, bool *newTraverseAllNodes,
int *newSnr, int*newInputIndex, int *newDiffs, int *nextSiblingPosition) { int *newSnr, int*newInputIndex, int *newDiffs, int *nextSiblingPosition) {
unsigned short c; unsigned short c;
int childPosition; int childPosition;
@ -287,7 +337,6 @@ inline bool UnigramDictionary::processCurrentNode(const int pos, const int depth
*newSnr = snr; *newSnr = snr;
*newDiffs = diffs; *newDiffs = diffs;
*newInputIndex = inputIndex; *newInputIndex = inputIndex;
*newDepth = depth + 1;
} else { } else {
int *currentChars = mInputCodes + (inputIndex * MAX_ALTERNATIVES); int *currentChars = mInputCodes + (inputIndex * MAX_ALTERNATIVES);
int matchedProximityCharId = getMatchedProximityId(currentChars, c, skipPos); int matchedProximityCharId = getMatchedProximityId(currentChars, c, skipPos);
@ -307,10 +356,9 @@ inline bool UnigramDictionary::processCurrentNode(const int pos, const int depth
*newSnr = snr * addedWeight; *newSnr = snr * addedWeight;
*newDiffs = diffs + (matchedProximityCharId > 0); *newDiffs = diffs + (matchedProximityCharId > 0);
*newInputIndex = inputIndex + 1; *newInputIndex = inputIndex + 1;
*newDepth = depth + 1;
} }
// Optimization: Prune out words that are too long compared to how much was typed. // Optimization: Prune out words that are too long compared to how much was typed.
if (*newDepth > maxDepth || *newDiffs > mMaxEditDistance) { if (depth >= maxDepth || *newDiffs > mMaxEditDistance) {
return false; return false;
} }

View File

@ -44,8 +44,11 @@ private:
void getWordsRec(const int childrenCount, const int pos, const int depth, const int maxDepth, void getWordsRec(const int childrenCount, const int pos, const int depth, const int maxDepth,
const bool traverseAllNodes, const int snr, const int inputIndex, const int diffs, const bool traverseAllNodes, const int snr, const int inputIndex, const int diffs,
const int skipPos, int *nextLetters, const int nextLettersSize); const int skipPos, int *nextLetters, const int nextLettersSize);
void getWords(const int initialPos, const int inputLength, const int skipPos, int *nextLetters, void getWords(const int rootPos, const int inputLength, const int skipPos,
const int nextLettersSize); int *nextLetters, const int nextLettersSize);
// Keep getWordsOld for comparing performance between getWords and getWordsOld
void getWordsOld(const int initialPos, const int inputLength, const int skipPos,
int *nextLetters, const int nextLettersSize);
void registerNextLetter(unsigned short c, int *nextLetters, int nextLettersSize); void registerNextLetter(unsigned short c, int *nextLetters, int nextLettersSize);
void onTerminalWhenUserTypedLengthIsGreaterThanInputLength(unsigned short *word, void onTerminalWhenUserTypedLengthIsGreaterThanInputLength(unsigned short *word,
const int mInputLength, const int depth, const int snr, int *nextLetters, const int mInputLength, const int depth, const int snr, int *nextLetters,
@ -58,7 +61,7 @@ private:
bool processCurrentNode(const int pos, const int depth, bool processCurrentNode(const int pos, const int depth,
const int maxDepth, const bool traverseAllNodes, const int snr, const int inputIndex, const int maxDepth, const bool traverseAllNodes, const int snr, const int inputIndex,
const int diffs, const int skipPos, int *nextLetters, const int nextLettersSize, const int diffs, const int skipPos, int *nextLetters, const int nextLettersSize,
int *newCount, int *newChildPosition, int *newDepth, bool *newTraverseAllNodes, int *newCount, int *newChildPosition, bool *newTraverseAllNodes,
int *newSnr, int*newInputIndex, int *newDiffs, int *nextSiblingPosition); int *newSnr, int*newInputIndex, int *newDiffs, int *nextSiblingPosition);
const unsigned char *DICT; const unsigned char *DICT;
const int MAX_WORDS; const int MAX_WORDS;
@ -75,6 +78,13 @@ private:
// MAX_WORD_LENGTH_INTERNAL must be bigger than MAX_WORD_LENGTH // MAX_WORD_LENGTH_INTERNAL must be bigger than MAX_WORD_LENGTH
unsigned short mWord[MAX_WORD_LENGTH_INTERNAL]; unsigned short mWord[MAX_WORD_LENGTH_INTERNAL];
int mMaxEditDistance; int mMaxEditDistance;
int mStackChildCount[MAX_WORD_LENGTH_INTERNAL];
bool mStackTraverseAll[MAX_WORD_LENGTH_INTERNAL];
int mStackNodeFreq[MAX_WORD_LENGTH_INTERNAL];
int mStackInputIndex[MAX_WORD_LENGTH_INTERNAL];
int mStackDiffs[MAX_WORD_LENGTH_INTERNAL];
int mStackSiblingPos[MAX_WORD_LENGTH_INTERNAL];
}; };
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------