diff options
27 files changed, 445 insertions, 359 deletions
diff --git a/java/src/com/android/inputmethod/latin/ExpandableBinaryDictionary.java b/java/src/com/android/inputmethod/latin/ExpandableBinaryDictionary.java index 7107076cc..056054273 100644 --- a/java/src/com/android/inputmethod/latin/ExpandableBinaryDictionary.java +++ b/java/src/com/android/inputmethod/latin/ExpandableBinaryDictionary.java @@ -53,6 +53,7 @@ abstract public class ExpandableBinaryDictionary extends Dictionary { /** Whether to print debug output to log */ private static boolean DEBUG = false; + private static final boolean DBG_STRESS_TEST = false; private static final int TIMEOUT_FOR_READ_OPS_IN_MILLISECONDS = 100; @@ -496,6 +497,16 @@ abstract public class ExpandableBinaryDictionary extends Dictionary { + mFilenameDictionaryUpdateController.mLastUpdateRequestTime + " update=" + mFilenameDictionaryUpdateController.mLastUpdateTime); } + if (DBG_STRESS_TEST) { + // Test if this class does not cause problems when it takes long time to load binary + // dictionary. + try { + Log.w(TAG, "Start stress in loading: " + mFilename); + Thread.sleep(15000); + Log.w(TAG, "End stress in loading"); + } catch (InterruptedException e) { + } + } final File file = new File(mContext.getFilesDir(), mFilename + getFileNameExtentionToOpenDict()); diff --git a/java/src/com/android/inputmethod/latin/LatinIME.java b/java/src/com/android/inputmethod/latin/LatinIME.java index 87eed3bc9..16d860f22 100644 --- a/java/src/com/android/inputmethod/latin/LatinIME.java +++ b/java/src/com/android/inputmethod/latin/LatinIME.java @@ -649,14 +649,13 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen final SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this); - mUserHistoryDictionary = PersonalizationHelper.getUserHistoryDictionary( - this, localeStr, prefs); + mUserHistoryDictionary = PersonalizationHelper.getUserHistoryDictionary(this, localeStr); newSuggest.setUserHistoryDictionary(mUserHistoryDictionary); - mPersonalizationDictionary = PersonalizationHelper - .getPersonalizationDictionary(this, localeStr, prefs); + mPersonalizationDictionary = + PersonalizationHelper.getPersonalizationDictionary(this, localeStr); newSuggest.setPersonalizationDictionary(mPersonalizationDictionary); - mPersonalizationPredictionDictionary = PersonalizationHelper - .getPersonalizationPredictionDictionary(this, localeStr, prefs); + mPersonalizationPredictionDictionary = + PersonalizationHelper.getPersonalizationPredictionDictionary(this, localeStr); newSuggest.setPersonalizationPredictionDictionary(mPersonalizationPredictionDictionary); final Suggest oldSuggest = mSuggest; diff --git a/java/src/com/android/inputmethod/latin/makedict/FormatSpec.java b/java/src/com/android/inputmethod/latin/makedict/FormatSpec.java index f85431ee8..555c71b4c 100644 --- a/java/src/com/android/inputmethod/latin/makedict/FormatSpec.java +++ b/java/src/com/android/inputmethod/latin/makedict/FormatSpec.java @@ -379,6 +379,15 @@ public final class FormatSpec { mHeaderSize = headerSize; mDictionaryOptions = dictionaryOptions; mFormatOptions = formatOptions; + if (null == getLocaleString()) { + throw new RuntimeException("Cannot create a FileHeader without a locale"); + } + if (null == getVersion()) { + throw new RuntimeException("Cannot create a FileHeader without a version"); + } + if (null == getId()) { + throw new RuntimeException("Cannot create a FileHeader without an ID"); + } } // Helper method to get the locale as a String diff --git a/java/src/com/android/inputmethod/latin/makedict/Ver4DictEncoder.java b/java/src/com/android/inputmethod/latin/makedict/Ver4DictEncoder.java index 772b09be0..6d045c88a 100644 --- a/java/src/com/android/inputmethod/latin/makedict/Ver4DictEncoder.java +++ b/java/src/com/android/inputmethod/latin/makedict/Ver4DictEncoder.java @@ -303,7 +303,7 @@ public class Ver4DictEncoder implements DictEncoder { @Override public void setPosition(int position) { - if (mTrieBuf == null || position < 0 || position >- mTrieBuf.length) return; + if (mTrieBuf == null || position < 0 || position > mTrieBuf.length) return; mTriePos = position; } diff --git a/java/src/com/android/inputmethod/latin/makedict/Ver4DictUpdater.java b/java/src/com/android/inputmethod/latin/makedict/Ver4DictUpdater.java index 883709f83..91d9cf345 100644 --- a/java/src/com/android/inputmethod/latin/makedict/Ver4DictUpdater.java +++ b/java/src/com/android/inputmethod/latin/makedict/Ver4DictUpdater.java @@ -140,8 +140,10 @@ public class Ver4DictUpdater extends Ver4DictDecoder implements DictUpdater { @Override public void deleteWord(final String word) throws IOException, UnsupportedFormatException { - if (mDictBuffer == null) openDictBuffer(); - readHeader(); + if (mDictBuffer == null) { + openDictBuffer(); + readHeader(); + } final int wordPos = getTerminalPosition(word); if (wordPos != FormatSpec.NOT_VALID_WORD) { mDictBuffer.position(wordPos); diff --git a/java/src/com/android/inputmethod/latin/personalization/DecayingExpandableBinaryDictionaryBase.java b/java/src/com/android/inputmethod/latin/personalization/DecayingExpandableBinaryDictionaryBase.java index 5edac232c..dbf6d0046 100644 --- a/java/src/com/android/inputmethod/latin/personalization/DecayingExpandableBinaryDictionaryBase.java +++ b/java/src/com/android/inputmethod/latin/personalization/DecayingExpandableBinaryDictionaryBase.java @@ -17,7 +17,6 @@ package com.android.inputmethod.latin.personalization; import android.content.Context; -import android.content.SharedPreferences; import android.util.Log; import com.android.inputmethod.annotations.UsedForTesting; @@ -25,11 +24,9 @@ import com.android.inputmethod.latin.BinaryDictionary.LanguageModelParam; import com.android.inputmethod.latin.Constants; import com.android.inputmethod.latin.Dictionary; import com.android.inputmethod.latin.ExpandableBinaryDictionary; -import com.android.inputmethod.latin.LatinImeLogger; import com.android.inputmethod.latin.makedict.DictDecoder; import com.android.inputmethod.latin.makedict.FormatSpec; import com.android.inputmethod.latin.makedict.UnsupportedFormatException; -import com.android.inputmethod.latin.settings.Settings; import com.android.inputmethod.latin.utils.CollectionUtils; import com.android.inputmethod.latin.utils.UserHistoryDictIOUtils; import com.android.inputmethod.latin.utils.UserHistoryDictIOUtils.OnAddWordListener; @@ -47,9 +44,7 @@ import java.util.Map; public abstract class DecayingExpandableBinaryDictionaryBase extends ExpandableBinaryDictionary { private static final String TAG = DecayingExpandableBinaryDictionaryBase.class.getSimpleName(); public static final boolean DBG_SAVE_RESTORE = false; - private static final boolean DBG_STRESS_TEST = false; private static final boolean DBG_DUMP_ON_CLOSE = false; - private static final boolean PROFILE_SAVE_RESTORE = LatinImeLogger.sDBG; /** Any pair being typed or picked */ public static final int FREQUENCY_FOR_TYPED = 2; @@ -64,8 +59,6 @@ public abstract class DecayingExpandableBinaryDictionaryBase extends ExpandableB private final String mFileName; - private final SharedPreferences mPrefs; - private final ArrayList<PersonalizationDictionaryUpdateSession> mSessions = CollectionUtils.newArrayList(); @@ -73,12 +66,10 @@ public abstract class DecayingExpandableBinaryDictionaryBase extends ExpandableB @UsedForTesting boolean mIsTest = false; /* package */ DecayingExpandableBinaryDictionaryBase(final Context context, - final String locale, final SharedPreferences sp, final String dictionaryType, - final String fileName) { + final String locale, final String dictionaryType, final String fileName) { super(context, fileName, dictionaryType, true); mLocale = locale; mFileName = fileName; - mPrefs = sp; if (mLocale != null && mLocale.length() > 1) { reloadDictionaryIfRequired(); } @@ -92,7 +83,6 @@ public abstract class DecayingExpandableBinaryDictionaryBase extends ExpandableB // Flush pending writes. // TODO: Remove after this class become to use a dynamic binary dictionary. asyncFlashAllBinaryDictionary(); - Settings.writeLastUserHistoryWriteTime(mPrefs, mLocale); } @Override @@ -171,67 +161,7 @@ public abstract class DecayingExpandableBinaryDictionaryBase extends ExpandableB @Override protected void loadDictionaryAsync() { - final int[] profTotalCount = { 0 }; - final String locale = getLocale(); - if (DBG_STRESS_TEST) { - try { - Log.w(TAG, "Start stress in loading: " + locale); - Thread.sleep(15000); - Log.w(TAG, "End stress in loading"); - } catch (InterruptedException e) { - } - } - final long last = Settings.readLastUserHistoryWriteTime(mPrefs, locale); - final long now = System.currentTimeMillis(); - final ExpandableBinaryDictionary dictionary = this; - final OnAddWordListener listener = new OnAddWordListener() { - @Override - public void setUnigram(final String word, final String shortcutTarget, - final int frequency, final int shortcutFreq) { - if (DBG_SAVE_RESTORE) { - Log.d(TAG, "load unigram: " + word + "," + frequency); - } - addWord(word, shortcutTarget, frequency, shortcutFreq, false /* isNotAWord */); - ++profTotalCount[0]; - } - - @Override - public void setBigram(final String word0, final String word1, final int frequency) { - if (word0.length() < Constants.DICTIONARY_MAX_WORD_LENGTH - && word1.length() < Constants.DICTIONARY_MAX_WORD_LENGTH) { - if (DBG_SAVE_RESTORE) { - Log.d(TAG, "load bigram: " + word0 + "," + word1 + "," + frequency); - } - ++profTotalCount[0]; - addBigram(word0, word1, frequency, last); - } - } - }; - - // Load the dictionary from binary file - final File dictFile = new File(mContext.getFilesDir(), mFileName); - final DictDecoder dictDecoder = FormatSpec.getDictDecoder(dictFile, - DictDecoder.USE_BYTEARRAY); - if (dictDecoder == null) { - // This is an expected condition: we don't have a user history dictionary for this - // language yet. It will be created sometime later. - return; - } - - try { - dictDecoder.openDictBuffer(); - UserHistoryDictIOUtils.readDictionaryBinary(dictDecoder, listener); - } catch (IOException e) { - Log.d(TAG, "IOException on opening a bytebuffer", e); - } catch (UnsupportedFormatException e) { - Log.d(TAG, "Unsupported format, can't read the dictionary", e); - } finally { - if (PROFILE_SAVE_RESTORE) { - final long diff = System.currentTimeMillis() - now; - Log.d(TAG, "PROF: Load UserHistoryDictionary: " - + locale + ", " + diff + "ms. load " + profTotalCount[0] + "entries."); - } - } + // Never loaded to memory in Java side. } protected String getLocale() { diff --git a/java/src/com/android/inputmethod/latin/personalization/PersonalizationDictionary.java b/java/src/com/android/inputmethod/latin/personalization/PersonalizationDictionary.java index f257165cb..67015f491 100644 --- a/java/src/com/android/inputmethod/latin/personalization/PersonalizationDictionary.java +++ b/java/src/com/android/inputmethod/latin/personalization/PersonalizationDictionary.java @@ -36,8 +36,7 @@ public class PersonalizationDictionary extends ExpandableBinaryDictionary { /** Locale for which this user history dictionary is storing words */ private final String mLocale; - public PersonalizationDictionary(final Context context, final String locale, - final SharedPreferences prefs) { + public PersonalizationDictionary(final Context context, final String locale) { // TODO: Make isUpdatable true. super(context, getFilenameWithLocale(NAME, locale), Dictionary.TYPE_PERSONALIZATION, false /* isUpdatable */); diff --git a/java/src/com/android/inputmethod/latin/personalization/PersonalizationHelper.java b/java/src/com/android/inputmethod/latin/personalization/PersonalizationHelper.java index 221ddeeba..a47cc4db9 100644 --- a/java/src/com/android/inputmethod/latin/personalization/PersonalizationHelper.java +++ b/java/src/com/android/inputmethod/latin/personalization/PersonalizationHelper.java @@ -41,7 +41,7 @@ public class PersonalizationHelper { CollectionUtils.newConcurrentHashMap(); public static UserHistoryDictionary getUserHistoryDictionary( - final Context context, final String locale, final SharedPreferences sp) { + final Context context, final String locale) { synchronized (sLangUserHistoryDictCache) { if (sLangUserHistoryDictCache.containsKey(locale)) { final SoftReference<UserHistoryDictionary> ref = @@ -55,7 +55,7 @@ public class PersonalizationHelper { return dict; } } - final UserHistoryDictionary dict = new UserHistoryDictionary(context, locale, sp); + final UserHistoryDictionary dict = new UserHistoryDictionary(context, locale); sLangUserHistoryDictCache.put(locale, new SoftReference<UserHistoryDictionary>(dict)); return dict; } @@ -76,17 +76,14 @@ public class PersonalizationHelper { public static void registerPersonalizationDictionaryUpdateSession(final Context context, final PersonalizationDictionaryUpdateSession session, String locale) { final PersonalizationPredictionDictionary predictionDictionary = - getPersonalizationPredictionDictionary(context, locale, - PreferenceManager.getDefaultSharedPreferences(context)); + getPersonalizationPredictionDictionary(context, locale); predictionDictionary.registerUpdateSession(session); - final PersonalizationDictionary dictionary = - getPersonalizationDictionary(context, locale, - PreferenceManager.getDefaultSharedPreferences(context)); + final PersonalizationDictionary dictionary = getPersonalizationDictionary(context, locale); dictionary.registerUpdateSession(session); } public static PersonalizationDictionary getPersonalizationDictionary( - final Context context, final String locale, final SharedPreferences sp) { + final Context context, final String locale) { synchronized (sLangPersonalizationDictCache) { if (sLangPersonalizationDictCache.containsKey(locale)) { final SoftReference<PersonalizationDictionary> ref = @@ -99,8 +96,7 @@ public class PersonalizationHelper { return dict; } } - final PersonalizationDictionary dict = - new PersonalizationDictionary(context, locale, sp); + final PersonalizationDictionary dict = new PersonalizationDictionary(context, locale); sLangPersonalizationDictCache.put( locale, new SoftReference<PersonalizationDictionary>(dict)); return dict; @@ -108,7 +104,7 @@ public class PersonalizationHelper { } public static PersonalizationPredictionDictionary getPersonalizationPredictionDictionary( - final Context context, final String locale, final SharedPreferences sp) { + final Context context, final String locale) { synchronized (sLangPersonalizationPredictionDictCache) { if (sLangPersonalizationPredictionDictCache.containsKey(locale)) { final SoftReference<PersonalizationPredictionDictionary> ref = @@ -122,7 +118,7 @@ public class PersonalizationHelper { } } final PersonalizationPredictionDictionary dict = - new PersonalizationPredictionDictionary(context, locale, sp); + new PersonalizationPredictionDictionary(context, locale); sLangPersonalizationPredictionDictCache.put( locale, new SoftReference<PersonalizationPredictionDictionary>(dict)); return dict; diff --git a/java/src/com/android/inputmethod/latin/personalization/PersonalizationPredictionDictionary.java b/java/src/com/android/inputmethod/latin/personalization/PersonalizationPredictionDictionary.java index 432954453..16107e29f 100644 --- a/java/src/com/android/inputmethod/latin/personalization/PersonalizationPredictionDictionary.java +++ b/java/src/com/android/inputmethod/latin/personalization/PersonalizationPredictionDictionary.java @@ -20,14 +20,12 @@ import com.android.inputmethod.latin.Dictionary; import com.android.inputmethod.latin.ExpandableBinaryDictionary; import android.content.Context; -import android.content.SharedPreferences; public class PersonalizationPredictionDictionary extends DecayingExpandableBinaryDictionaryBase { private static final String NAME = PersonalizationPredictionDictionary.class.getSimpleName(); - /* package */ PersonalizationPredictionDictionary(final Context context, final String locale, - final SharedPreferences sp) { - super(context, locale, sp, Dictionary.TYPE_PERSONALIZATION_PREDICTION_IN_JAVA, + /* package */ PersonalizationPredictionDictionary(final Context context, final String locale) { + super(context, locale, Dictionary.TYPE_PERSONALIZATION_PREDICTION_IN_JAVA, getDictionaryFileName(locale)); } diff --git a/java/src/com/android/inputmethod/latin/personalization/UserHistoryDictionary.java b/java/src/com/android/inputmethod/latin/personalization/UserHistoryDictionary.java index a60226d7e..95a6fe142 100644 --- a/java/src/com/android/inputmethod/latin/personalization/UserHistoryDictionary.java +++ b/java/src/com/android/inputmethod/latin/personalization/UserHistoryDictionary.java @@ -20,7 +20,6 @@ import com.android.inputmethod.latin.Dictionary; import com.android.inputmethod.latin.ExpandableBinaryDictionary; import android.content.Context; -import android.content.SharedPreferences; /** * Locally gathers stats about the words user types and various other signals like auto-correction @@ -29,9 +28,8 @@ import android.content.SharedPreferences; public class UserHistoryDictionary extends DecayingExpandableBinaryDictionaryBase { /* package for tests */ static final String NAME = UserHistoryDictionary.class.getSimpleName(); - /* package */ UserHistoryDictionary(final Context context, final String locale, - final SharedPreferences sp) { - super(context, locale, sp, Dictionary.TYPE_USER_HISTORY, getDictionaryFileName(locale)); + /* package */ UserHistoryDictionary(final Context context, final String locale) { + super(context, locale, Dictionary.TYPE_USER_HISTORY, getDictionaryFileName(locale)); } private static String getDictionaryFileName(final String locale) { diff --git a/java/src/com/android/inputmethod/latin/settings/Settings.java b/java/src/com/android/inputmethod/latin/settings/Settings.java index df2c6907f..f5c1d102c 100644 --- a/java/src/com/android/inputmethod/latin/settings/Settings.java +++ b/java/src/com/android/inputmethod/latin/settings/Settings.java @@ -53,8 +53,6 @@ public final class Settings implements SharedPreferences.OnSharedPreferenceChang public static final String PREF_AUTO_CORRECTION_THRESHOLD = "auto_correction_threshold"; public static final String PREF_SHOW_SUGGESTIONS_SETTING = "show_suggestions_setting"; public static final String PREF_MISC_SETTINGS = "misc_settings"; - public static final String PREF_LAST_USER_DICTIONARY_WRITE_TIME = - "last_user_dictionary_write_time"; public static final String PREF_ADVANCED_SETTINGS = "pref_advanced_settings"; public static final String PREF_KEY_USE_CONTACTS_DICT = "pref_key_use_contacts_dict"; public static final String PREF_KEY_USE_DOUBLE_SPACE_PERIOD = @@ -333,25 +331,6 @@ public final class Settings implements SharedPreferences.OnSharedPreferenceChang return prefs.getBoolean(DebugSettings.PREF_USABILITY_STUDY_MODE, true); } - public static long readLastUserHistoryWriteTime(final SharedPreferences prefs, - final String locale) { - final String str = prefs.getString(PREF_LAST_USER_DICTIONARY_WRITE_TIME, ""); - final HashMap<String, Long> map = LocaleUtils.localeAndTimeStrToHashMap(str); - if (map.containsKey(locale)) { - return map.get(locale); - } - return 0; - } - - public static void writeLastUserHistoryWriteTime(final SharedPreferences prefs, - final String locale) { - final String oldStr = prefs.getString(PREF_LAST_USER_DICTIONARY_WRITE_TIME, ""); - final HashMap<String, Long> map = LocaleUtils.localeAndTimeStrToHashMap(oldStr); - map.put(locale, System.currentTimeMillis()); - final String newStr = LocaleUtils.localeAndTimeHashMapToStr(map); - prefs.edit().putString(PREF_LAST_USER_DICTIONARY_WRITE_TIME, newStr).apply(); - } - public static boolean readUseFullscreenMode(final Resources res) { return res.getBoolean(R.bool.config_use_fullscreen_mode); } diff --git a/java/src/com/android/inputmethod/latin/utils/LocaleUtils.java b/java/src/com/android/inputmethod/latin/utils/LocaleUtils.java index 22045aa38..b4ff849f1 100644 --- a/java/src/com/android/inputmethod/latin/utils/LocaleUtils.java +++ b/java/src/com/android/inputmethod/latin/utils/LocaleUtils.java @@ -30,9 +30,6 @@ import java.util.Locale; * dictionary pack. */ public final class LocaleUtils { - private static final HashMap<String, Long> EMPTY_LT_HASH_MAP = CollectionUtils.newHashMap(); - private static final String LOCALE_AND_TIME_STR_SEPARATER = ","; - private LocaleUtils() { // Intentional empty constructor for utility class. } @@ -188,38 +185,4 @@ public final class LocaleUtils { return retval; } } - - public static HashMap<String, Long> localeAndTimeStrToHashMap(String str) { - if (TextUtils.isEmpty(str)) { - return EMPTY_LT_HASH_MAP; - } - final String[] ss = str.split(LOCALE_AND_TIME_STR_SEPARATER); - final int N = ss.length; - if (N < 2 || N % 2 != 0) { - return EMPTY_LT_HASH_MAP; - } - final HashMap<String, Long> retval = CollectionUtils.newHashMap(); - for (int i = 0; i < N / 2; ++i) { - final String localeStr = ss[i * 2]; - final long time = Long.valueOf(ss[i * 2 + 1]); - retval.put(localeStr, time); - } - return retval; - } - - public static String localeAndTimeHashMapToStr(HashMap<String, Long> map) { - if (map == null || map.isEmpty()) { - return ""; - } - final StringBuilder builder = new StringBuilder(); - for (String localeStr : map.keySet()) { - if (builder.length() > 0) { - builder.append(LOCALE_AND_TIME_STR_SEPARATER); - } - final Long time = map.get(localeStr); - builder.append(localeStr).append(LOCALE_AND_TIME_STR_SEPARATER); - builder.append(String.valueOf(time)); - } - return builder.toString(); - } } diff --git a/native/jni/src/defines.h b/native/jni/src/defines.h index fbcd612b7..564811560 100644 --- a/native/jni/src/defines.h +++ b/native/jni/src/defines.h @@ -341,12 +341,21 @@ template<typename T> AK_FORCE_INLINE const T &max(const T &a, const T &b) { retu #define INPUTLENGTH_FOR_DEBUG (-1) #define MIN_OUTPUT_INDEX_FOR_DEBUG (-1) -#define DISALLOW_COPY_AND_ASSIGN(TypeName) \ - TypeName(const TypeName&); \ +#define DISALLOW_DEFAULT_CONSTRUCTOR(TypeName) \ + TypeName() + +#define DISALLOW_COPY_CONSTRUCTOR(TypeName) \ + TypeName(const TypeName&) + +#define DISALLOW_ASSIGNMENT_OPERATOR(TypeName) \ void operator=(const TypeName&) +#define DISALLOW_COPY_AND_ASSIGN(TypeName) \ + DISALLOW_COPY_CONSTRUCTOR(TypeName); \ + DISALLOW_ASSIGNMENT_OPERATOR(TypeName) + #define DISALLOW_IMPLICIT_CONSTRUCTORS(TypeName) \ - TypeName(); \ + DISALLOW_DEFAULT_CONSTRUCTOR(TypeName); \ DISALLOW_COPY_AND_ASSIGN(TypeName) // Used as a return value for character comparison diff --git a/native/jni/src/suggest/core/dictionary/bloom_filter.h b/native/jni/src/suggest/core/dictionary/bloom_filter.h index 5205456a8..5f9700486 100644 --- a/native/jni/src/suggest/core/dictionary/bloom_filter.h +++ b/native/jni/src/suggest/core/dictionary/bloom_filter.h @@ -50,6 +50,8 @@ class BloomFilter { } private: + DISALLOW_ASSIGNMENT_OPERATOR(BloomFilter); + // Size, in bytes, of the bloom filter index for bigrams // 128 gives us 1024 buckets. The probability of false positive is (1 - e ** (-kn/m))**k, // where k is the number of hash functions, n the number of bigrams, and m the number of diff --git a/native/jni/src/suggest/core/dictionary/multi_bigram_map.cpp b/native/jni/src/suggest/core/dictionary/multi_bigram_map.cpp index b1d2f4b4d..49d82e69a 100644 --- a/native/jni/src/suggest/core/dictionary/multi_bigram_map.cpp +++ b/native/jni/src/suggest/core/dictionary/multi_bigram_map.cpp @@ -30,4 +30,75 @@ const size_t MultiBigramMap::MAX_CACHED_PREV_WORDS_IN_BIGRAM_MAP = 25; // Most common previous word contexts currently have 100 bigrams const int MultiBigramMap::BigramMap::DEFAULT_HASH_MAP_SIZE_FOR_EACH_BIGRAM_MAP = 100; +// Look up the bigram probability for the given word pair from the cached bigram maps. +// Also caches the bigrams if there is space remaining and they have not been cached already. +int MultiBigramMap::getBigramProbability( + const DictionaryStructureWithBufferPolicy *const structurePolicy, + const int wordPosition, const int nextWordPosition, const int unigramProbability) { + hash_map_compat<int, BigramMap>::const_iterator mapPosition = + mBigramMaps.find(wordPosition); + if (mapPosition != mBigramMaps.end()) { + return mapPosition->second.getBigramProbability(structurePolicy, nextWordPosition, + unigramProbability); + } + if (mBigramMaps.size() < MAX_CACHED_PREV_WORDS_IN_BIGRAM_MAP) { + addBigramsForWordPosition(structurePolicy, wordPosition); + return mBigramMaps[wordPosition].getBigramProbability(structurePolicy, + nextWordPosition, unigramProbability); + } + return readBigramProbabilityFromBinaryDictionary(structurePolicy, wordPosition, + nextWordPosition, unigramProbability); +} + +void MultiBigramMap::BigramMap::init( + const DictionaryStructureWithBufferPolicy *const structurePolicy, const int nodePos) { + const int bigramsListPos = structurePolicy->getBigramsPositionOfPtNode(nodePos); + BinaryDictionaryBigramsIterator bigramsIt(structurePolicy->getBigramsStructurePolicy(), + bigramsListPos); + while (bigramsIt.hasNext()) { + bigramsIt.next(); + if (bigramsIt.getBigramPos() == NOT_A_DICT_POS) { + continue; + } + mBigramMap[bigramsIt.getBigramPos()] = bigramsIt.getProbability(); + mBloomFilter.setInFilter(bigramsIt.getBigramPos()); + } +} + +int MultiBigramMap::BigramMap::getBigramProbability( + const DictionaryStructureWithBufferPolicy *const structurePolicy, + const int nextWordPosition, const int unigramProbability) const { + int bigramProbability = NOT_A_PROBABILITY; + if (mBloomFilter.isInFilter(nextWordPosition)) { + const hash_map_compat<int, int>::const_iterator bigramProbabilityIt = + mBigramMap.find(nextWordPosition); + if (bigramProbabilityIt != mBigramMap.end()) { + bigramProbability = bigramProbabilityIt->second; + } + } + return structurePolicy->getProbability(unigramProbability, bigramProbability); +} + +void MultiBigramMap::addBigramsForWordPosition( + const DictionaryStructureWithBufferPolicy *const structurePolicy, const int position) { + mBigramMaps[position].init(structurePolicy, position); +} + +int MultiBigramMap::readBigramProbabilityFromBinaryDictionary( + const DictionaryStructureWithBufferPolicy *const structurePolicy, const int nodePos, + const int nextWordPosition, const int unigramProbability) { + int bigramProbability = NOT_A_PROBABILITY; + const int bigramsListPos = structurePolicy->getBigramsPositionOfPtNode(nodePos); + BinaryDictionaryBigramsIterator bigramsIt(structurePolicy->getBigramsStructurePolicy(), + bigramsListPos); + while (bigramsIt.hasNext()) { + bigramsIt.next(); + if (bigramsIt.getBigramPos() == nextWordPosition) { + bigramProbability = bigramsIt.getProbability(); + break; + } + } + return structurePolicy->getProbability(unigramProbability, bigramProbability); +} + } // namespace latinime diff --git a/native/jni/src/suggest/core/dictionary/multi_bigram_map.h b/native/jni/src/suggest/core/dictionary/multi_bigram_map.h index 4633c07b0..421b2681c 100644 --- a/native/jni/src/suggest/core/dictionary/multi_bigram_map.h +++ b/native/jni/src/suggest/core/dictionary/multi_bigram_map.h @@ -38,21 +38,7 @@ class MultiBigramMap { // Look up the bigram probability for the given word pair from the cached bigram maps. // Also caches the bigrams if there is space remaining and they have not been cached already. int getBigramProbability(const DictionaryStructureWithBufferPolicy *const structurePolicy, - const int wordPosition, const int nextWordPosition, const int unigramProbability) { - hash_map_compat<int, BigramMap>::const_iterator mapPosition = - mBigramMaps.find(wordPosition); - if (mapPosition != mBigramMaps.end()) { - return mapPosition->second.getBigramProbability(structurePolicy, nextWordPosition, - unigramProbability); - } - if (mBigramMaps.size() < MAX_CACHED_PREV_WORDS_IN_BIGRAM_MAP) { - addBigramsForWordPosition(structurePolicy, wordPosition); - return mBigramMaps[wordPosition].getBigramProbability(structurePolicy, - nextWordPosition, unigramProbability); - } - return readBigramProbabilityFromBinaryDictionary(structurePolicy, wordPosition, - nextWordPosition, unigramProbability); - } + const int wordPosition, const int nextWordPosition, const int unigramProbability); void clear() { mBigramMaps.clear(); @@ -67,33 +53,11 @@ class MultiBigramMap { ~BigramMap() {} void init(const DictionaryStructureWithBufferPolicy *const structurePolicy, - const int nodePos) { - const int bigramsListPos = structurePolicy->getBigramsPositionOfPtNode(nodePos); - BinaryDictionaryBigramsIterator bigramsIt(structurePolicy->getBigramsStructurePolicy(), - bigramsListPos); - while (bigramsIt.hasNext()) { - bigramsIt.next(); - if (bigramsIt.getBigramPos() == NOT_A_DICT_POS) { - continue; - } - mBigramMap[bigramsIt.getBigramPos()] = bigramsIt.getProbability(); - mBloomFilter.setInFilter(bigramsIt.getBigramPos()); - } - } + const int nodePos); - AK_FORCE_INLINE int getBigramProbability( + int getBigramProbability( const DictionaryStructureWithBufferPolicy *const structurePolicy, - const int nextWordPosition, const int unigramProbability) const { - int bigramProbability = NOT_A_PROBABILITY; - if (mBloomFilter.isInFilter(nextWordPosition)) { - const hash_map_compat<int, int>::const_iterator bigramProbabilityIt = - mBigramMap.find(nextWordPosition); - if (bigramProbabilityIt != mBigramMap.end()) { - bigramProbability = bigramProbabilityIt->second; - } - } - return structurePolicy->getProbability(unigramProbability, bigramProbability); - } + const int nextWordPosition, const int unigramProbability) const; private: // NOTE: The BigramMap class doesn't use DISALLOW_COPY_AND_ASSIGN() because its default @@ -103,27 +67,12 @@ class MultiBigramMap { BloomFilter mBloomFilter; }; - AK_FORCE_INLINE void addBigramsForWordPosition( - const DictionaryStructureWithBufferPolicy *const structurePolicy, const int position) { - mBigramMaps[position].init(structurePolicy, position); - } + void addBigramsForWordPosition( + const DictionaryStructureWithBufferPolicy *const structurePolicy, const int position); - AK_FORCE_INLINE int readBigramProbabilityFromBinaryDictionary( + int readBigramProbabilityFromBinaryDictionary( const DictionaryStructureWithBufferPolicy *const structurePolicy, const int nodePos, - const int nextWordPosition, const int unigramProbability) { - int bigramProbability = NOT_A_PROBABILITY; - const int bigramsListPos = structurePolicy->getBigramsPositionOfPtNode(nodePos); - BinaryDictionaryBigramsIterator bigramsIt(structurePolicy->getBigramsStructurePolicy(), - bigramsListPos); - while (bigramsIt.hasNext()) { - bigramsIt.next(); - if (bigramsIt.getBigramPos() == nextWordPosition) { - bigramProbability = bigramsIt.getProbability(); - break; - } - } - return structurePolicy->getProbability(unigramProbability, bigramProbability); - } + const int nextWordPosition, const int unigramProbability); static const size_t MAX_CACHED_PREV_WORDS_IN_BIGRAM_MAP; hash_map_compat<int, BigramMap> mBigramMaps; diff --git a/native/jni/src/suggest/policyimpl/dictionary/bigram/ver4_bigram_list_policy.cpp b/native/jni/src/suggest/policyimpl/dictionary/bigram/ver4_bigram_list_policy.cpp index 7160f6f48..48ddb2ff4 100644 --- a/native/jni/src/suggest/policyimpl/dictionary/bigram/ver4_bigram_list_policy.cpp +++ b/native/jni/src/suggest/policyimpl/dictionary/bigram/ver4_bigram_list_policy.cpp @@ -26,12 +26,18 @@ namespace latinime { void Ver4BigramListPolicy::getNextBigram(int *const outBigramPos, int *const outProbability, bool *const outHasNext, int *const bigramEntryPos) const { - int targetTerminalId = Ver4DictConstants::NOT_A_TERMINAL_ID; - mBigramDictContent->getBigramEntryAndAdvancePosition(outProbability, outHasNext, - &targetTerminalId, bigramEntryPos); + const BigramEntry bigramEntry = + mBigramDictContent->getBigramEntryAndAdvancePosition(bigramEntryPos); if (outBigramPos) { // Lookup target PtNode position. - *outBigramPos = mTerminalPositionLookupTable->getTerminalPtNodePosition(targetTerminalId); + *outBigramPos = mTerminalPositionLookupTable->getTerminalPtNodePosition( + bigramEntry.getTargetTerminalId()); + } + if (outProbability) { + *outProbability = bigramEntry.getProbability(); + } + if (outHasNext) { + *outHasNext = bigramEntry.hasNext(); } } @@ -47,12 +53,13 @@ bool Ver4BigramListPolicy::addNewEntry(const int terminalId, const int newTarget if (!mBigramDictContent->createNewBigramList(terminalId)) { return false; } - const int probabilityToWrite = getUpdatedProbability( - NOT_A_PROBABILITY /* originalProbability */, newProbability); + const BigramEntry newBigramEntry(false /* hasNext */, NOT_A_PROBABILITY, + newTargetTerminalId); + const BigramEntry bigramEntryToWrite = getUpdatedBigramEntry(&newBigramEntry, + newProbability, timestamp); // Write an entry. const int writingPos = mBigramDictContent->getBigramListHeadPos(terminalId); - if (!mBigramDictContent->writeBigramEntry(probabilityToWrite, false /* hasNext */, - newTargetTerminalId, writingPos)) { + if (!mBigramDictContent->writeBigramEntry(&bigramEntryToWrite, writingPos)) { return false; } if (outAddedNewEntry) { @@ -64,18 +71,19 @@ bool Ver4BigramListPolicy::addNewEntry(const int terminalId, const int newTarget const int entryPosToUpdate = getEntryPosToUpdate(newTargetTerminalId, bigramListPos); if (entryPosToUpdate != NOT_A_DICT_POS) { // Overwrite existing entry. - bool hasNext = false; - int probability = NOT_A_PROBABILITY; - int targetTerminalId = Ver4DictConstants::NOT_A_TERMINAL_ID; - mBigramDictContent->getBigramEntry(&probability, &hasNext, &targetTerminalId, - entryPosToUpdate); - const int probabilityToWrite = getUpdatedProbability(probability, newProbability); - if (targetTerminalId == Ver4DictConstants::NOT_A_TERMINAL_ID && outAddedNewEntry) { + const BigramEntry originalBigramEntry = + mBigramDictContent->getBigramEntry(entryPosToUpdate); + if (!originalBigramEntry.isValid()) { // Reuse invalid entry. - *outAddedNewEntry = true; + if (outAddedNewEntry) { + *outAddedNewEntry = true; + } } - return mBigramDictContent->writeBigramEntry(probabilityToWrite, hasNext, - newTargetTerminalId, entryPosToUpdate); + const BigramEntry updatedBigramEntry = + originalBigramEntry.updateTargetTerminalIdAndGetEntry(newTargetTerminalId); + const BigramEntry bigramEntryToWrite = getUpdatedBigramEntry( + &updatedBigramEntry, newProbability, timestamp); + return mBigramDictContent->writeBigramEntry(&bigramEntryToWrite, entryPosToUpdate); } // Add new entry to the bigram list. @@ -85,10 +93,10 @@ bool Ver4BigramListPolicy::addNewEntry(const int terminalId, const int newTarget } // Write new entry at a head position of the bigram list. int writingPos = mBigramDictContent->getBigramListHeadPos(terminalId); - const int probabilityToWrite = getUpdatedProbability( - NOT_A_PROBABILITY /* originalProbability */, newProbability); - if (!mBigramDictContent->writeBigramEntryAndAdvancePosition(probabilityToWrite, - true /* hasNext */, newTargetTerminalId, &writingPos)) { + const BigramEntry newBigramEntry(true /* hasNext */, NOT_A_PROBABILITY, newTargetTerminalId); + const BigramEntry bigramEntryToWrite = getUpdatedBigramEntry( + &newBigramEntry, newProbability, timestamp); + if (!mBigramDictContent->writeBigramEntryAndAdvancePosition(&bigramEntryToWrite, &writingPos)) { return false; } if (outAddedNewEntry) { @@ -109,18 +117,14 @@ bool Ver4BigramListPolicy::removeEntry(const int terminalId, const int targetTer // Bigram entry doesn't exist. return false; } - bool hasNext = false; - int probability = NOT_A_PROBABILITY; - int originalTargetTerminalId = Ver4DictConstants::NOT_A_TERMINAL_ID; - mBigramDictContent->getBigramEntry(&probability, &hasNext, &originalTargetTerminalId, - entryPosToUpdate); - if (targetTerminalId != originalTargetTerminalId) { + const BigramEntry bigramEntry = mBigramDictContent->getBigramEntry(entryPosToUpdate); + if (targetTerminalId != bigramEntry.getTargetTerminalId()) { // Bigram entry doesn't exist. return false; } - // Remove bigram entry by overwriting target terminal Id. - return mBigramDictContent->writeBigramEntry(probability, hasNext, - Ver4DictConstants::NOT_A_TERMINAL_ID /* targetTerminalId */, entryPosToUpdate); + // Remove bigram entry by marking it as invalid entry and overwriting the original entry. + const BigramEntry updatedBigramEntry = bigramEntry.getInvalidatedEntry(); + return mBigramDictContent->writeBigramEntry(&updatedBigramEntry, entryPosToUpdate); } bool Ver4BigramListPolicy::updateAllBigramEntriesAndDeleteUselessEntries(const int terminalId, @@ -134,34 +138,35 @@ bool Ver4BigramListPolicy::updateAllBigramEntriesAndDeleteUselessEntries(const i int readingPos = bigramListPos; while (hasNext) { const int entryPos = readingPos; - int probability = NOT_A_PROBABILITY; - int targetTerminalId = Ver4DictConstants::NOT_A_TERMINAL_ID; - mBigramDictContent->getBigramEntryAndAdvancePosition(&probability, &hasNext, - &targetTerminalId, &readingPos); - if (targetTerminalId == Ver4DictConstants::NOT_A_TERMINAL_ID) { + const BigramEntry bigramEntry = + mBigramDictContent->getBigramEntryAndAdvancePosition(&readingPos); + hasNext = bigramEntry.hasNext(); + if (!bigramEntry.isValid()) { continue; } const int targetPtNodePos = mTerminalPositionLookupTable->getTerminalPtNodePosition( - targetTerminalId); + bigramEntry.getTargetTerminalId()); if (targetPtNodePos == NOT_A_DICT_POS) { // Invalidate bigram entry. - if (!mBigramDictContent->writeBigramEntry(probability, hasNext, - Ver4DictConstants::NOT_A_TERMINAL_ID /* targetTerminalId */, entryPos)) { + const BigramEntry updatedBigramEntry = bigramEntry.getInvalidatedEntry(); + if (!mBigramDictContent->writeBigramEntry(&updatedBigramEntry, entryPos)) { return false; } } else if (mNeedsToDecayWhenUpdating) { - probability = ForgettingCurveUtils::getEncodedProbabilityToSave( - probability, mHeaderPolicy); + // TODO: Quit decaying probability during GC. + const int probability = ForgettingCurveUtils::getEncodedProbabilityToSave( + bigramEntry.getProbability(), mHeaderPolicy); if (ForgettingCurveUtils::isValidEncodedProbability(probability)) { - if (!mBigramDictContent->writeBigramEntry(probability, hasNext, targetTerminalId, - entryPos)) { + const BigramEntry updatedBigramEntry = + bigramEntry.updateProbabilityAndGetEntry(probability); + if (!mBigramDictContent->writeBigramEntry(&updatedBigramEntry, entryPos)) { return false; } *outBigramCount += 1; } else { // Remove entry. - if (!mBigramDictContent->writeBigramEntry(probability, hasNext, - Ver4DictConstants::NOT_A_TERMINAL_ID /* targetTerminalId */, entryPos)) { + const BigramEntry updatedBigramEntry = bigramEntry.getInvalidatedEntry(); + if (!mBigramDictContent->writeBigramEntry(&updatedBigramEntry, entryPos)) { return false; } } @@ -182,10 +187,10 @@ int Ver4BigramListPolicy::getBigramEntryConut(const int terminalId) { bool hasNext = true; int readingPos = bigramListPos; while (hasNext) { - int targetTerminalId = Ver4DictConstants::NOT_A_TERMINAL_ID; - mBigramDictContent->getBigramEntryAndAdvancePosition(0 /* probability */, &hasNext, - &targetTerminalId, &readingPos); - if (targetTerminalId != Ver4DictConstants::NOT_A_TERMINAL_ID) { + const BigramEntry bigramEntry = + mBigramDictContent->getBigramEntryAndAdvancePosition(&readingPos); + hasNext = bigramEntry.hasNext(); + if (bigramEntry.isValid()) { bigramCount++; } } @@ -199,13 +204,13 @@ int Ver4BigramListPolicy::getEntryPosToUpdate(const int targetTerminalIdToFind, int readingPos = bigramListPos; while (hasNext) { const int entryPos = readingPos; - int targetTerminalId = Ver4DictConstants::NOT_A_TERMINAL_ID; - mBigramDictContent->getBigramEntryAndAdvancePosition(0 /* probability */, &hasNext, - &targetTerminalId, &readingPos); - if (targetTerminalId == targetTerminalIdToFind) { + const BigramEntry bigramEntry = + mBigramDictContent->getBigramEntryAndAdvancePosition(&readingPos); + hasNext = bigramEntry.hasNext(); + if (bigramEntry.getTargetTerminalId() == targetTerminalIdToFind) { // Entry with same target is found. return entryPos; - } else if (targetTerminalId == Ver4DictConstants::NOT_A_TERMINAL_ID) { + } else if (!bigramEntry.isValid()) { // Invalid entry that can be reused is found. invalidEntryPos = entryPos; } @@ -213,13 +218,16 @@ int Ver4BigramListPolicy::getEntryPosToUpdate(const int targetTerminalIdToFind, return invalidEntryPos; } -int Ver4BigramListPolicy::getUpdatedProbability(const int originalProbability, - const int newProbability) const { +const BigramEntry Ver4BigramListPolicy::getUpdatedBigramEntry( + const BigramEntry *const originalBigramEntry, const int newProbability, + const int timestamp) const { if (mNeedsToDecayWhenUpdating) { - return ForgettingCurveUtils::getUpdatedEncodedProbability(originalProbability, - newProbability); + // TODO: Update historical information. + const int probability = ForgettingCurveUtils::getUpdatedEncodedProbability( + originalBigramEntry->getProbability(), newProbability); + return originalBigramEntry->updateProbabilityAndGetEntry(probability); } else { - return newProbability; + return originalBigramEntry->updateProbabilityAndGetEntry(newProbability); } } diff --git a/native/jni/src/suggest/policyimpl/dictionary/bigram/ver4_bigram_list_policy.h b/native/jni/src/suggest/policyimpl/dictionary/bigram/ver4_bigram_list_policy.h index c0959118e..e718645b4 100644 --- a/native/jni/src/suggest/policyimpl/dictionary/bigram/ver4_bigram_list_policy.h +++ b/native/jni/src/suggest/policyimpl/dictionary/bigram/ver4_bigram_list_policy.h @@ -19,6 +19,7 @@ #include "defines.h" #include "suggest/core/policy/dictionary_bigrams_structure_policy.h" +#include "suggest/policyimpl/dictionary/structure/v4/content/bigram_entry.h" namespace latinime { @@ -58,7 +59,8 @@ class Ver4BigramListPolicy : public DictionaryBigramsStructurePolicy { int getEntryPosToUpdate(const int targetTerminalIdToFind, const int bigramListPos) const; - int getUpdatedProbability(const int originalProbability, const int newProbability) const; + const BigramEntry getUpdatedBigramEntry(const BigramEntry *const originalBigramEntry, + const int newProbability, const int timestamp) const; BigramDictContent *const mBigramDictContent; const TerminalPositionLookupTable *const mTerminalPositionLookupTable; diff --git a/native/jni/src/suggest/policyimpl/dictionary/structure/v4/content/bigram_dict_content.cpp b/native/jni/src/suggest/policyimpl/dictionary/structure/v4/content/bigram_dict_content.cpp index 4cd96722e..2a783543a 100644 --- a/native/jni/src/suggest/policyimpl/dictionary/structure/v4/content/bigram_dict_content.cpp +++ b/native/jni/src/suggest/policyimpl/dictionary/structure/v4/content/bigram_dict_content.cpp @@ -20,52 +20,99 @@ namespace latinime { -void BigramDictContent::getBigramEntryAndAdvancePosition(int *const outProbability, - bool *const outHasNext, int *const outTargetTerminalId, int *const bigramEntryPos) const { +const BigramEntry BigramDictContent::getBigramEntryAndAdvancePosition( + int *const bigramEntryPos) const { const BufferWithExtendableBuffer *const bigramListBuffer = getContentBuffer(); const int bigramFlags = bigramListBuffer->readUintAndAdvancePosition( Ver4DictConstants::BIGRAM_FLAGS_FIELD_SIZE, bigramEntryPos); - if (outProbability) { - *outProbability = bigramFlags & Ver4DictConstants::BIGRAM_PROBABILITY_MASK; + const int hasNext = (bigramFlags & Ver4DictConstants::BIGRAM_HAS_NEXT_MASK) != 0; + int probability = NOT_A_PROBABILITY; + int timestamp = Ver4DictConstants::NOT_A_TIME_STAMP; + int level = 0; + int count = 0; + if (mHasHistoricalInfo) { + probability = bigramListBuffer->readUintAndAdvancePosition( + Ver4DictConstants::PROBABILITY_SIZE, bigramEntryPos); + timestamp = bigramListBuffer->readUintAndAdvancePosition( + Ver4DictConstants::TIME_STAMP_FIELD_SIZE, bigramEntryPos); + level = bigramListBuffer->readUintAndAdvancePosition( + Ver4DictConstants::WORD_LEVEL_FIELD_SIZE, bigramEntryPos); + count = bigramListBuffer->readUintAndAdvancePosition( + Ver4DictConstants::WORD_COUNT_FIELD_SIZE, bigramEntryPos); + } else { + probability = bigramFlags & Ver4DictConstants::BIGRAM_PROBABILITY_MASK; } - if (outHasNext) { - *outHasNext = (bigramFlags & Ver4DictConstants::BIGRAM_HAS_NEXT_MASK) != 0; - } - const int targetTerminalId = bigramListBuffer->readUintAndAdvancePosition( + const int encodedTargetTerminalId = bigramListBuffer->readUintAndAdvancePosition( Ver4DictConstants::BIGRAM_TARGET_TERMINAL_ID_FIELD_SIZE, bigramEntryPos); - if (outTargetTerminalId) { - *outTargetTerminalId = - (targetTerminalId == Ver4DictConstants::INVALID_BIGRAM_TARGET_TERMINAL_ID) ? - Ver4DictConstants::NOT_A_TERMINAL_ID : targetTerminalId; + const int targetTerminalId = + (encodedTargetTerminalId == Ver4DictConstants::INVALID_BIGRAM_TARGET_TERMINAL_ID) ? + Ver4DictConstants::NOT_A_TERMINAL_ID : encodedTargetTerminalId; + if (mHasHistoricalInfo) { + return BigramEntry(hasNext, probability, timestamp, level, count, targetTerminalId); + } else { + return BigramEntry(hasNext, probability, targetTerminalId); } } -bool BigramDictContent::writeBigramEntryAndAdvancePosition(const int probability, const int hasNext, - const int targetTerminalId, int *const entryWritingPos) { +bool BigramDictContent::writeBigramEntryAndAdvancePosition( + const BigramEntry *const bigramEntryToWrite, int *const entryWritingPos) { BufferWithExtendableBuffer *const bigramListBuffer = getWritableContentBuffer(); - const int bigramFlags = createAndGetBigramFlags(probability, hasNext); + const int bigramFlags = createAndGetBigramFlags( + mHasHistoricalInfo ? 0 : bigramEntryToWrite->getProbability(), + bigramEntryToWrite->hasNext()); if (!bigramListBuffer->writeUintAndAdvancePosition(bigramFlags, Ver4DictConstants::BIGRAM_FLAGS_FIELD_SIZE, entryWritingPos)) { + AKLOGE("Cannot write bigram flags. pos: %d, flags: %x", *entryWritingPos, bigramFlags); return false; } + if (mHasHistoricalInfo) { + if (!bigramListBuffer->writeUintAndAdvancePosition(bigramEntryToWrite->getProbability(), + Ver4DictConstants::PROBABILITY_SIZE, entryWritingPos)) { + AKLOGE("Cannot write bigram probability. pos: %d, probability: %d", *entryWritingPos, + bigramEntryToWrite->getProbability()); + return false; + } + if (!bigramListBuffer->writeUintAndAdvancePosition(bigramEntryToWrite->getTimeStamp(), + Ver4DictConstants::TIME_STAMP_FIELD_SIZE, entryWritingPos)) { + AKLOGE("Cannot write bigram timestamps. pos: %d, timestamp: %d", *entryWritingPos, + bigramEntryToWrite->getTimeStamp()); + return false; + } + if (!bigramListBuffer->writeUintAndAdvancePosition(bigramEntryToWrite->getLevel(), + Ver4DictConstants::WORD_LEVEL_FIELD_SIZE, entryWritingPos)) { + AKLOGE("Cannot write bigram level. pos: %d, level: %d", *entryWritingPos, + bigramEntryToWrite->getLevel()); + return false; + } + if (!bigramListBuffer->writeUintAndAdvancePosition(bigramEntryToWrite->getCount(), + Ver4DictConstants::WORD_COUNT_FIELD_SIZE, entryWritingPos)) { + AKLOGE("Cannot write bigram count. pos: %d, count: %d", *entryWritingPos, + bigramEntryToWrite->getCount()); + return false; + } + } const int targetTerminalIdToWrite = - (targetTerminalId == Ver4DictConstants::NOT_A_TERMINAL_ID) ? - Ver4DictConstants::INVALID_BIGRAM_TARGET_TERMINAL_ID : targetTerminalId; - return bigramListBuffer->writeUintAndAdvancePosition(targetTerminalIdToWrite, - Ver4DictConstants::BIGRAM_TARGET_TERMINAL_ID_FIELD_SIZE, entryWritingPos); + (bigramEntryToWrite->getTargetTerminalId() == Ver4DictConstants::NOT_A_TERMINAL_ID) ? + Ver4DictConstants::INVALID_BIGRAM_TARGET_TERMINAL_ID : + bigramEntryToWrite->getTargetTerminalId(); + if (!bigramListBuffer->writeUintAndAdvancePosition(targetTerminalIdToWrite, + Ver4DictConstants::BIGRAM_TARGET_TERMINAL_ID_FIELD_SIZE, entryWritingPos)) { + AKLOGE("Cannot write bigram target terminal id. pos: %d, target terminal id: %d", + *entryWritingPos, bigramEntryToWrite->getTargetTerminalId()); + return false; + } + return true; } bool BigramDictContent::copyBigramList(const int bigramListPos, const int toPos) { - bool hasNext = true; int readingPos = bigramListPos; int writingPos = toPos; + bool hasNext = true; while (hasNext) { - int probability = NOT_A_PROBABILITY; - int targetTerminalId = Ver4DictConstants::NOT_A_TERMINAL_ID; - getBigramEntryAndAdvancePosition(&probability, &hasNext, &targetTerminalId, - &readingPos); - if (!writeBigramEntryAndAdvancePosition(probability, hasNext, targetTerminalId, - &writingPos)) { + const BigramEntry bigramEntry = getBigramEntryAndAdvancePosition(&readingPos); + hasNext = bigramEntry.hasNext(); + if (!writeBigramEntryAndAdvancePosition(&bigramEntry, &writingPos)) { + AKLOGE("Cannot write bigram entry to copy. pos: %d", writingPos); return false; } } @@ -88,6 +135,8 @@ bool BigramDictContent::runGC(const TerminalPositionLookupTable::TerminalIdMap * // Copy bigram list with GC from original content. if (!runGCBigramList(originalBigramListPos, originalBigramDictContent, bigramListPos, terminalIdMap, &bigramEntryCount)) { + AKLOGE("Cannot complete GC for the bigram list. original pos: %d, pos: %d", + originalBigramListPos, bigramListPos); return false; } if (bigramEntryCount == 0) { @@ -97,6 +146,8 @@ bool BigramDictContent::runGC(const TerminalPositionLookupTable::TerminalIdMap * *outBigramEntryCount += bigramEntryCount; // Set bigram list position to the lookup table. if (!getUpdatableAddressLookupTable()->set(it->second, bigramListPos)) { + AKLOGE("Cannot set bigram list position. terminal id: %d, pos: %d", + it->second, bigramListPos); return false; } } @@ -111,26 +162,38 @@ bool BigramDictContent::runGCBigramList(const int bigramListPos, bool hasNext = true; int readingPos = bigramListPos; int writingPos = toPos; + int lastEntryPos = NOT_A_DICT_POS; while (hasNext) { - int probability = NOT_A_PROBABILITY; - int targetTerminalId = Ver4DictConstants::NOT_A_TERMINAL_ID; - sourceBigramDictContent->getBigramEntryAndAdvancePosition(&probability, &hasNext, - &targetTerminalId, &readingPos); - if (targetTerminalId == Ver4DictConstants::NOT_A_TERMINAL_ID) { + const BigramEntry originalBigramEntry = + sourceBigramDictContent->getBigramEntryAndAdvancePosition(&readingPos); + hasNext = originalBigramEntry.hasNext(); + if (originalBigramEntry.getTargetTerminalId() == Ver4DictConstants::NOT_A_TERMINAL_ID) { continue; } TerminalPositionLookupTable::TerminalIdMap::const_iterator it = - terminalIdMap->find(targetTerminalId); + terminalIdMap->find(originalBigramEntry.getTargetTerminalId()); if (it == terminalIdMap->end()) { // Target word has been removed. continue; } - if (!writeBigramEntryAndAdvancePosition(probability, hasNext, it->second, - &writingPos)) { + lastEntryPos = hasNext ? writingPos : NOT_A_DICT_POS; + const BigramEntry updatedBigramEntry = + originalBigramEntry.updateTargetTerminalIdAndGetEntry(it->second); + if (!writeBigramEntryAndAdvancePosition(&updatedBigramEntry, &writingPos)) { + AKLOGE("Cannot write bigram entry to run GC. pos: %d", writingPos); return false; } *outEntrycount += 1; } + if (lastEntryPos != NOT_A_DICT_POS) { + // Update has next flag in the last written entry. + const BigramEntry bigramEntry = getBigramEntry(lastEntryPos).updateHasNextAndGetEntry( + false /* hasNext */); + if (!writeBigramEntry(&bigramEntry, writingPos)) { + AKLOGE("Cannot write bigram entry to set hasNext flag after GC. pos: %d", writingPos); + return false; + } + } return true; } diff --git a/native/jni/src/suggest/policyimpl/dictionary/structure/v4/content/bigram_dict_content.h b/native/jni/src/suggest/policyimpl/dictionary/structure/v4/content/bigram_dict_content.h index cf380f403..ac05b215b 100644 --- a/native/jni/src/suggest/policyimpl/dictionary/structure/v4/content/bigram_dict_content.h +++ b/native/jni/src/suggest/policyimpl/dictionary/structure/v4/content/bigram_dict_content.h @@ -18,6 +18,7 @@ #define LATINIME_BIGRAM_DICT_CONTENT_H #include "defines.h" +#include "suggest/policyimpl/dictionary/structure/v4/content/bigram_entry.h" #include "suggest/policyimpl/dictionary/structure/v4/content/sparse_table_dict_content.h" #include "suggest/policyimpl/dictionary/structure/v4/content/terminal_position_lookup_table.h" #include "suggest/policyimpl/dictionary/structure/v4/ver4_dict_constants.h" @@ -26,27 +27,27 @@ namespace latinime { class BigramDictContent : public SparseTableDictContent { public: - BigramDictContent(const char *const dictDirPath, const bool isUpdatable) + BigramDictContent(const char *const dictDirPath, const bool hasHistoricalInfo, + const bool isUpdatable) : SparseTableDictContent(dictDirPath, Ver4DictConstants::BIGRAM_LOOKUP_TABLE_FILE_EXTENSION, Ver4DictConstants::BIGRAM_CONTENT_TABLE_FILE_EXTENSION, Ver4DictConstants::BIGRAM_FILE_EXTENSION, isUpdatable, Ver4DictConstants::BIGRAM_ADDRESS_TABLE_BLOCK_SIZE, - Ver4DictConstants::BIGRAM_ADDRESS_TABLE_DATA_SIZE) {} + Ver4DictConstants::BIGRAM_ADDRESS_TABLE_DATA_SIZE), + mHasHistoricalInfo(hasHistoricalInfo) {} - BigramDictContent() + BigramDictContent(const bool hasHistoricalInfo) : SparseTableDictContent(Ver4DictConstants::BIGRAM_ADDRESS_TABLE_BLOCK_SIZE, - Ver4DictConstants::BIGRAM_ADDRESS_TABLE_DATA_SIZE) {} + Ver4DictConstants::BIGRAM_ADDRESS_TABLE_DATA_SIZE), + mHasHistoricalInfo(hasHistoricalInfo) {} - void getBigramEntry(int *const outProbability, bool *const outHasNext, - int *const outTargetTerminalId, const int bigramEntryPos) const { + const BigramEntry getBigramEntry(const int bigramEntryPos) const { int readingPos = bigramEntryPos; - getBigramEntryAndAdvancePosition(outProbability, outHasNext, outTargetTerminalId, - &readingPos); + return getBigramEntryAndAdvancePosition(&readingPos); } - void getBigramEntryAndAdvancePosition(int *const outProbability, bool *const outHasNext, - int *const outTargetTerminalId, int *const bigramEntryPos) const; + const BigramEntry getBigramEntryAndAdvancePosition(int *const bigramEntryPos) const; // Returns head position of bigram list for a PtNode specified by terminalId. int getBigramListHeadPos(const int terminalId) const { @@ -57,15 +58,13 @@ class BigramDictContent : public SparseTableDictContent { return addressLookupTable->get(terminalId); } - bool writeBigramEntry(const int probability, const int hasNext, const int targetTerminalId, - const int entryWritingPos) { + bool writeBigramEntry(const BigramEntry *const bigramEntryToWrite, const int entryWritingPos) { int writingPos = entryWritingPos; - return writeBigramEntryAndAdvancePosition(probability, hasNext, targetTerminalId, - &writingPos); + return writeBigramEntryAndAdvancePosition(bigramEntryToWrite, &writingPos); } - bool writeBigramEntryAndAdvancePosition(const int probability, const int hasNext, - const int targetTerminalId, int *const entryWritingPos); + bool writeBigramEntryAndAdvancePosition(const BigramEntry *const bigramEntryToWrite, + int *const entryWritingPos); bool createNewBigramList(const int terminalId) { const int bigramListPos = getContentBuffer()->getTailPosition(); @@ -96,6 +95,8 @@ class BigramDictContent : public SparseTableDictContent { const BigramDictContent *const sourceBigramDictContent, const int toPos, const TerminalPositionLookupTable::TerminalIdMap *const terminalIdMap, int *const outEntryCount); + + bool mHasHistoricalInfo; }; } // namespace latinime #endif /* LATINIME_BIGRAM_DICT_CONTENT_H */ diff --git a/native/jni/src/suggest/policyimpl/dictionary/structure/v4/content/bigram_entry.h b/native/jni/src/suggest/policyimpl/dictionary/structure/v4/content/bigram_entry.h new file mode 100644 index 000000000..10b3ec8dc --- /dev/null +++ b/native/jni/src/suggest/policyimpl/dictionary/structure/v4/content/bigram_entry.h @@ -0,0 +1,104 @@ +/* + * 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_BIGRAM_ENTRY_H +#define LATINIME_BIGRAM_ENTRY_H + +#include "defines.h" +#include "suggest/policyimpl/dictionary/structure/v4/ver4_dict_constants.h" + +namespace latinime { + +class BigramEntry { + public: + BigramEntry(const BigramEntry& bigramEntry) + : mHasNext(bigramEntry.mHasNext), mProbability(bigramEntry.mProbability), + mTimestamp(bigramEntry.mTimestamp), mLevel(bigramEntry.mLevel), + mCount(bigramEntry.mCount), mTargetTerminalId(bigramEntry.mTargetTerminalId) {} + + // Entry with historical information. + BigramEntry(const bool hasNext, const int probability, const int targetTerminalId) + : mHasNext(hasNext), mProbability(probability), + mTimestamp(Ver4DictConstants::NOT_A_TIME_STAMP), mLevel(0), mCount(0), + mTargetTerminalId(targetTerminalId) {} + + // Entry with historical information. + BigramEntry(const bool hasNext, const int probability, const int timestamp, const int level, + const int count, const int targetTerminalId) + : mHasNext(hasNext), mProbability(probability), mTimestamp(timestamp), + mLevel(level), mCount(count), mTargetTerminalId(targetTerminalId) {} + + const BigramEntry getInvalidatedEntry() const { + return updateTargetTerminalIdAndGetEntry(Ver4DictConstants::NOT_A_TERMINAL_ID); + } + + const BigramEntry updateHasNextAndGetEntry(const bool hasNext) const { + return BigramEntry(hasNext, mProbability, mTimestamp, mLevel, mCount, + mTargetTerminalId); + } + + const BigramEntry updateTargetTerminalIdAndGetEntry(const int newTargetTerminalId) const { + return BigramEntry(mHasNext, mProbability, mTimestamp, mLevel, mCount, + newTargetTerminalId); + } + + const BigramEntry updateProbabilityAndGetEntry(const int probability) const { + return BigramEntry(mHasNext, probability, mTimestamp, mLevel, mCount, + mTargetTerminalId); + } + + bool isValid() const { + return mTargetTerminalId != Ver4DictConstants::NOT_A_TERMINAL_ID; + } + + bool hasNext() const { + return mHasNext; + } + + int getProbability() const { + return mProbability; + } + + int getTimeStamp() const { + return mTimestamp; + } + + int getLevel() const { + return mLevel; + } + + int getCount() const { + return mCount; + } + + int getTargetTerminalId() const { + return mTargetTerminalId; + } + + private: + // Copy constructor is public to use this class as a type of return value. + DISALLOW_DEFAULT_CONSTRUCTOR(BigramEntry); + DISALLOW_ASSIGNMENT_OPERATOR(BigramEntry); + + const bool mHasNext; + const int mProbability; + const int mTimestamp; + const int mLevel; + const int mCount; + const int mTargetTerminalId; +}; +} // namespace latinime +#endif /* LATINIME_BIGRAM_ENTRY_H */ diff --git a/native/jni/src/suggest/policyimpl/dictionary/structure/v4/ver4_dict_buffers.h b/native/jni/src/suggest/policyimpl/dictionary/structure/v4/ver4_dict_buffers.h index 8fdbbedfe..07b8f181d 100644 --- a/native/jni/src/suggest/policyimpl/dictionary/structure/v4/ver4_dict_buffers.h +++ b/native/jni/src/suggest/policyimpl/dictionary/structure/v4/ver4_dict_buffers.h @@ -127,7 +127,7 @@ class Ver4DictBuffers { // TODO: Quit using header size. mTerminalPositionLookupTable(dictDirPath, isUpdatable, mHeaderSize), mProbabilityDictContent(dictDirPath, false /* hasHistoricalInfo */, isUpdatable), - mBigramDictContent(dictDirPath, isUpdatable), + mBigramDictContent(dictDirPath, false /* hasHistoricalInfo */, isUpdatable), mShortcutDictContent(dictDirPath, isUpdatable), mIsUpdatable(isUpdatable) {} @@ -137,7 +137,8 @@ class Ver4DictBuffers { mExpandableTrieBuffer(Ver4DictConstants::MAX_DICTIONARY_SIZE), mTerminalPositionLookupTable(), mProbabilityDictContent(false /* hasHistoricalInfo */), - mBigramDictContent(), mShortcutDictContent(), mIsUpdatable(true) {} + mBigramDictContent(false /* hasHistoricalInfo */), mShortcutDictContent(), + mIsUpdatable(true) {} const MmappedBuffer::MmappedBufferPtr mDictBuffer; const int mHeaderSize; diff --git a/native/jni/src/utils/exclusive_ownership_pointer.h b/native/jni/src/utils/exclusive_ownership_pointer.h index 3cf78954a..6c67df28e 100644 --- a/native/jni/src/utils/exclusive_ownership_pointer.h +++ b/native/jni/src/utils/exclusive_ownership_pointer.h @@ -56,8 +56,7 @@ class ExclusiveOwnershipPointer { private: // This class allows to copy and assign and ensures only one instance has the ownership of the // managed pointer. - - ExclusiveOwnershipPointer() : mPointer(0), mSharedOwnerPtr(0) {} + DISALLOW_DEFAULT_CONSTRUCTOR(ExclusiveOwnershipPointer); void transferOwnership(const ExclusiveOwnershipPointer<T> *const src) { if (*mSharedOwnerPtr != src) { diff --git a/tests/src/com/android/inputmethod/latin/makedict/BinaryDictDecoderEncoderTests.java b/tests/src/com/android/inputmethod/latin/makedict/BinaryDictDecoderEncoderTests.java index c4749df82..05de37d4c 100644 --- a/tests/src/com/android/inputmethod/latin/makedict/BinaryDictDecoderEncoderTests.java +++ b/tests/src/com/android/inputmethod/latin/makedict/BinaryDictDecoderEncoderTests.java @@ -265,7 +265,7 @@ public class BinaryDictDecoderEncoderTests extends AndroidTestCase { getContext().getCacheDir()); final FusionDictionary dict = new FusionDictionary(new PtNodeArray(), - BinaryDictUtils.getDictionaryOptions(dictName, dictVersion)); + BinaryDictUtils.makeDictionaryOptions(dictName, dictVersion)); addUnigrams(words.size(), dict, words, shortcuts); addBigrams(dict, words, bigrams); checkDictionary(dict, words, bigrams, shortcuts); @@ -444,7 +444,7 @@ public class BinaryDictDecoderEncoderTests extends AndroidTestCase { // making the dictionary from lists of words. final FusionDictionary dict = new FusionDictionary(new PtNodeArray(), - BinaryDictUtils.getDictionaryOptions(dictName, dictVersion)); + BinaryDictUtils.makeDictionaryOptions(dictName, dictVersion)); addUnigrams(words.size(), dict, words, null /* shortcutMap */); addBigrams(dict, words, bigrams); @@ -555,7 +555,7 @@ public class BinaryDictDecoderEncoderTests extends AndroidTestCase { getContext().getCacheDir()); final FusionDictionary dict = new FusionDictionary(new PtNodeArray(), - BinaryDictUtils.getDictionaryOptions(dictName, dictVersion)); + BinaryDictUtils.makeDictionaryOptions(dictName, dictVersion)); addUnigrams(sWords.size(), dict, sWords, null /* shortcutMap */); addBigrams(dict, words, bigrams); timeWritingDictToFile(file, dict, formatOptions); @@ -649,8 +649,7 @@ public class BinaryDictDecoderEncoderTests extends AndroidTestCase { getContext().getCacheDir()); final FusionDictionary dict = new FusionDictionary(new PtNodeArray(), - new FusionDictionary.DictionaryOptions( - new HashMap<String, String>(), false, false)); + BinaryDictUtils.makeDictionaryOptions(dictName, dictVersion)); addUnigrams(sWords.size(), dict, sWords, null /* shortcutMap */); timeWritingDictToFile(file, dict, formatOptions); diff --git a/tests/src/com/android/inputmethod/latin/makedict/BinaryDictIOUtilsTests.java b/tests/src/com/android/inputmethod/latin/makedict/BinaryDictIOUtilsTests.java index 8bea3c074..da217cea6 100644 --- a/tests/src/com/android/inputmethod/latin/makedict/BinaryDictIOUtilsTests.java +++ b/tests/src/com/android/inputmethod/latin/makedict/BinaryDictIOUtilsTests.java @@ -233,7 +233,7 @@ public class BinaryDictIOUtilsTests extends AndroidTestCase { // set an initial dictionary. final FusionDictionary dict = new FusionDictionary(new PtNodeArray(), - BinaryDictUtils.getDictionaryOptions(testName, version)); + BinaryDictUtils.makeDictionaryOptions(testName, version)); dict.add("abcd", 10, null, false); try { @@ -301,7 +301,7 @@ public class BinaryDictIOUtilsTests extends AndroidTestCase { // set an initial dictionary. final FusionDictionary dict = new FusionDictionary(new PtNodeArray(), - BinaryDictUtils.getDictionaryOptions(testName, version)); + BinaryDictUtils.makeDictionaryOptions(testName, version)); dict.add("abcd", 10, null, false); dict.add("efgh", 15, null, false); @@ -341,7 +341,7 @@ public class BinaryDictIOUtilsTests extends AndroidTestCase { // set an initial dictionary. final FusionDictionary dict = new FusionDictionary(new PtNodeArray(), - BinaryDictUtils.getDictionaryOptions(testName, version)); + BinaryDictUtils.makeDictionaryOptions(testName, version)); dict.add("initial", 10, null, false); try { diff --git a/tests/src/com/android/inputmethod/latin/makedict/BinaryDictUtils.java b/tests/src/com/android/inputmethod/latin/makedict/BinaryDictUtils.java index 5ec37255d..8b1521a6c 100644 --- a/tests/src/com/android/inputmethod/latin/makedict/BinaryDictUtils.java +++ b/tests/src/com/android/inputmethod/latin/makedict/BinaryDictUtils.java @@ -16,6 +16,7 @@ package com.android.inputmethod.latin.makedict; +import com.android.inputmethod.latin.makedict.FormatSpec.FileHeader; import com.android.inputmethod.latin.makedict.FormatSpec.FormatOptions; import com.android.inputmethod.latin.makedict.FusionDictionary.DictionaryOptions; @@ -41,11 +42,12 @@ public class BinaryDictUtils { new FormatSpec.FormatOptions(4, true /* supportsDynamicUpdate */, true /* hasTimestamp */); - public static DictionaryOptions getDictionaryOptions(final String id, final String version) { + public static DictionaryOptions makeDictionaryOptions(final String id, final String version) { final DictionaryOptions options = new DictionaryOptions(new HashMap<String, String>(), false /* germanUmlautProcessing */, false /* frenchLigatureProcessing */); - options.mAttributes.put("dictionary", id); - options.mAttributes.put("version", version); + options.mAttributes.put(FileHeader.DICTIONARY_LOCALE_ATTRIBUTE, "en_US"); + options.mAttributes.put(FileHeader.DICTIONARY_ID_ATTRIBUTE, id); + options.mAttributes.put(FileHeader.DICTIONARY_VERSION_ATTRIBUTE, version); return options; } diff --git a/tests/src/com/android/inputmethod/latin/personalization/UserHistoryDictionaryTests.java b/tests/src/com/android/inputmethod/latin/personalization/UserHistoryDictionaryTests.java index c3e062b65..9c93b8b25 100644 --- a/tests/src/com/android/inputmethod/latin/personalization/UserHistoryDictionaryTests.java +++ b/tests/src/com/android/inputmethod/latin/personalization/UserHistoryDictionaryTests.java @@ -16,8 +16,6 @@ package com.android.inputmethod.latin.personalization; -import android.content.SharedPreferences; -import android.preference.PreferenceManager; import android.test.AndroidTestCase; import android.test.suitebuilder.annotation.LargeTest; import android.util.Log; @@ -38,7 +36,6 @@ import java.util.concurrent.TimeUnit; @LargeTest public class UserHistoryDictionaryTests extends AndroidTestCase { private static final String TAG = UserHistoryDictionaryTests.class.getSimpleName(); - private SharedPreferences mPrefs; private static final String[] CHARACTERS = { "a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", @@ -48,11 +45,6 @@ public class UserHistoryDictionaryTests extends AndroidTestCase { private static final int MIN_USER_HISTORY_DICTIONARY_FILE_SIZE = 1000; private static final int WAIT_TERMINATING_IN_MILLISECONDS = 100; - @Override - public void setUp() { - mPrefs = PreferenceManager.getDefaultSharedPreferences(getContext()); - } - /** * Generates a random word. */ @@ -92,7 +84,7 @@ public class UserHistoryDictionaryTests extends AndroidTestCase { final List<String> words = generateWords(numberOfWords, random); final UserHistoryDictionary dict = PersonalizationHelper.getUserHistoryDictionary(getContext(), - testFilenameSuffix /* locale */, mPrefs); + testFilenameSuffix /* locale */); // Add random words to the user history dictionary. addToDict(dict, words); if (checkContents) { @@ -116,7 +108,7 @@ public class UserHistoryDictionaryTests extends AndroidTestCase { private void clearHistory(final String testFilenameSuffix) { final UserHistoryDictionary dict = PersonalizationHelper.getUserHistoryDictionary(getContext(), - testFilenameSuffix /* locale */, mPrefs); + testFilenameSuffix /* locale */); dict.clearAndFlushDictionary(); dict.close(); } @@ -129,7 +121,7 @@ public class UserHistoryDictionaryTests extends AndroidTestCase { try { final UserHistoryDictionary dict = PersonalizationHelper.getUserHistoryDictionary(getContext(), - testFilenameSuffix, mPrefs); + testFilenameSuffix); dict.shutdownExecutorForTests(); while (!dict.isTerminatedForTests()) { Thread.sleep(WAIT_TERMINATING_IN_MILLISECONDS); |