am be963611: Merge "Check contents in user history dictionary tests"

* commit 'be9636115689689a1f60da35658cacf0df90608d':
  Check contents in user history dictionary tests
main
Satoshi Kataoka 2013-09-08 23:48:16 -07:00 committed by Android Git Automerger
commit 011ce47f12
6 changed files with 87 additions and 29 deletions

View File

@ -24,6 +24,7 @@ import com.android.inputmethod.annotations.UsedForTesting;
import com.android.inputmethod.keyboard.ProximityInfo; import com.android.inputmethod.keyboard.ProximityInfo;
import com.android.inputmethod.latin.SuggestedWords.SuggestedWordInfo; import com.android.inputmethod.latin.SuggestedWords.SuggestedWordInfo;
import com.android.inputmethod.latin.personalization.DynamicPersonalizationDictionaryWriter; import com.android.inputmethod.latin.personalization.DynamicPersonalizationDictionaryWriter;
import com.android.inputmethod.latin.personalization.DynamicPredictionDictionaryBase;
import com.android.inputmethod.latin.utils.CollectionUtils; import com.android.inputmethod.latin.utils.CollectionUtils;
import java.io.File; import java.io.File;
@ -72,7 +73,7 @@ abstract public class ExpandableBinaryDictionary extends Dictionary {
private BinaryDictionary mBinaryDictionary; private BinaryDictionary mBinaryDictionary;
/** The in-memory dictionary used to generate the binary dictionary. */ /** The in-memory dictionary used to generate the binary dictionary. */
private AbstractDictionaryWriter mDictionaryWriter; protected AbstractDictionaryWriter mDictionaryWriter;
/** /**
* The name of this dictionary, used as the filename for storing the binary dictionary. Multiple * The name of this dictionary, used as the filename for storing the binary dictionary. Multiple
@ -624,4 +625,35 @@ abstract public class ExpandableBinaryDictionary extends Dictionary {
mLocalDictionaryController.writeLock().unlock(); mLocalDictionaryController.writeLock().unlock();
} }
} }
// TODO: Implement native binary methods once the dynamic dictionary implementation is done.
@UsedForTesting
public boolean isInDictionaryForTests(final String word) {
mLocalDictionaryController.writeLock().lock();
try {
if (mDictType == Dictionary.TYPE_USER_HISTORY) {
return ((DynamicPersonalizationDictionaryWriter) mDictionaryWriter)
.isInDictionaryForTests(word);
}
} finally {
mLocalDictionaryController.writeLock().unlock();
}
return false;
}
// TODO: Remove and use addToPersonalizationPredictionDictionary instead!!!!!!!!!!!!!!!!
@UsedForTesting
public void forceAddWordForTest(
final String word0, final String word1, final boolean isValid) {
mLocalDictionaryController.writeLock().lock();
try {
mDictionaryWriter.addUnigramWord(word1, null /* the "shortcut" parameter is null */,
DynamicPredictionDictionaryBase.FREQUENCY_FOR_TYPED, false /* isNotAWord */);
mDictionaryWriter.addBigramWords(word0, word1,
DynamicPredictionDictionaryBase.FREQUENCY_FOR_TYPED, isValid,
0 /* lastTouchedTime */);
} finally {
mLocalDictionaryController.writeLock().unlock();
}
}
} }

View File

@ -265,10 +265,10 @@ public class ExpandableDictionary extends Dictionary {
return (node == null) ? false : !node.mShortcutOnly; return (node == null) ? false : !node.mShortcutOnly;
} }
public boolean removeBigram(final String word1, final String word2) { public boolean removeBigram(final String word0, final String word1) {
// Refer to addOrSetBigram() about word1.toLowerCase() // Refer to addOrSetBigram() about word1.toLowerCase()
final Node firstWord = searchWord(mRoots, word1.toLowerCase(), 0, null); final Node firstWord = searchWord(mRoots, word0.toLowerCase(), 0, null);
final Node secondWord = searchWord(mRoots, word2, 0, null); final Node secondWord = searchWord(mRoots, word1, 0, null);
LinkedList<NextWord> bigrams = firstWord.mNGrams; LinkedList<NextWord> bigrams = firstWord.mNGrams;
NextWord bigramNode = null; NextWord bigramNode = null;
if (bigrams == null || bigrams.size() == 0) { if (bigrams == null || bigrams.size() == 0) {
@ -297,10 +297,10 @@ public class ExpandableDictionary extends Dictionary {
return (node == null) ? -1 : node.mFrequency; return (node == null) ? -1 : node.mFrequency;
} }
public NextWord getBigramWord(final String word1, final String word2) { public NextWord getBigramWord(final String word0, final String word1) {
// Refer to addOrSetBigram() about word1.toLowerCase() // Refer to addOrSetBigram() about word0.toLowerCase()
final Node firstWord = searchWord(mRoots, word1.toLowerCase(), 0, null); final Node firstWord = searchWord(mRoots, word0.toLowerCase(), 0, null);
final Node secondWord = searchWord(mRoots, word2, 0, null); final Node secondWord = searchWord(mRoots, word1, 0, null);
LinkedList<NextWord> bigrams = firstWord.mNGrams; LinkedList<NextWord> bigrams = firstWord.mNGrams;
if (bigrams == null || bigrams.size() == 0) { if (bigrams == null || bigrams.size() == 0) {
return null; return null;
@ -473,37 +473,41 @@ public class ExpandableDictionary extends Dictionary {
} }
} }
public int setBigramAndGetFrequency(final String word1, final String word2, public int setBigramAndGetFrequency(final String word0, final String word1,
final int frequency) { final int frequency) {
return setBigramAndGetFrequency(word1, word2, frequency, null /* unused */); return setBigramAndGetFrequency(word0, word1, frequency, null /* unused */);
} }
public int setBigramAndGetFrequency(final String word1, final String word2, public int setBigramAndGetFrequency(final String word0, final String word1,
final ForgettingCurveParams fcp) { final ForgettingCurveParams fcp) {
return setBigramAndGetFrequency(word1, word2, 0 /* unused */, fcp); return setBigramAndGetFrequency(word0, word1, 0 /* unused */, fcp);
} }
/** /**
* Adds bigrams to the in-memory trie structure that is being used to retrieve any word * Adds bigrams to the in-memory trie structure that is being used to retrieve any word
* @param word1 the first word of this bigram * @param word0 the first word of this bigram
* @param word2 the second word of this bigram * @param word1 the second word of this bigram
* @param frequency frequency for this bigram * @param frequency frequency for this bigram
* @param fcp an instance of ForgettingCurveParams to use for decay policy * @param fcp an instance of ForgettingCurveParams to use for decay policy
* @return returns the final bigram frequency * @return returns the final bigram frequency
*/ */
private int setBigramAndGetFrequency(final String word1, final String word2, private int setBigramAndGetFrequency(final String word0, final String word1,
final int frequency, final ForgettingCurveParams fcp) { final int frequency, final ForgettingCurveParams fcp) {
if (TextUtils.isEmpty(word0)) {
Log.e(TAG, "Invalid bigram previous word: " + word0);
return frequency;
}
// We don't want results to be different according to case of the looked up left hand side // We don't want results to be different according to case of the looked up left hand side
// word. We do want however to return the correct case for the right hand side. // word. We do want however to return the correct case for the right hand side.
// So we want to squash the case of the left hand side, and preserve that of the right // So we want to squash the case of the left hand side, and preserve that of the right
// hand side word. // hand side word.
final String word1Lower = word1.toLowerCase(); final String word0Lower = word0.toLowerCase();
if (TextUtils.isEmpty(word1Lower) || TextUtils.isEmpty(word2)) { if (TextUtils.isEmpty(word0Lower) || TextUtils.isEmpty(word1)) {
Log.e(TAG, "Invalid bigram pair: " + word1 + ", " + word1Lower + ", " + word2); Log.e(TAG, "Invalid bigram pair: " + word0 + ", " + word0Lower + ", " + word1);
return frequency; return frequency;
} }
final Node firstWord = searchWord(mRoots, word1Lower, 0, null); final Node firstWord = searchWord(mRoots, word0Lower, 0, null);
final Node secondWord = searchWord(mRoots, word2, 0, null); final Node secondWord = searchWord(mRoots, word1, 0, null);
LinkedList<NextWord> bigrams = firstWord.mNGrams; LinkedList<NextWord> bigrams = firstWord.mNGrams;
if (bigrams == null || bigrams.size() == 0) { if (bigrams == null || bigrams.size() == 0) {
firstWord.mNGrams = CollectionUtils.newLinkedList(); firstWord.mNGrams = CollectionUtils.newLinkedList();

View File

@ -18,6 +18,7 @@ package com.android.inputmethod.latin.personalization;
import android.content.Context; import android.content.Context;
import com.android.inputmethod.annotations.UsedForTesting;
import com.android.inputmethod.keyboard.ProximityInfo; import com.android.inputmethod.keyboard.ProximityInfo;
import com.android.inputmethod.latin.AbstractDictionaryWriter; import com.android.inputmethod.latin.AbstractDictionaryWriter;
import com.android.inputmethod.latin.ExpandableDictionary; import com.android.inputmethod.latin.ExpandableDictionary;
@ -156,4 +157,10 @@ public class DynamicPersonalizationDictionaryWriter extends AbstractDictionaryWr
public boolean isValidWord(final String word) { public boolean isValidWord(final String word) {
return mExpandableDictionary.isValidWord(word); return mExpandableDictionary.isValidWord(word);
} }
@UsedForTesting
public boolean isInDictionaryForTests(final String word) {
// TODO: Use native method to determine whether the word is in dictionary or not
return mBigramList.containsKey(word);
}
} }

View File

@ -196,12 +196,6 @@ public abstract class DynamicPredictionDictionaryBase extends ExpandableBinaryDi
return mLocale; return mLocale;
} }
@UsedForTesting
/* package for test */ void forceAddWordForTest(
final String word0, final String word1, final boolean isValid) {
addToPersonalizationPredictionDictionary(word0, word1, isValid);
}
public void registerUpdateSession(PersonalizationDictionaryUpdateSession session) { public void registerUpdateSession(PersonalizationDictionaryUpdateSession session) {
session.setPredictionDictionary(this); session.setPredictionDictionary(this);
mSessions.add(session); mSessions.add(session);

View File

@ -97,6 +97,10 @@ public final class UserHistoryDictionaryBigramList {
return mBigramMap.isEmpty(); return mBigramMap.isEmpty();
} }
public boolean containsKey(String word) {
return mBigramMap.containsKey(word);
}
public Set<String> keySet() { public Set<String> keySet() {
return mBigramMap.keySet(); return mBigramMap.keySet();
} }

View File

@ -82,14 +82,29 @@ public class UserHistoryDictionaryTests extends AndroidTestCase {
} }
} }
/**
* @param checksContents if true, checks whether written words are actually in the dictionary
* or not.
*/
private void addAndWriteRandomWords(final String testFilenameSuffix, final int numberOfWords, private void addAndWriteRandomWords(final String testFilenameSuffix, final int numberOfWords,
final Random random) { final Random random, final boolean checksContents) {
final List<String> words = generateWords(numberOfWords, random); final List<String> words = generateWords(numberOfWords, random);
final UserHistoryPredictionDictionary dict = final UserHistoryPredictionDictionary dict =
PersonalizationHelper.getUserHistoryPredictionDictionary(getContext(), PersonalizationHelper.getUserHistoryPredictionDictionary(getContext(),
testFilenameSuffix /* locale */, mPrefs); testFilenameSuffix /* locale */, mPrefs);
// Add random words to the user history dictionary. // Add random words to the user history dictionary.
addToDict(dict, words); addToDict(dict, words);
if (checksContents) {
try {
Thread.sleep(TimeUnit.MILLISECONDS.convert(5L, TimeUnit.SECONDS));
} catch (InterruptedException e) {
}
for (int i = 0; i < 10 && i < numberOfWords; ++i) {
final String word = words.get(i);
// This may fail as long as we use tryLock on inserting the bigram words
assertTrue(dict.isInDictionaryForTests(word));
}
}
// write to file. // write to file.
dict.close(); dict.close();
} }
@ -103,7 +118,8 @@ public class UserHistoryDictionaryTests extends AndroidTestCase {
final Random random = new Random(123456); final Random random = new Random(123456);
try { try {
addAndWriteRandomWords(testFilenameSuffix, numberOfWords, random); addAndWriteRandomWords(testFilenameSuffix, numberOfWords, random,
true /* checksContents */);
} finally { } finally {
try { try {
Log.d(TAG, "waiting for writing ..."); Log.d(TAG, "waiting for writing ...");
@ -148,7 +164,8 @@ public class UserHistoryDictionaryTests extends AndroidTestCase {
final int index = i % numberOfLanguages; final int index = i % numberOfLanguages;
// Switch languages to testFilenameSuffixes[index]. // Switch languages to testFilenameSuffixes[index].
addAndWriteRandomWords(testFilenameSuffixes[index], addAndWriteRandomWords(testFilenameSuffixes[index],
numberOfWordsInsertedForEachLanguageSwitch, random); numberOfWordsInsertedForEachLanguageSwitch, random,
false /* checksContents */);
} }
final long end = System.currentTimeMillis(); final long end = System.currentTimeMillis();