1fd02b2d6ee55d4aee7faab89a7a2b72764eafc47Keisuke Kuroyanagi/*
2fd02b2d6ee55d4aee7faab89a7a2b72764eafc47Keisuke Kuroyanagi * Copyright (C) 2013 The Android Open Source Project
3fd02b2d6ee55d4aee7faab89a7a2b72764eafc47Keisuke Kuroyanagi *
4fd02b2d6ee55d4aee7faab89a7a2b72764eafc47Keisuke Kuroyanagi * Licensed under the Apache License, Version 2.0 (the "License");
5fd02b2d6ee55d4aee7faab89a7a2b72764eafc47Keisuke Kuroyanagi * you may not use this file except in compliance with the License.
6fd02b2d6ee55d4aee7faab89a7a2b72764eafc47Keisuke Kuroyanagi * You may obtain a copy of the License at
7fd02b2d6ee55d4aee7faab89a7a2b72764eafc47Keisuke Kuroyanagi *
8fd02b2d6ee55d4aee7faab89a7a2b72764eafc47Keisuke Kuroyanagi *      http://www.apache.org/licenses/LICENSE-2.0
9fd02b2d6ee55d4aee7faab89a7a2b72764eafc47Keisuke Kuroyanagi *
10fd02b2d6ee55d4aee7faab89a7a2b72764eafc47Keisuke Kuroyanagi * Unless required by applicable law or agreed to in writing, software
11fd02b2d6ee55d4aee7faab89a7a2b72764eafc47Keisuke Kuroyanagi * distributed under the License is distributed on an "AS IS" BASIS,
12fd02b2d6ee55d4aee7faab89a7a2b72764eafc47Keisuke Kuroyanagi * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13fd02b2d6ee55d4aee7faab89a7a2b72764eafc47Keisuke Kuroyanagi * See the License for the specific language governing permissions and
14fd02b2d6ee55d4aee7faab89a7a2b72764eafc47Keisuke Kuroyanagi * limitations under the License.
15fd02b2d6ee55d4aee7faab89a7a2b72764eafc47Keisuke Kuroyanagi */
16fd02b2d6ee55d4aee7faab89a7a2b72764eafc47Keisuke Kuroyanagi
17fd02b2d6ee55d4aee7faab89a7a2b72764eafc47Keisuke Kuroyanagipackage com.android.inputmethod.latin;
18fd02b2d6ee55d4aee7faab89a7a2b72764eafc47Keisuke Kuroyanagi
19fd02b2d6ee55d4aee7faab89a7a2b72764eafc47Keisuke Kuroyanagiimport android.test.AndroidTestCase;
20fd02b2d6ee55d4aee7faab89a7a2b72764eafc47Keisuke Kuroyanagiimport android.test.suitebuilder.annotation.LargeTest;
21a2821fde60891f7a44441a3673abfa9c65e7fa66Keisuke Kuroyanagiimport android.util.Pair;
22fd02b2d6ee55d4aee7faab89a7a2b72764eafc47Keisuke Kuroyanagi
23e708b1bc2e11285ad404133b8de21719ce08acb5Keisuke Kuroyanagiimport com.android.inputmethod.latin.PrevWordsInfo.WordInfo;
2493cda5bb396c22f1781e390debaf75d54cf7c0dcKeisuke Kuroyanagiimport com.android.inputmethod.latin.makedict.BinaryDictIOUtils;
25cfb018ba6db78f2b33b54d4811f0bf166db29792Keisuke Kuroyanagiimport com.android.inputmethod.latin.makedict.CodePointUtils;
2626bd46095a05843e7574dfcf7db53406f215525dKeisuke Kuroyanagiimport com.android.inputmethod.latin.makedict.DictDecoder;
27b986f78ba826fa360304a69565f1880bdd7ce0c5Keisuke Kuroyanagiimport com.android.inputmethod.latin.makedict.DictionaryHeader;
28fd02b2d6ee55d4aee7faab89a7a2b72764eafc47Keisuke Kuroyanagiimport com.android.inputmethod.latin.makedict.FormatSpec;
2926bd46095a05843e7574dfcf7db53406f215525dKeisuke Kuroyanagiimport com.android.inputmethod.latin.makedict.FusionDictionary;
3026bd46095a05843e7574dfcf7db53406f215525dKeisuke Kuroyanagiimport com.android.inputmethod.latin.makedict.FusionDictionary.PtNode;
3126bd46095a05843e7574dfcf7db53406f215525dKeisuke Kuroyanagiimport com.android.inputmethod.latin.makedict.UnsupportedFormatException;
32e784148ae6872942434eaa55ca32b4c6442cc8e8Keisuke Kuroyanagiimport com.android.inputmethod.latin.utils.BinaryDictionaryUtils;
332fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasaimport com.android.inputmethod.latin.utils.FileUtils;
3443cf9076b2d053c554941e55f6073b8f586c510bJean Chalardimport com.android.inputmethod.latin.utils.LocaleUtils;
35fd02b2d6ee55d4aee7faab89a7a2b72764eafc47Keisuke Kuroyanagi
36fd02b2d6ee55d4aee7faab89a7a2b72764eafc47Keisuke Kuroyanagiimport java.io.File;
37fd02b2d6ee55d4aee7faab89a7a2b72764eafc47Keisuke Kuroyanagiimport java.io.IOException;
38cfb018ba6db78f2b33b54d4811f0bf166db29792Keisuke Kuroyanagiimport java.util.ArrayList;
39fd02b2d6ee55d4aee7faab89a7a2b72764eafc47Keisuke Kuroyanagiimport java.util.HashMap;
40fd02b2d6ee55d4aee7faab89a7a2b72764eafc47Keisuke Kuroyanagiimport java.util.Locale;
41fd02b2d6ee55d4aee7faab89a7a2b72764eafc47Keisuke Kuroyanagiimport java.util.Map;
42cfb018ba6db78f2b33b54d4811f0bf166db29792Keisuke Kuroyanagiimport java.util.Random;
432fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasaimport java.util.concurrent.TimeUnit;
44fd02b2d6ee55d4aee7faab89a7a2b72764eafc47Keisuke Kuroyanagi
45fd02b2d6ee55d4aee7faab89a7a2b72764eafc47Keisuke Kuroyanagi@LargeTest
46fd02b2d6ee55d4aee7faab89a7a2b72764eafc47Keisuke Kuroyanagipublic class BinaryDictionaryDecayingTests extends AndroidTestCase {
47fd02b2d6ee55d4aee7faab89a7a2b72764eafc47Keisuke Kuroyanagi    private static final String TEST_DICT_FILE_EXTENSION = ".testDict";
48fd02b2d6ee55d4aee7faab89a7a2b72764eafc47Keisuke Kuroyanagi    private static final String TEST_LOCALE = "test";
49fd02b2d6ee55d4aee7faab89a7a2b72764eafc47Keisuke Kuroyanagi    private static final int DUMMY_PROBABILITY = 0;
5004536f14b02566ead3a95fc7d80d47e8d99936edKeisuke Kuroyanagi    private static final int[] DICT_FORMAT_VERSIONS =
5104536f14b02566ead3a95fc7d80d47e8d99936edKeisuke Kuroyanagi            new int[] { FormatSpec.VERSION4, FormatSpec.VERSION4_DEV };
52fd02b2d6ee55d4aee7faab89a7a2b72764eafc47Keisuke Kuroyanagi
532fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa    private int mCurrentTime = 0;
542fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa
55fd02b2d6ee55d4aee7faab89a7a2b72764eafc47Keisuke Kuroyanagi    @Override
56fd02b2d6ee55d4aee7faab89a7a2b72764eafc47Keisuke Kuroyanagi    protected void setUp() throws Exception {
57fd02b2d6ee55d4aee7faab89a7a2b72764eafc47Keisuke Kuroyanagi        super.setUp();
582fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa        mCurrentTime = 0;
59fd02b2d6ee55d4aee7faab89a7a2b72764eafc47Keisuke Kuroyanagi    }
60fd02b2d6ee55d4aee7faab89a7a2b72764eafc47Keisuke Kuroyanagi
61fd02b2d6ee55d4aee7faab89a7a2b72764eafc47Keisuke Kuroyanagi    @Override
62fd02b2d6ee55d4aee7faab89a7a2b72764eafc47Keisuke Kuroyanagi    protected void tearDown() throws Exception {
63d78a447d107ae60d2bb8f16a1b9797f5ebad2277Keisuke Kuroyanagi        stopTestModeInNativeCode();
64da973e75dcea8dac8c83d7dcc4a7a33a69bab2cdTadashi G. Takaoka        super.tearDown();
652fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa    }
662fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa
671adca93381d261a6070be2721dbf8b8abafbfe01Keisuke Kuroyanagi    private static boolean supportsBeginningOfSentence(final int formatVersion) {
68a37f374ad140f14e5e8ecaef9e1dbee3b1d7b84cKeisuke Kuroyanagi        return formatVersion > FormatSpec.VERSION401;
691adca93381d261a6070be2721dbf8b8abafbfe01Keisuke Kuroyanagi    }
701adca93381d261a6070be2721dbf8b8abafbfe01Keisuke Kuroyanagi
712fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa    private void addUnigramWord(final BinaryDictionary binaryDictionary, final String word,
722fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa            final int probability) {
73e507d92aa3ee4ae43124c5452f20aa8ed0ecef4cKeisuke Kuroyanagi        binaryDictionary.addUnigramEntry(word, probability, "" /* shortcutTarget */,
742fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa                BinaryDictionary.NOT_A_PROBABILITY /* shortcutProbability */,
751adca93381d261a6070be2721dbf8b8abafbfe01Keisuke Kuroyanagi                false /* isBeginningOfSentence */, false /* isNotAWord */,
761adca93381d261a6070be2721dbf8b8abafbfe01Keisuke Kuroyanagi                false /* isBlacklisted */, mCurrentTime /* timestamp */);
772fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa    }
782fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa
792fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa    private void addBigramWords(final BinaryDictionary binaryDictionary, final String word0,
802fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa            final String word1, final int probability) {
81e708b1bc2e11285ad404133b8de21719ce08acb5Keisuke Kuroyanagi        binaryDictionary.addNgramEntry(new PrevWordsInfo(new WordInfo(word0)), word1, probability,
822fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa                mCurrentTime /* timestamp */);
83fd02b2d6ee55d4aee7faab89a7a2b72764eafc47Keisuke Kuroyanagi    }
84fd02b2d6ee55d4aee7faab89a7a2b72764eafc47Keisuke Kuroyanagi
85e507d92aa3ee4ae43124c5452f20aa8ed0ecef4cKeisuke Kuroyanagi    private static boolean isValidBigram(final BinaryDictionary binaryDictionary,
86e507d92aa3ee4ae43124c5452f20aa8ed0ecef4cKeisuke Kuroyanagi            final String word0, final String word1) {
87e708b1bc2e11285ad404133b8de21719ce08acb5Keisuke Kuroyanagi        return binaryDictionary.isValidNgram(new PrevWordsInfo(new WordInfo(word0)), word1);
88e507d92aa3ee4ae43124c5452f20aa8ed0ecef4cKeisuke Kuroyanagi    }
89e507d92aa3ee4ae43124c5452f20aa8ed0ecef4cKeisuke Kuroyanagi
90fd02b2d6ee55d4aee7faab89a7a2b72764eafc47Keisuke Kuroyanagi    private void forcePassingShortTime(final BinaryDictionary binaryDictionary) {
9173a2426d455e6e83dd9402913889f80a0071f0acKeisuke Kuroyanagi        // 30 days.
9273a2426d455e6e83dd9402913889f80a0071f0acKeisuke Kuroyanagi        final int timeToElapse = (int)TimeUnit.SECONDS.convert(30, TimeUnit.DAYS);
932fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa        mCurrentTime += timeToElapse;
94d78a447d107ae60d2bb8f16a1b9797f5ebad2277Keisuke Kuroyanagi        setCurrentTimeForTestMode(mCurrentTime);
952fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa        binaryDictionary.flushWithGC();
96fd02b2d6ee55d4aee7faab89a7a2b72764eafc47Keisuke Kuroyanagi    }
97fd02b2d6ee55d4aee7faab89a7a2b72764eafc47Keisuke Kuroyanagi
98fd02b2d6ee55d4aee7faab89a7a2b72764eafc47Keisuke Kuroyanagi    private void forcePassingLongTime(final BinaryDictionary binaryDictionary) {
9973a2426d455e6e83dd9402913889f80a0071f0acKeisuke Kuroyanagi        // 365 days.
10073a2426d455e6e83dd9402913889f80a0071f0acKeisuke Kuroyanagi        final int timeToElapse = (int)TimeUnit.SECONDS.convert(365, TimeUnit.DAYS);
1012fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa        mCurrentTime += timeToElapse;
102d78a447d107ae60d2bb8f16a1b9797f5ebad2277Keisuke Kuroyanagi        setCurrentTimeForTestMode(mCurrentTime);
1032fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa        binaryDictionary.flushWithGC();
104fd02b2d6ee55d4aee7faab89a7a2b72764eafc47Keisuke Kuroyanagi    }
105fd02b2d6ee55d4aee7faab89a7a2b72764eafc47Keisuke Kuroyanagi
1062fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa    private File createEmptyDictionaryAndGetFile(final String dictId,
1072fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa            final int formatVersion) throws IOException {
1089d7e8c717f56a8b706a174fd3d5a2864d08d320cKeisuke Kuroyanagi        if (formatVersion == FormatSpec.VERSION4
10904536f14b02566ead3a95fc7d80d47e8d99936edKeisuke Kuroyanagi                || formatVersion == FormatSpec.VERSION4_ONLY_FOR_TESTING
11004536f14b02566ead3a95fc7d80d47e8d99936edKeisuke Kuroyanagi                || formatVersion == FormatSpec.VERSION4_DEV) {
1119d7e8c717f56a8b706a174fd3d5a2864d08d320cKeisuke Kuroyanagi            return createEmptyVer4DictionaryAndGetFile(dictId, formatVersion);
1122fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa        } else {
1132fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa            throw new IOException("Dictionary format version " + formatVersion
1142fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa                    + " is not supported.");
1152fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa        }
1162fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa    }
117d78a447d107ae60d2bb8f16a1b9797f5ebad2277Keisuke Kuroyanagi
1189d7e8c717f56a8b706a174fd3d5a2864d08d320cKeisuke Kuroyanagi    private File createEmptyVer4DictionaryAndGetFile(final String dictId, final int formatVersion)
1199d7e8c717f56a8b706a174fd3d5a2864d08d320cKeisuke Kuroyanagi            throws IOException {
1202fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa        final File file = File.createTempFile(dictId, TEST_DICT_FILE_EXTENSION,
121fd02b2d6ee55d4aee7faab89a7a2b72764eafc47Keisuke Kuroyanagi                getContext().getCacheDir());
1222fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa        FileUtils.deleteRecursively(file);
123a91561aa58db1c43092c1caecc051a11fa5391c7Tadashi G. Takaoka        Map<String, String> attributeMap = new HashMap<>();
124b986f78ba826fa360304a69565f1880bdd7ce0c5Keisuke Kuroyanagi        attributeMap.put(DictionaryHeader.DICTIONARY_ID_KEY, dictId);
125b986f78ba826fa360304a69565f1880bdd7ce0c5Keisuke Kuroyanagi        attributeMap.put(DictionaryHeader.DICTIONARY_VERSION_KEY,
12626bd46095a05843e7574dfcf7db53406f215525dKeisuke Kuroyanagi                String.valueOf(TimeUnit.MILLISECONDS.toSeconds(System.currentTimeMillis())));
127b986f78ba826fa360304a69565f1880bdd7ce0c5Keisuke Kuroyanagi        attributeMap.put(DictionaryHeader.USES_FORGETTING_CURVE_KEY,
128b986f78ba826fa360304a69565f1880bdd7ce0c5Keisuke Kuroyanagi                DictionaryHeader.ATTRIBUTE_VALUE_TRUE);
129b986f78ba826fa360304a69565f1880bdd7ce0c5Keisuke Kuroyanagi        attributeMap.put(DictionaryHeader.HAS_HISTORICAL_INFO_KEY,
130b986f78ba826fa360304a69565f1880bdd7ce0c5Keisuke Kuroyanagi                DictionaryHeader.ATTRIBUTE_VALUE_TRUE);
1319d7e8c717f56a8b706a174fd3d5a2864d08d320cKeisuke Kuroyanagi        if (BinaryDictionaryUtils.createEmptyDictFile(file.getAbsolutePath(), formatVersion,
13243cf9076b2d053c554941e55f6073b8f586c510bJean Chalard                LocaleUtils.constructLocaleFromString(TEST_LOCALE), attributeMap)) {
133fd02b2d6ee55d4aee7faab89a7a2b72764eafc47Keisuke Kuroyanagi            return file;
134fd02b2d6ee55d4aee7faab89a7a2b72764eafc47Keisuke Kuroyanagi        } else {
135a245d15da5d295af21ead9a01583c64796a31ad7Jean Chalard            throw new IOException("Empty dictionary " + file.getAbsolutePath()
13604536f14b02566ead3a95fc7d80d47e8d99936edKeisuke Kuroyanagi                    + " cannot be created. Foramt version: " + formatVersion);
137fd02b2d6ee55d4aee7faab89a7a2b72764eafc47Keisuke Kuroyanagi        }
138fd02b2d6ee55d4aee7faab89a7a2b72764eafc47Keisuke Kuroyanagi    }
139fd02b2d6ee55d4aee7faab89a7a2b72764eafc47Keisuke Kuroyanagi
140d78a447d107ae60d2bb8f16a1b9797f5ebad2277Keisuke Kuroyanagi    private static int setCurrentTimeForTestMode(final int currentTime) {
141e784148ae6872942434eaa55ca32b4c6442cc8e8Keisuke Kuroyanagi        return BinaryDictionaryUtils.setCurrentTimeForTest(currentTime);
1422fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa    }
1432fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa
144d78a447d107ae60d2bb8f16a1b9797f5ebad2277Keisuke Kuroyanagi    private static int stopTestModeInNativeCode() {
145e784148ae6872942434eaa55ca32b4c6442cc8e8Keisuke Kuroyanagi        return BinaryDictionaryUtils.setCurrentTimeForTest(-1);
1462fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa    }
1472fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa
14826bd46095a05843e7574dfcf7db53406f215525dKeisuke Kuroyanagi    public void testReadDictInJavaSide() {
14904536f14b02566ead3a95fc7d80d47e8d99936edKeisuke Kuroyanagi        for (final int formatVersion : DICT_FORMAT_VERSIONS) {
15004536f14b02566ead3a95fc7d80d47e8d99936edKeisuke Kuroyanagi            testReadDictInJavaSide(formatVersion);
15104536f14b02566ead3a95fc7d80d47e8d99936edKeisuke Kuroyanagi        }
15226bd46095a05843e7574dfcf7db53406f215525dKeisuke Kuroyanagi    }
15326bd46095a05843e7574dfcf7db53406f215525dKeisuke Kuroyanagi
15426bd46095a05843e7574dfcf7db53406f215525dKeisuke Kuroyanagi    private void testReadDictInJavaSide(final int formatVersion) {
15526bd46095a05843e7574dfcf7db53406f215525dKeisuke Kuroyanagi        setCurrentTimeForTestMode(mCurrentTime);
15626bd46095a05843e7574dfcf7db53406f215525dKeisuke Kuroyanagi        File dictFile = null;
15726bd46095a05843e7574dfcf7db53406f215525dKeisuke Kuroyanagi        try {
15826bd46095a05843e7574dfcf7db53406f215525dKeisuke Kuroyanagi            dictFile = createEmptyDictionaryAndGetFile("TestBinaryDictionary", formatVersion);
15926bd46095a05843e7574dfcf7db53406f215525dKeisuke Kuroyanagi        } catch (IOException e) {
16026bd46095a05843e7574dfcf7db53406f215525dKeisuke Kuroyanagi            fail("IOException while writing an initial dictionary : " + e);
16126bd46095a05843e7574dfcf7db53406f215525dKeisuke Kuroyanagi        }
16226bd46095a05843e7574dfcf7db53406f215525dKeisuke Kuroyanagi        BinaryDictionary binaryDictionary = new BinaryDictionary(dictFile.getAbsolutePath(),
16326bd46095a05843e7574dfcf7db53406f215525dKeisuke Kuroyanagi                0 /* offset */, dictFile.length(), true /* useFullEditDistance */,
16426bd46095a05843e7574dfcf7db53406f215525dKeisuke Kuroyanagi                Locale.getDefault(), TEST_LOCALE, true /* isUpdatable */);
16526bd46095a05843e7574dfcf7db53406f215525dKeisuke Kuroyanagi        addUnigramWord(binaryDictionary, "a", DUMMY_PROBABILITY);
16626bd46095a05843e7574dfcf7db53406f215525dKeisuke Kuroyanagi        addUnigramWord(binaryDictionary, "ab", DUMMY_PROBABILITY);
16726bd46095a05843e7574dfcf7db53406f215525dKeisuke Kuroyanagi        addUnigramWord(binaryDictionary, "aaa", DUMMY_PROBABILITY);
16826bd46095a05843e7574dfcf7db53406f215525dKeisuke Kuroyanagi        addBigramWords(binaryDictionary, "a", "aaa", DUMMY_PROBABILITY);
16926bd46095a05843e7574dfcf7db53406f215525dKeisuke Kuroyanagi        binaryDictionary.flushWithGC();
17026bd46095a05843e7574dfcf7db53406f215525dKeisuke Kuroyanagi        binaryDictionary.close();
17126bd46095a05843e7574dfcf7db53406f215525dKeisuke Kuroyanagi
17293cda5bb396c22f1781e390debaf75d54cf7c0dcKeisuke Kuroyanagi        final DictDecoder dictDecoder =
17393cda5bb396c22f1781e390debaf75d54cf7c0dcKeisuke Kuroyanagi                BinaryDictIOUtils.getDictDecoder(dictFile, 0, dictFile.length());
17426bd46095a05843e7574dfcf7db53406f215525dKeisuke Kuroyanagi        try {
1758e3a1d0f89ac5a0c7d31effb8cbb447f93f70310Keisuke Kuroyanagi            final FusionDictionary dict =
1768e3a1d0f89ac5a0c7d31effb8cbb447f93f70310Keisuke Kuroyanagi                    dictDecoder.readDictionaryBinary(false /* deleteDictIfBroken */);
17726bd46095a05843e7574dfcf7db53406f215525dKeisuke Kuroyanagi            PtNode ptNode = FusionDictionary.findWordInTree(dict.mRootNodeArray, "a");
17826bd46095a05843e7574dfcf7db53406f215525dKeisuke Kuroyanagi            assertNotNull(ptNode);
17926bd46095a05843e7574dfcf7db53406f215525dKeisuke Kuroyanagi            assertTrue(ptNode.isTerminal());
18026bd46095a05843e7574dfcf7db53406f215525dKeisuke Kuroyanagi            assertNotNull(ptNode.getBigram("aaa"));
18126bd46095a05843e7574dfcf7db53406f215525dKeisuke Kuroyanagi            ptNode = FusionDictionary.findWordInTree(dict.mRootNodeArray, "ab");
18226bd46095a05843e7574dfcf7db53406f215525dKeisuke Kuroyanagi            assertNotNull(ptNode);
18326bd46095a05843e7574dfcf7db53406f215525dKeisuke Kuroyanagi            assertTrue(ptNode.isTerminal());
18426bd46095a05843e7574dfcf7db53406f215525dKeisuke Kuroyanagi            ptNode = FusionDictionary.findWordInTree(dict.mRootNodeArray, "aaa");
18526bd46095a05843e7574dfcf7db53406f215525dKeisuke Kuroyanagi            assertNotNull(ptNode);
18626bd46095a05843e7574dfcf7db53406f215525dKeisuke Kuroyanagi            assertTrue(ptNode.isTerminal());
18726bd46095a05843e7574dfcf7db53406f215525dKeisuke Kuroyanagi        } catch (IOException e) {
18826bd46095a05843e7574dfcf7db53406f215525dKeisuke Kuroyanagi            fail("IOException while reading dictionary: " + e);
18926bd46095a05843e7574dfcf7db53406f215525dKeisuke Kuroyanagi        } catch (UnsupportedFormatException e) {
19026bd46095a05843e7574dfcf7db53406f215525dKeisuke Kuroyanagi            fail("Unsupported format: " + e);
19126bd46095a05843e7574dfcf7db53406f215525dKeisuke Kuroyanagi        }
19226bd46095a05843e7574dfcf7db53406f215525dKeisuke Kuroyanagi        dictFile.delete();
19326bd46095a05843e7574dfcf7db53406f215525dKeisuke Kuroyanagi    }
19426bd46095a05843e7574dfcf7db53406f215525dKeisuke Kuroyanagi
1952fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa    public void testControlCurrentTime() {
1962fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa        final int TEST_COUNT = 1000;
1972fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa        final long seed = System.currentTimeMillis();
1982fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa        final Random random = new Random(seed);
199d78a447d107ae60d2bb8f16a1b9797f5ebad2277Keisuke Kuroyanagi        final int startTime = stopTestModeInNativeCode();
2002fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa        for (int i = 0; i < TEST_COUNT; i++) {
2012fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa            final int currentTime = random.nextInt(Integer.MAX_VALUE);
202d78a447d107ae60d2bb8f16a1b9797f5ebad2277Keisuke Kuroyanagi            final int currentTimeInNativeCode = setCurrentTimeForTestMode(currentTime);
203d78a447d107ae60d2bb8f16a1b9797f5ebad2277Keisuke Kuroyanagi            assertEquals(currentTime, currentTimeInNativeCode);
2042fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa        }
205d78a447d107ae60d2bb8f16a1b9797f5ebad2277Keisuke Kuroyanagi        final int endTime = stopTestModeInNativeCode();
2062fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa        final int MAX_ALLOWED_ELAPSED_TIME = 10;
2072fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa        assertTrue(startTime <= endTime && endTime <= startTime + MAX_ALLOWED_ELAPSED_TIME);
2082fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa    }
2092fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa
210fd02b2d6ee55d4aee7faab89a7a2b72764eafc47Keisuke Kuroyanagi    public void testAddValidAndInvalidWords() {
21104536f14b02566ead3a95fc7d80d47e8d99936edKeisuke Kuroyanagi        for (final int formatVersion : DICT_FORMAT_VERSIONS) {
21204536f14b02566ead3a95fc7d80d47e8d99936edKeisuke Kuroyanagi            testAddValidAndInvalidWords(formatVersion);
21304536f14b02566ead3a95fc7d80d47e8d99936edKeisuke Kuroyanagi        }
2142fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa    }
2152fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa
2162fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa    private void testAddValidAndInvalidWords(final int formatVersion) {
217fd02b2d6ee55d4aee7faab89a7a2b72764eafc47Keisuke Kuroyanagi        File dictFile = null;
218fd02b2d6ee55d4aee7faab89a7a2b72764eafc47Keisuke Kuroyanagi        try {
2192fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa            dictFile = createEmptyDictionaryAndGetFile("TestBinaryDictionary", formatVersion);
220fd02b2d6ee55d4aee7faab89a7a2b72764eafc47Keisuke Kuroyanagi        } catch (IOException e) {
221fd02b2d6ee55d4aee7faab89a7a2b72764eafc47Keisuke Kuroyanagi            fail("IOException while writing an initial dictionary : " + e);
222fd02b2d6ee55d4aee7faab89a7a2b72764eafc47Keisuke Kuroyanagi        }
223fd02b2d6ee55d4aee7faab89a7a2b72764eafc47Keisuke Kuroyanagi        BinaryDictionary binaryDictionary = new BinaryDictionary(dictFile.getAbsolutePath(),
224fd02b2d6ee55d4aee7faab89a7a2b72764eafc47Keisuke Kuroyanagi                0 /* offset */, dictFile.length(), true /* useFullEditDistance */,
225fd02b2d6ee55d4aee7faab89a7a2b72764eafc47Keisuke Kuroyanagi                Locale.getDefault(), TEST_LOCALE, true /* isUpdatable */);
226fd02b2d6ee55d4aee7faab89a7a2b72764eafc47Keisuke Kuroyanagi
2272fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa        addUnigramWord(binaryDictionary, "a", Dictionary.NOT_A_PROBABILITY);
228fd02b2d6ee55d4aee7faab89a7a2b72764eafc47Keisuke Kuroyanagi        assertFalse(binaryDictionary.isValidWord("a"));
2292fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa        addUnigramWord(binaryDictionary, "a", Dictionary.NOT_A_PROBABILITY);
2302fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa        addUnigramWord(binaryDictionary, "a", Dictionary.NOT_A_PROBABILITY);
231fd02b2d6ee55d4aee7faab89a7a2b72764eafc47Keisuke Kuroyanagi        assertTrue(binaryDictionary.isValidWord("a"));
232fd02b2d6ee55d4aee7faab89a7a2b72764eafc47Keisuke Kuroyanagi
2332fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa        addUnigramWord(binaryDictionary, "b", DUMMY_PROBABILITY);
234fd02b2d6ee55d4aee7faab89a7a2b72764eafc47Keisuke Kuroyanagi        assertTrue(binaryDictionary.isValidWord("b"));
235fd02b2d6ee55d4aee7faab89a7a2b72764eafc47Keisuke Kuroyanagi
2362fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa        addBigramWords(binaryDictionary, "a", "b", Dictionary.NOT_A_PROBABILITY);
237e507d92aa3ee4ae43124c5452f20aa8ed0ecef4cKeisuke Kuroyanagi        assertFalse(isValidBigram(binaryDictionary, "a", "b"));
2382fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa        addBigramWords(binaryDictionary, "a", "b", Dictionary.NOT_A_PROBABILITY);
239e507d92aa3ee4ae43124c5452f20aa8ed0ecef4cKeisuke Kuroyanagi        assertTrue(isValidBigram(binaryDictionary, "a", "b"));
240fd02b2d6ee55d4aee7faab89a7a2b72764eafc47Keisuke Kuroyanagi
2412fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa        addUnigramWord(binaryDictionary, "c", DUMMY_PROBABILITY);
2422fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa        addBigramWords(binaryDictionary, "a", "c", DUMMY_PROBABILITY);
243e507d92aa3ee4ae43124c5452f20aa8ed0ecef4cKeisuke Kuroyanagi        assertTrue(isValidBigram(binaryDictionary, "a", "c"));
244fd02b2d6ee55d4aee7faab89a7a2b72764eafc47Keisuke Kuroyanagi
245a2821fde60891f7a44441a3673abfa9c65e7fa66Keisuke Kuroyanagi        // Add bigrams of not valid unigrams.
2462fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa        addBigramWords(binaryDictionary, "x", "y", Dictionary.NOT_A_PROBABILITY);
247e507d92aa3ee4ae43124c5452f20aa8ed0ecef4cKeisuke Kuroyanagi        assertFalse(isValidBigram(binaryDictionary, "x", "y"));
2482fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa        addBigramWords(binaryDictionary, "x", "y", DUMMY_PROBABILITY);
249e507d92aa3ee4ae43124c5452f20aa8ed0ecef4cKeisuke Kuroyanagi        assertFalse(isValidBigram(binaryDictionary, "x", "y"));
250a2821fde60891f7a44441a3673abfa9c65e7fa66Keisuke Kuroyanagi
251fd02b2d6ee55d4aee7faab89a7a2b72764eafc47Keisuke Kuroyanagi        binaryDictionary.close();
252fd02b2d6ee55d4aee7faab89a7a2b72764eafc47Keisuke Kuroyanagi        dictFile.delete();
253fd02b2d6ee55d4aee7faab89a7a2b72764eafc47Keisuke Kuroyanagi    }
254fd02b2d6ee55d4aee7faab89a7a2b72764eafc47Keisuke Kuroyanagi
255fd02b2d6ee55d4aee7faab89a7a2b72764eafc47Keisuke Kuroyanagi    public void testDecayingProbability() {
25604536f14b02566ead3a95fc7d80d47e8d99936edKeisuke Kuroyanagi        for (final int formatVersion : DICT_FORMAT_VERSIONS) {
25704536f14b02566ead3a95fc7d80d47e8d99936edKeisuke Kuroyanagi            testDecayingProbability(formatVersion);
25804536f14b02566ead3a95fc7d80d47e8d99936edKeisuke Kuroyanagi        }
2592fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa    }
2602fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa
2612fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa    private void testDecayingProbability(final int formatVersion) {
262fd02b2d6ee55d4aee7faab89a7a2b72764eafc47Keisuke Kuroyanagi        File dictFile = null;
263fd02b2d6ee55d4aee7faab89a7a2b72764eafc47Keisuke Kuroyanagi        try {
2642fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa            dictFile = createEmptyDictionaryAndGetFile("TestBinaryDictionary", formatVersion);
265fd02b2d6ee55d4aee7faab89a7a2b72764eafc47Keisuke Kuroyanagi        } catch (IOException e) {
266fd02b2d6ee55d4aee7faab89a7a2b72764eafc47Keisuke Kuroyanagi            fail("IOException while writing an initial dictionary : " + e);
267fd02b2d6ee55d4aee7faab89a7a2b72764eafc47Keisuke Kuroyanagi        }
268fd02b2d6ee55d4aee7faab89a7a2b72764eafc47Keisuke Kuroyanagi        BinaryDictionary binaryDictionary = new BinaryDictionary(dictFile.getAbsolutePath(),
269fd02b2d6ee55d4aee7faab89a7a2b72764eafc47Keisuke Kuroyanagi                0 /* offset */, dictFile.length(), true /* useFullEditDistance */,
270fd02b2d6ee55d4aee7faab89a7a2b72764eafc47Keisuke Kuroyanagi                Locale.getDefault(), TEST_LOCALE, true /* isUpdatable */);
271fd02b2d6ee55d4aee7faab89a7a2b72764eafc47Keisuke Kuroyanagi
2722fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa        addUnigramWord(binaryDictionary, "a", DUMMY_PROBABILITY);
273fd02b2d6ee55d4aee7faab89a7a2b72764eafc47Keisuke Kuroyanagi        assertTrue(binaryDictionary.isValidWord("a"));
274fd02b2d6ee55d4aee7faab89a7a2b72764eafc47Keisuke Kuroyanagi        forcePassingShortTime(binaryDictionary);
275fd02b2d6ee55d4aee7faab89a7a2b72764eafc47Keisuke Kuroyanagi        assertFalse(binaryDictionary.isValidWord("a"));
276fd02b2d6ee55d4aee7faab89a7a2b72764eafc47Keisuke Kuroyanagi
2772fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa        addUnigramWord(binaryDictionary, "a", DUMMY_PROBABILITY);
2782fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa        addUnigramWord(binaryDictionary, "a", DUMMY_PROBABILITY);
2792fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa        addUnigramWord(binaryDictionary, "a", DUMMY_PROBABILITY);
2802fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa        assertTrue(binaryDictionary.isValidWord("a"));
281fd02b2d6ee55d4aee7faab89a7a2b72764eafc47Keisuke Kuroyanagi        forcePassingShortTime(binaryDictionary);
282fd02b2d6ee55d4aee7faab89a7a2b72764eafc47Keisuke Kuroyanagi        assertTrue(binaryDictionary.isValidWord("a"));
283fd02b2d6ee55d4aee7faab89a7a2b72764eafc47Keisuke Kuroyanagi        forcePassingLongTime(binaryDictionary);
284fd02b2d6ee55d4aee7faab89a7a2b72764eafc47Keisuke Kuroyanagi        assertFalse(binaryDictionary.isValidWord("a"));
285fd02b2d6ee55d4aee7faab89a7a2b72764eafc47Keisuke Kuroyanagi
2862fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa        addUnigramWord(binaryDictionary, "a", DUMMY_PROBABILITY);
2872fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa        addUnigramWord(binaryDictionary, "b", DUMMY_PROBABILITY);
2882fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa        addBigramWords(binaryDictionary, "a", "b", DUMMY_PROBABILITY);
289e507d92aa3ee4ae43124c5452f20aa8ed0ecef4cKeisuke Kuroyanagi        assertTrue(isValidBigram(binaryDictionary, "a", "b"));
290fd02b2d6ee55d4aee7faab89a7a2b72764eafc47Keisuke Kuroyanagi        forcePassingShortTime(binaryDictionary);
291e507d92aa3ee4ae43124c5452f20aa8ed0ecef4cKeisuke Kuroyanagi        assertFalse(isValidBigram(binaryDictionary, "a", "b"));
292fd02b2d6ee55d4aee7faab89a7a2b72764eafc47Keisuke Kuroyanagi
2932fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa        addUnigramWord(binaryDictionary, "a", DUMMY_PROBABILITY);
2942fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa        addUnigramWord(binaryDictionary, "b", DUMMY_PROBABILITY);
2952fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa        addBigramWords(binaryDictionary, "a", "b", DUMMY_PROBABILITY);
2962fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa        addUnigramWord(binaryDictionary, "a", DUMMY_PROBABILITY);
2972fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa        addUnigramWord(binaryDictionary, "b", DUMMY_PROBABILITY);
2982fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa        addBigramWords(binaryDictionary, "a", "b", DUMMY_PROBABILITY);
2992fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa        addUnigramWord(binaryDictionary, "a", DUMMY_PROBABILITY);
3002fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa        addUnigramWord(binaryDictionary, "b", DUMMY_PROBABILITY);
3012fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa        addBigramWords(binaryDictionary, "a", "b", DUMMY_PROBABILITY);
302e507d92aa3ee4ae43124c5452f20aa8ed0ecef4cKeisuke Kuroyanagi        assertTrue(isValidBigram(binaryDictionary, "a", "b"));
303fd02b2d6ee55d4aee7faab89a7a2b72764eafc47Keisuke Kuroyanagi        forcePassingShortTime(binaryDictionary);
304e507d92aa3ee4ae43124c5452f20aa8ed0ecef4cKeisuke Kuroyanagi        assertTrue(isValidBigram(binaryDictionary, "a", "b"));
305fd02b2d6ee55d4aee7faab89a7a2b72764eafc47Keisuke Kuroyanagi        forcePassingLongTime(binaryDictionary);
306e507d92aa3ee4ae43124c5452f20aa8ed0ecef4cKeisuke Kuroyanagi        assertFalse(isValidBigram(binaryDictionary, "a", "b"));
307fd02b2d6ee55d4aee7faab89a7a2b72764eafc47Keisuke Kuroyanagi
308fd02b2d6ee55d4aee7faab89a7a2b72764eafc47Keisuke Kuroyanagi        binaryDictionary.close();
309fd02b2d6ee55d4aee7faab89a7a2b72764eafc47Keisuke Kuroyanagi        dictFile.delete();
310fd02b2d6ee55d4aee7faab89a7a2b72764eafc47Keisuke Kuroyanagi    }
311cfb018ba6db78f2b33b54d4811f0bf166db29792Keisuke Kuroyanagi
312cfb018ba6db78f2b33b54d4811f0bf166db29792Keisuke Kuroyanagi    public void testAddManyUnigramsToDecayingDict() {
31304536f14b02566ead3a95fc7d80d47e8d99936edKeisuke Kuroyanagi        for (final int formatVersion : DICT_FORMAT_VERSIONS) {
31404536f14b02566ead3a95fc7d80d47e8d99936edKeisuke Kuroyanagi            testAddManyUnigramsToDecayingDict(formatVersion);
31504536f14b02566ead3a95fc7d80d47e8d99936edKeisuke Kuroyanagi        }
3162fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa    }
3172fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa
3182fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa    private void testAddManyUnigramsToDecayingDict(final int formatVersion) {
319cfb018ba6db78f2b33b54d4811f0bf166db29792Keisuke Kuroyanagi        final int unigramCount = 30000;
320cfb018ba6db78f2b33b54d4811f0bf166db29792Keisuke Kuroyanagi        final int unigramTypedCount = 100000;
321cfb018ba6db78f2b33b54d4811f0bf166db29792Keisuke Kuroyanagi        final int codePointSetSize = 50;
322cfb018ba6db78f2b33b54d4811f0bf166db29792Keisuke Kuroyanagi        final long seed = System.currentTimeMillis();
323cfb018ba6db78f2b33b54d4811f0bf166db29792Keisuke Kuroyanagi        final Random random = new Random(seed);
324cfb018ba6db78f2b33b54d4811f0bf166db29792Keisuke Kuroyanagi
325cfb018ba6db78f2b33b54d4811f0bf166db29792Keisuke Kuroyanagi        File dictFile = null;
326cfb018ba6db78f2b33b54d4811f0bf166db29792Keisuke Kuroyanagi        try {
3272fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa            dictFile = createEmptyDictionaryAndGetFile("TestBinaryDictionary", formatVersion);
328cfb018ba6db78f2b33b54d4811f0bf166db29792Keisuke Kuroyanagi        } catch (IOException e) {
329cfb018ba6db78f2b33b54d4811f0bf166db29792Keisuke Kuroyanagi            fail("IOException while writing an initial dictionary : " + e);
330cfb018ba6db78f2b33b54d4811f0bf166db29792Keisuke Kuroyanagi        }
331cfb018ba6db78f2b33b54d4811f0bf166db29792Keisuke Kuroyanagi        BinaryDictionary binaryDictionary = new BinaryDictionary(dictFile.getAbsolutePath(),
332cfb018ba6db78f2b33b54d4811f0bf166db29792Keisuke Kuroyanagi                0 /* offset */, dictFile.length(), true /* useFullEditDistance */,
333cfb018ba6db78f2b33b54d4811f0bf166db29792Keisuke Kuroyanagi                Locale.getDefault(), TEST_LOCALE, true /* isUpdatable */);
334d78a447d107ae60d2bb8f16a1b9797f5ebad2277Keisuke Kuroyanagi        setCurrentTimeForTestMode(mCurrentTime);
335cfb018ba6db78f2b33b54d4811f0bf166db29792Keisuke Kuroyanagi
336cfb018ba6db78f2b33b54d4811f0bf166db29792Keisuke Kuroyanagi        final int[] codePointSet = CodePointUtils.generateCodePointSet(codePointSetSize, random);
337a91561aa58db1c43092c1caecc051a11fa5391c7Tadashi G. Takaoka        final ArrayList<String> words = new ArrayList<>();
338cfb018ba6db78f2b33b54d4811f0bf166db29792Keisuke Kuroyanagi
339cfb018ba6db78f2b33b54d4811f0bf166db29792Keisuke Kuroyanagi        for (int i = 0; i < unigramCount; i++) {
340cfb018ba6db78f2b33b54d4811f0bf166db29792Keisuke Kuroyanagi            final String word = CodePointUtils.generateWord(random, codePointSet);
341cfb018ba6db78f2b33b54d4811f0bf166db29792Keisuke Kuroyanagi            words.add(word);
342cfb018ba6db78f2b33b54d4811f0bf166db29792Keisuke Kuroyanagi        }
343cfb018ba6db78f2b33b54d4811f0bf166db29792Keisuke Kuroyanagi
344cfb018ba6db78f2b33b54d4811f0bf166db29792Keisuke Kuroyanagi        final int maxUnigramCount = Integer.parseInt(
345d78a447d107ae60d2bb8f16a1b9797f5ebad2277Keisuke Kuroyanagi                binaryDictionary.getPropertyForTest(BinaryDictionary.MAX_UNIGRAM_COUNT_QUERY));
346cfb018ba6db78f2b33b54d4811f0bf166db29792Keisuke Kuroyanagi        for (int i = 0; i < unigramTypedCount; i++) {
347cfb018ba6db78f2b33b54d4811f0bf166db29792Keisuke Kuroyanagi            final String word = words.get(random.nextInt(words.size()));
3482fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa            addUnigramWord(binaryDictionary, word, DUMMY_PROBABILITY);
349cfb018ba6db78f2b33b54d4811f0bf166db29792Keisuke Kuroyanagi
350cfb018ba6db78f2b33b54d4811f0bf166db29792Keisuke Kuroyanagi            if (binaryDictionary.needsToRunGC(true /* mindsBlockByGC */)) {
351cfb018ba6db78f2b33b54d4811f0bf166db29792Keisuke Kuroyanagi                final int unigramCountBeforeGC =
352d78a447d107ae60d2bb8f16a1b9797f5ebad2277Keisuke Kuroyanagi                        Integer.parseInt(binaryDictionary.getPropertyForTest(
353cfb018ba6db78f2b33b54d4811f0bf166db29792Keisuke Kuroyanagi                                BinaryDictionary.UNIGRAM_COUNT_QUERY));
354cfb018ba6db78f2b33b54d4811f0bf166db29792Keisuke Kuroyanagi                while (binaryDictionary.needsToRunGC(true /* mindsBlockByGC */)) {
3552fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa                    forcePassingShortTime(binaryDictionary);
356cfb018ba6db78f2b33b54d4811f0bf166db29792Keisuke Kuroyanagi                }
357cfb018ba6db78f2b33b54d4811f0bf166db29792Keisuke Kuroyanagi                final int unigramCountAfterGC =
358d78a447d107ae60d2bb8f16a1b9797f5ebad2277Keisuke Kuroyanagi                        Integer.parseInt(binaryDictionary.getPropertyForTest(
359cfb018ba6db78f2b33b54d4811f0bf166db29792Keisuke Kuroyanagi                                BinaryDictionary.UNIGRAM_COUNT_QUERY));
360cfb018ba6db78f2b33b54d4811f0bf166db29792Keisuke Kuroyanagi                assertTrue(unigramCountBeforeGC > unigramCountAfterGC);
361cfb018ba6db78f2b33b54d4811f0bf166db29792Keisuke Kuroyanagi            }
362cfb018ba6db78f2b33b54d4811f0bf166db29792Keisuke Kuroyanagi        }
363cfb018ba6db78f2b33b54d4811f0bf166db29792Keisuke Kuroyanagi
364d78a447d107ae60d2bb8f16a1b9797f5ebad2277Keisuke Kuroyanagi        assertTrue(Integer.parseInt(binaryDictionary.getPropertyForTest(
365cfb018ba6db78f2b33b54d4811f0bf166db29792Keisuke Kuroyanagi                BinaryDictionary.UNIGRAM_COUNT_QUERY)) > 0);
366d78a447d107ae60d2bb8f16a1b9797f5ebad2277Keisuke Kuroyanagi        assertTrue(Integer.parseInt(binaryDictionary.getPropertyForTest(
367cfb018ba6db78f2b33b54d4811f0bf166db29792Keisuke Kuroyanagi                BinaryDictionary.UNIGRAM_COUNT_QUERY)) <= maxUnigramCount);
3682fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa        forcePassingLongTime(binaryDictionary);
369d78a447d107ae60d2bb8f16a1b9797f5ebad2277Keisuke Kuroyanagi        assertEquals(0, Integer.parseInt(binaryDictionary.getPropertyForTest(
3702fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa                BinaryDictionary.UNIGRAM_COUNT_QUERY)));
3712fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa    }
3722fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa
3732fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa    public void testOverflowUnigrams() {
37404536f14b02566ead3a95fc7d80d47e8d99936edKeisuke Kuroyanagi        for (final int formatVersion : DICT_FORMAT_VERSIONS) {
37504536f14b02566ead3a95fc7d80d47e8d99936edKeisuke Kuroyanagi            testOverflowUnigrams(formatVersion);
37604536f14b02566ead3a95fc7d80d47e8d99936edKeisuke Kuroyanagi        }
3772fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa    }
3782fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa
3792fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa    private void testOverflowUnigrams(final int formatVersion) {
3802fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa        final int unigramCount = 20000;
38173a2426d455e6e83dd9402913889f80a0071f0acKeisuke Kuroyanagi        final int eachUnigramTypedCount = 2;
3822fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa        final int strongUnigramTypedCount = 20;
3832fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa        final int weakUnigramTypedCount = 1;
3842fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa        final int codePointSetSize = 50;
3852fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa        final long seed = System.currentTimeMillis();
3862fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa        final Random random = new Random(seed);
3872fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa
3882fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa        File dictFile = null;
3892fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa        try {
3902fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa            dictFile = createEmptyDictionaryAndGetFile("TestBinaryDictionary", formatVersion);
3912fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa        } catch (IOException e) {
3922fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa            fail("IOException while writing an initial dictionary : " + e);
3932fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa        }
3942fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa        BinaryDictionary binaryDictionary = new BinaryDictionary(dictFile.getAbsolutePath(),
3952fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa                0 /* offset */, dictFile.length(), true /* useFullEditDistance */,
3962fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa                Locale.getDefault(), TEST_LOCALE, true /* isUpdatable */);
397d78a447d107ae60d2bb8f16a1b9797f5ebad2277Keisuke Kuroyanagi        setCurrentTimeForTestMode(mCurrentTime);
3982fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa        final int[] codePointSet = CodePointUtils.generateCodePointSet(codePointSetSize, random);
3992fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa
4002fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa        final String strong = "strong";
4012fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa        final String weak = "weak";
4022fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa        for (int j = 0; j < strongUnigramTypedCount; j++) {
4032fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa            addUnigramWord(binaryDictionary, strong, DUMMY_PROBABILITY);
4042fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa        }
4052fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa        for (int j = 0; j < weakUnigramTypedCount; j++) {
4062fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa            addUnigramWord(binaryDictionary, weak, DUMMY_PROBABILITY);
4072fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa        }
4082fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa        assertTrue(binaryDictionary.isValidWord(strong));
4092fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa        assertTrue(binaryDictionary.isValidWord(weak));
4102fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa
4112fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa        for (int i = 0; i < unigramCount; i++) {
4122fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa            final String word = CodePointUtils.generateWord(random, codePointSet);
4132fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa            for (int j = 0; j < eachUnigramTypedCount; j++) {
4142fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa                addUnigramWord(binaryDictionary, word, DUMMY_PROBABILITY);
4152fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa            }
4162fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa            if (binaryDictionary.needsToRunGC(true /* mindsBlockByGC */)) {
4172fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa                final int unigramCountBeforeGC =
418d78a447d107ae60d2bb8f16a1b9797f5ebad2277Keisuke Kuroyanagi                        Integer.parseInt(binaryDictionary.getPropertyForTest(
4192fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa                                BinaryDictionary.UNIGRAM_COUNT_QUERY));
4202fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa                assertTrue(binaryDictionary.isValidWord(strong));
4212fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa                assertTrue(binaryDictionary.isValidWord(weak));
4222fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa                binaryDictionary.flushWithGC();
4232fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa                final int unigramCountAfterGC =
424d78a447d107ae60d2bb8f16a1b9797f5ebad2277Keisuke Kuroyanagi                        Integer.parseInt(binaryDictionary.getPropertyForTest(
4252fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa                                BinaryDictionary.UNIGRAM_COUNT_QUERY));
4262fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa                assertTrue(unigramCountBeforeGC > unigramCountAfterGC);
4272fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa                assertFalse(binaryDictionary.isValidWord(weak));
4282fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa                assertTrue(binaryDictionary.isValidWord(strong));
4292fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa                break;
4302fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa            }
4312fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa        }
432cfb018ba6db78f2b33b54d4811f0bf166db29792Keisuke Kuroyanagi    }
433a2821fde60891f7a44441a3673abfa9c65e7fa66Keisuke Kuroyanagi
434a2821fde60891f7a44441a3673abfa9c65e7fa66Keisuke Kuroyanagi    public void testAddManyBigramsToDecayingDict() {
43504536f14b02566ead3a95fc7d80d47e8d99936edKeisuke Kuroyanagi        for (final int formatVersion : DICT_FORMAT_VERSIONS) {
43604536f14b02566ead3a95fc7d80d47e8d99936edKeisuke Kuroyanagi            testAddManyBigramsToDecayingDict(formatVersion);
43704536f14b02566ead3a95fc7d80d47e8d99936edKeisuke Kuroyanagi        }
4382fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa    }
4392fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa
4402fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa    private void testAddManyBigramsToDecayingDict(final int formatVersion) {
441a2821fde60891f7a44441a3673abfa9c65e7fa66Keisuke Kuroyanagi        final int unigramCount = 5000;
442a2821fde60891f7a44441a3673abfa9c65e7fa66Keisuke Kuroyanagi        final int bigramCount = 30000;
443a2821fde60891f7a44441a3673abfa9c65e7fa66Keisuke Kuroyanagi        final int bigramTypedCount = 100000;
444a2821fde60891f7a44441a3673abfa9c65e7fa66Keisuke Kuroyanagi        final int codePointSetSize = 50;
445a2821fde60891f7a44441a3673abfa9c65e7fa66Keisuke Kuroyanagi        final long seed = System.currentTimeMillis();
446a2821fde60891f7a44441a3673abfa9c65e7fa66Keisuke Kuroyanagi        final Random random = new Random(seed);
447a2821fde60891f7a44441a3673abfa9c65e7fa66Keisuke Kuroyanagi
448a2821fde60891f7a44441a3673abfa9c65e7fa66Keisuke Kuroyanagi        File dictFile = null;
449a2821fde60891f7a44441a3673abfa9c65e7fa66Keisuke Kuroyanagi        try {
4502fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa            dictFile = createEmptyDictionaryAndGetFile("TestBinaryDictionary", formatVersion);
451a2821fde60891f7a44441a3673abfa9c65e7fa66Keisuke Kuroyanagi        } catch (IOException e) {
452a2821fde60891f7a44441a3673abfa9c65e7fa66Keisuke Kuroyanagi            fail("IOException while writing an initial dictionary : " + e);
453a2821fde60891f7a44441a3673abfa9c65e7fa66Keisuke Kuroyanagi        }
454a2821fde60891f7a44441a3673abfa9c65e7fa66Keisuke Kuroyanagi        BinaryDictionary binaryDictionary = new BinaryDictionary(dictFile.getAbsolutePath(),
455a2821fde60891f7a44441a3673abfa9c65e7fa66Keisuke Kuroyanagi                0 /* offset */, dictFile.length(), true /* useFullEditDistance */,
456a2821fde60891f7a44441a3673abfa9c65e7fa66Keisuke Kuroyanagi                Locale.getDefault(), TEST_LOCALE, true /* isUpdatable */);
457d78a447d107ae60d2bb8f16a1b9797f5ebad2277Keisuke Kuroyanagi        setCurrentTimeForTestMode(mCurrentTime);
458a2821fde60891f7a44441a3673abfa9c65e7fa66Keisuke Kuroyanagi
459a2821fde60891f7a44441a3673abfa9c65e7fa66Keisuke Kuroyanagi        final int[] codePointSet = CodePointUtils.generateCodePointSet(codePointSetSize, random);
460a91561aa58db1c43092c1caecc051a11fa5391c7Tadashi G. Takaoka        final ArrayList<String> words = new ArrayList<>();
461a91561aa58db1c43092c1caecc051a11fa5391c7Tadashi G. Takaoka        final ArrayList<Pair<String, String>> bigrams = new ArrayList<>();
462a2821fde60891f7a44441a3673abfa9c65e7fa66Keisuke Kuroyanagi
463a2821fde60891f7a44441a3673abfa9c65e7fa66Keisuke Kuroyanagi        for (int i = 0; i < unigramCount; ++i) {
464a2821fde60891f7a44441a3673abfa9c65e7fa66Keisuke Kuroyanagi            final String word = CodePointUtils.generateWord(random, codePointSet);
465a2821fde60891f7a44441a3673abfa9c65e7fa66Keisuke Kuroyanagi            words.add(word);
466a2821fde60891f7a44441a3673abfa9c65e7fa66Keisuke Kuroyanagi        }
467a2821fde60891f7a44441a3673abfa9c65e7fa66Keisuke Kuroyanagi        for (int i = 0; i < bigramCount; ++i) {
468a2821fde60891f7a44441a3673abfa9c65e7fa66Keisuke Kuroyanagi            final int word0Index = random.nextInt(words.size());
469a2821fde60891f7a44441a3673abfa9c65e7fa66Keisuke Kuroyanagi            int word1Index = random.nextInt(words.size() - 1);
470a2821fde60891f7a44441a3673abfa9c65e7fa66Keisuke Kuroyanagi            if (word1Index >= word0Index) {
471a2821fde60891f7a44441a3673abfa9c65e7fa66Keisuke Kuroyanagi                word1Index += 1;
472a2821fde60891f7a44441a3673abfa9c65e7fa66Keisuke Kuroyanagi            }
473a2821fde60891f7a44441a3673abfa9c65e7fa66Keisuke Kuroyanagi            final String word0 = words.get(word0Index);
474a2821fde60891f7a44441a3673abfa9c65e7fa66Keisuke Kuroyanagi            final String word1 = words.get(word1Index);
475a91561aa58db1c43092c1caecc051a11fa5391c7Tadashi G. Takaoka            final Pair<String, String> bigram = new Pair<>(word0, word1);
476a2821fde60891f7a44441a3673abfa9c65e7fa66Keisuke Kuroyanagi            bigrams.add(bigram);
477a2821fde60891f7a44441a3673abfa9c65e7fa66Keisuke Kuroyanagi        }
478a2821fde60891f7a44441a3673abfa9c65e7fa66Keisuke Kuroyanagi
479a2821fde60891f7a44441a3673abfa9c65e7fa66Keisuke Kuroyanagi        final int maxBigramCount = Integer.parseInt(
480d78a447d107ae60d2bb8f16a1b9797f5ebad2277Keisuke Kuroyanagi                binaryDictionary.getPropertyForTest(BinaryDictionary.MAX_BIGRAM_COUNT_QUERY));
481a2821fde60891f7a44441a3673abfa9c65e7fa66Keisuke Kuroyanagi        for (int i = 0; i < bigramTypedCount; ++i) {
482a2821fde60891f7a44441a3673abfa9c65e7fa66Keisuke Kuroyanagi            final Pair<String, String> bigram = bigrams.get(random.nextInt(bigrams.size()));
4832fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa            addUnigramWord(binaryDictionary, bigram.first, DUMMY_PROBABILITY);
4842fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa            addUnigramWord(binaryDictionary, bigram.second, DUMMY_PROBABILITY);
4852fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa            addBigramWords(binaryDictionary, bigram.first, bigram.second, DUMMY_PROBABILITY);
486a2821fde60891f7a44441a3673abfa9c65e7fa66Keisuke Kuroyanagi
487a2821fde60891f7a44441a3673abfa9c65e7fa66Keisuke Kuroyanagi            if (binaryDictionary.needsToRunGC(true /* mindsBlockByGC */)) {
488a2821fde60891f7a44441a3673abfa9c65e7fa66Keisuke Kuroyanagi                final int bigramCountBeforeGC =
489d78a447d107ae60d2bb8f16a1b9797f5ebad2277Keisuke Kuroyanagi                        Integer.parseInt(binaryDictionary.getPropertyForTest(
490a2821fde60891f7a44441a3673abfa9c65e7fa66Keisuke Kuroyanagi                                BinaryDictionary.BIGRAM_COUNT_QUERY));
491a2821fde60891f7a44441a3673abfa9c65e7fa66Keisuke Kuroyanagi                while (binaryDictionary.needsToRunGC(true /* mindsBlockByGC */)) {
4922fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa                    forcePassingShortTime(binaryDictionary);
493a2821fde60891f7a44441a3673abfa9c65e7fa66Keisuke Kuroyanagi                }
494a2821fde60891f7a44441a3673abfa9c65e7fa66Keisuke Kuroyanagi                final int bigramCountAfterGC =
495d78a447d107ae60d2bb8f16a1b9797f5ebad2277Keisuke Kuroyanagi                        Integer.parseInt(binaryDictionary.getPropertyForTest(
496a2821fde60891f7a44441a3673abfa9c65e7fa66Keisuke Kuroyanagi                                BinaryDictionary.BIGRAM_COUNT_QUERY));
497a2821fde60891f7a44441a3673abfa9c65e7fa66Keisuke Kuroyanagi                assertTrue(bigramCountBeforeGC > bigramCountAfterGC);
498a2821fde60891f7a44441a3673abfa9c65e7fa66Keisuke Kuroyanagi            }
499a2821fde60891f7a44441a3673abfa9c65e7fa66Keisuke Kuroyanagi        }
500a2821fde60891f7a44441a3673abfa9c65e7fa66Keisuke Kuroyanagi
501d78a447d107ae60d2bb8f16a1b9797f5ebad2277Keisuke Kuroyanagi        assertTrue(Integer.parseInt(binaryDictionary.getPropertyForTest(
502a2821fde60891f7a44441a3673abfa9c65e7fa66Keisuke Kuroyanagi                BinaryDictionary.BIGRAM_COUNT_QUERY)) > 0);
503d78a447d107ae60d2bb8f16a1b9797f5ebad2277Keisuke Kuroyanagi        assertTrue(Integer.parseInt(binaryDictionary.getPropertyForTest(
504a2821fde60891f7a44441a3673abfa9c65e7fa66Keisuke Kuroyanagi                BinaryDictionary.BIGRAM_COUNT_QUERY)) <= maxBigramCount);
5052fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa        forcePassingLongTime(binaryDictionary);
506d78a447d107ae60d2bb8f16a1b9797f5ebad2277Keisuke Kuroyanagi        assertEquals(0, Integer.parseInt(binaryDictionary.getPropertyForTest(
5072fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa                BinaryDictionary.BIGRAM_COUNT_QUERY)));
5082fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa    }
5092fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa
5102fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa    public void testOverflowBigrams() {
51104536f14b02566ead3a95fc7d80d47e8d99936edKeisuke Kuroyanagi        for (final int formatVersion : DICT_FORMAT_VERSIONS) {
51204536f14b02566ead3a95fc7d80d47e8d99936edKeisuke Kuroyanagi            testOverflowBigrams(formatVersion);
51304536f14b02566ead3a95fc7d80d47e8d99936edKeisuke Kuroyanagi        }
5142fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa    }
5152fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa
5162fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa    private void testOverflowBigrams(final int formatVersion) {
5172fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa        final int bigramCount = 20000;
5182fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa        final int unigramCount = 1000;
5192fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa        final int unigramTypedCount = 20;
52073a2426d455e6e83dd9402913889f80a0071f0acKeisuke Kuroyanagi        final int eachBigramTypedCount = 2;
5212fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa        final int strongBigramTypedCount = 20;
5222fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa        final int weakBigramTypedCount = 1;
5232fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa        final int codePointSetSize = 50;
5242fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa        final long seed = System.currentTimeMillis();
5252fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa        final Random random = new Random(seed);
5262fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa
5272fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa        File dictFile = null;
5282fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa        try {
5292fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa            dictFile = createEmptyDictionaryAndGetFile("TestBinaryDictionary", formatVersion);
5302fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa        } catch (IOException e) {
5312fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa            fail("IOException while writing an initial dictionary : " + e);
5322fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa        }
5332fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa        BinaryDictionary binaryDictionary = new BinaryDictionary(dictFile.getAbsolutePath(),
5342fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa                0 /* offset */, dictFile.length(), true /* useFullEditDistance */,
5352fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa                Locale.getDefault(), TEST_LOCALE, true /* isUpdatable */);
536d78a447d107ae60d2bb8f16a1b9797f5ebad2277Keisuke Kuroyanagi        setCurrentTimeForTestMode(mCurrentTime);
5372fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa        final int[] codePointSet = CodePointUtils.generateCodePointSet(codePointSetSize, random);
5382fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa
539a91561aa58db1c43092c1caecc051a11fa5391c7Tadashi G. Takaoka        final ArrayList<String> words = new ArrayList<>();
5402fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa        for (int i = 0; i < unigramCount; i++) {
5412fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa            final String word = CodePointUtils.generateWord(random, codePointSet);
5422fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa            words.add(word);
5432fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa            for (int j = 0; j < unigramTypedCount; j++) {
5442fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa                addUnigramWord(binaryDictionary, word, DUMMY_PROBABILITY);
5452fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa            }
5462fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa        }
5472fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa        final String strong = "strong";
5482fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa        final String weak = "weak";
5492fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa        final String target = "target";
5502fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa        for (int j = 0; j < unigramTypedCount; j++) {
5512fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa            addUnigramWord(binaryDictionary, strong, DUMMY_PROBABILITY);
5522fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa            addUnigramWord(binaryDictionary, weak, DUMMY_PROBABILITY);
5532fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa            addUnigramWord(binaryDictionary, target, DUMMY_PROBABILITY);
5542fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa        }
5552fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa        binaryDictionary.flushWithGC();
5562fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa        for (int j = 0; j < strongBigramTypedCount; j++) {
5572fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa            addBigramWords(binaryDictionary, strong, target, DUMMY_PROBABILITY);
5582fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa        }
5592fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa        for (int j = 0; j < weakBigramTypedCount; j++) {
5602fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa            addBigramWords(binaryDictionary, weak, target, DUMMY_PROBABILITY);
5612fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa        }
562e507d92aa3ee4ae43124c5452f20aa8ed0ecef4cKeisuke Kuroyanagi        assertTrue(isValidBigram(binaryDictionary, strong, target));
563e507d92aa3ee4ae43124c5452f20aa8ed0ecef4cKeisuke Kuroyanagi        assertTrue(isValidBigram(binaryDictionary, weak, target));
5642fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa
5652fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa        for (int i = 0; i < bigramCount; i++) {
5662fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa            final int word0Index = random.nextInt(words.size());
5672fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa            final String word0 = words.get(word0Index);
5682fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa            final int index = random.nextInt(words.size() - 1);
5692fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa            final int word1Index = (index >= word0Index) ? index + 1 : index;
5702fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa            final String word1 = words.get(word1Index);
5712fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa
5722fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa            for (int j = 0; j < eachBigramTypedCount; j++) {
5732fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa                addBigramWords(binaryDictionary, word0, word1, DUMMY_PROBABILITY);
5742fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa            }
5752fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa            if (binaryDictionary.needsToRunGC(true /* mindsBlockByGC */)) {
5762fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa                final int bigramCountBeforeGC =
577d78a447d107ae60d2bb8f16a1b9797f5ebad2277Keisuke Kuroyanagi                        Integer.parseInt(binaryDictionary.getPropertyForTest(
5782fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa                                BinaryDictionary.BIGRAM_COUNT_QUERY));
5792fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa                binaryDictionary.flushWithGC();
5802fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa                final int bigramCountAfterGC =
581d78a447d107ae60d2bb8f16a1b9797f5ebad2277Keisuke Kuroyanagi                        Integer.parseInt(binaryDictionary.getPropertyForTest(
5822fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa                                BinaryDictionary.BIGRAM_COUNT_QUERY));
5832fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa                assertTrue(bigramCountBeforeGC > bigramCountAfterGC);
584e507d92aa3ee4ae43124c5452f20aa8ed0ecef4cKeisuke Kuroyanagi                assertTrue(isValidBigram(binaryDictionary, strong, target));
585e507d92aa3ee4ae43124c5452f20aa8ed0ecef4cKeisuke Kuroyanagi                assertFalse(isValidBigram(binaryDictionary, weak, target));
5862fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa                break;
5872fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa            }
5882fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa        }
589a2821fde60891f7a44441a3673abfa9c65e7fa66Keisuke Kuroyanagi    }
5909d7e8c717f56a8b706a174fd3d5a2864d08d320cKeisuke Kuroyanagi
5919d7e8c717f56a8b706a174fd3d5a2864d08d320cKeisuke Kuroyanagi    public void testDictMigration() {
59204536f14b02566ead3a95fc7d80d47e8d99936edKeisuke Kuroyanagi        for (final int formatVersion : DICT_FORMAT_VERSIONS) {
59304536f14b02566ead3a95fc7d80d47e8d99936edKeisuke Kuroyanagi            testDictMigration(FormatSpec.VERSION4_ONLY_FOR_TESTING, formatVersion);
59404536f14b02566ead3a95fc7d80d47e8d99936edKeisuke Kuroyanagi        }
5959d7e8c717f56a8b706a174fd3d5a2864d08d320cKeisuke Kuroyanagi    }
5969d7e8c717f56a8b706a174fd3d5a2864d08d320cKeisuke Kuroyanagi
5979d7e8c717f56a8b706a174fd3d5a2864d08d320cKeisuke Kuroyanagi    private void testDictMigration(final int fromFormatVersion, final int toFormatVersion) {
5989d7e8c717f56a8b706a174fd3d5a2864d08d320cKeisuke Kuroyanagi        setCurrentTimeForTestMode(mCurrentTime);
5999d7e8c717f56a8b706a174fd3d5a2864d08d320cKeisuke Kuroyanagi        File dictFile = null;
6009d7e8c717f56a8b706a174fd3d5a2864d08d320cKeisuke Kuroyanagi        try {
6019d7e8c717f56a8b706a174fd3d5a2864d08d320cKeisuke Kuroyanagi            dictFile = createEmptyDictionaryAndGetFile("TestBinaryDictionary", fromFormatVersion);
6029d7e8c717f56a8b706a174fd3d5a2864d08d320cKeisuke Kuroyanagi        } catch (IOException e) {
6039d7e8c717f56a8b706a174fd3d5a2864d08d320cKeisuke Kuroyanagi            fail("IOException while writing an initial dictionary : " + e);
6049d7e8c717f56a8b706a174fd3d5a2864d08d320cKeisuke Kuroyanagi        }
6059d7e8c717f56a8b706a174fd3d5a2864d08d320cKeisuke Kuroyanagi        final BinaryDictionary binaryDictionary = new BinaryDictionary(dictFile.getAbsolutePath(),
6069d7e8c717f56a8b706a174fd3d5a2864d08d320cKeisuke Kuroyanagi                0 /* offset */, dictFile.length(), true /* useFullEditDistance */,
6079d7e8c717f56a8b706a174fd3d5a2864d08d320cKeisuke Kuroyanagi                Locale.getDefault(), TEST_LOCALE, true /* isUpdatable */);
6089d7e8c717f56a8b706a174fd3d5a2864d08d320cKeisuke Kuroyanagi        addUnigramWord(binaryDictionary, "aaa", DUMMY_PROBABILITY);
6099d7e8c717f56a8b706a174fd3d5a2864d08d320cKeisuke Kuroyanagi        assertTrue(binaryDictionary.isValidWord("aaa"));
6109d7e8c717f56a8b706a174fd3d5a2864d08d320cKeisuke Kuroyanagi        addUnigramWord(binaryDictionary, "bbb", Dictionary.NOT_A_PROBABILITY);
6119d7e8c717f56a8b706a174fd3d5a2864d08d320cKeisuke Kuroyanagi        assertFalse(binaryDictionary.isValidWord("bbb"));
6129d7e8c717f56a8b706a174fd3d5a2864d08d320cKeisuke Kuroyanagi        addUnigramWord(binaryDictionary, "ccc", DUMMY_PROBABILITY);
6139d7e8c717f56a8b706a174fd3d5a2864d08d320cKeisuke Kuroyanagi        addUnigramWord(binaryDictionary, "ccc", DUMMY_PROBABILITY);
6149d7e8c717f56a8b706a174fd3d5a2864d08d320cKeisuke Kuroyanagi        addUnigramWord(binaryDictionary, "ccc", DUMMY_PROBABILITY);
6159d7e8c717f56a8b706a174fd3d5a2864d08d320cKeisuke Kuroyanagi        addUnigramWord(binaryDictionary, "ccc", DUMMY_PROBABILITY);
6169d7e8c717f56a8b706a174fd3d5a2864d08d320cKeisuke Kuroyanagi        addUnigramWord(binaryDictionary, "ccc", DUMMY_PROBABILITY);
617620a05ae59ec9f7be39557094fc306c51c712ca1Keisuke Kuroyanagi        addUnigramWord(binaryDictionary, "abc", DUMMY_PROBABILITY);
618620a05ae59ec9f7be39557094fc306c51c712ca1Keisuke Kuroyanagi        addBigramWords(binaryDictionary, "aaa", "abc", DUMMY_PROBABILITY);
619e507d92aa3ee4ae43124c5452f20aa8ed0ecef4cKeisuke Kuroyanagi        assertTrue(isValidBigram(binaryDictionary, "aaa", "abc"));
620620a05ae59ec9f7be39557094fc306c51c712ca1Keisuke Kuroyanagi        addBigramWords(binaryDictionary, "aaa", "bbb", Dictionary.NOT_A_PROBABILITY);
621e507d92aa3ee4ae43124c5452f20aa8ed0ecef4cKeisuke Kuroyanagi        assertFalse(isValidBigram(binaryDictionary, "aaa", "bbb"));
6229d7e8c717f56a8b706a174fd3d5a2864d08d320cKeisuke Kuroyanagi
6239d7e8c717f56a8b706a174fd3d5a2864d08d320cKeisuke Kuroyanagi        assertEquals(fromFormatVersion, binaryDictionary.getFormatVersion());
6249d7e8c717f56a8b706a174fd3d5a2864d08d320cKeisuke Kuroyanagi        assertTrue(binaryDictionary.migrateTo(toFormatVersion));
6259d7e8c717f56a8b706a174fd3d5a2864d08d320cKeisuke Kuroyanagi        assertTrue(binaryDictionary.isValidDictionary());
6269d7e8c717f56a8b706a174fd3d5a2864d08d320cKeisuke Kuroyanagi        assertEquals(toFormatVersion, binaryDictionary.getFormatVersion());
6279d7e8c717f56a8b706a174fd3d5a2864d08d320cKeisuke Kuroyanagi        assertTrue(binaryDictionary.isValidWord("aaa"));
6289d7e8c717f56a8b706a174fd3d5a2864d08d320cKeisuke Kuroyanagi        assertFalse(binaryDictionary.isValidWord("bbb"));
6299d7e8c717f56a8b706a174fd3d5a2864d08d320cKeisuke Kuroyanagi        assertTrue(binaryDictionary.getFrequency("aaa") < binaryDictionary.getFrequency("ccc"));
6309d7e8c717f56a8b706a174fd3d5a2864d08d320cKeisuke Kuroyanagi        addUnigramWord(binaryDictionary, "bbb", Dictionary.NOT_A_PROBABILITY);
6319d7e8c717f56a8b706a174fd3d5a2864d08d320cKeisuke Kuroyanagi        assertTrue(binaryDictionary.isValidWord("bbb"));
632e507d92aa3ee4ae43124c5452f20aa8ed0ecef4cKeisuke Kuroyanagi        assertTrue(isValidBigram(binaryDictionary, "aaa", "abc"));
633e507d92aa3ee4ae43124c5452f20aa8ed0ecef4cKeisuke Kuroyanagi        assertFalse(isValidBigram(binaryDictionary, "aaa", "bbb"));
634620a05ae59ec9f7be39557094fc306c51c712ca1Keisuke Kuroyanagi        addBigramWords(binaryDictionary, "aaa", "bbb", Dictionary.NOT_A_PROBABILITY);
635e507d92aa3ee4ae43124c5452f20aa8ed0ecef4cKeisuke Kuroyanagi        assertTrue(isValidBigram(binaryDictionary, "aaa", "bbb"));
6369d7e8c717f56a8b706a174fd3d5a2864d08d320cKeisuke Kuroyanagi        binaryDictionary.close();
6379d7e8c717f56a8b706a174fd3d5a2864d08d320cKeisuke Kuroyanagi        dictFile.delete();
6389d7e8c717f56a8b706a174fd3d5a2864d08d320cKeisuke Kuroyanagi    }
6391adca93381d261a6070be2721dbf8b8abafbfe01Keisuke Kuroyanagi
6401adca93381d261a6070be2721dbf8b8abafbfe01Keisuke Kuroyanagi    public void testBeginningOfSentence() {
6411adca93381d261a6070be2721dbf8b8abafbfe01Keisuke Kuroyanagi        for (final int formatVersion : DICT_FORMAT_VERSIONS) {
6421adca93381d261a6070be2721dbf8b8abafbfe01Keisuke Kuroyanagi            if (supportsBeginningOfSentence(formatVersion)) {
6431adca93381d261a6070be2721dbf8b8abafbfe01Keisuke Kuroyanagi                testBeginningOfSentence(formatVersion);
6441adca93381d261a6070be2721dbf8b8abafbfe01Keisuke Kuroyanagi            }
6451adca93381d261a6070be2721dbf8b8abafbfe01Keisuke Kuroyanagi        }
6461adca93381d261a6070be2721dbf8b8abafbfe01Keisuke Kuroyanagi    }
6471adca93381d261a6070be2721dbf8b8abafbfe01Keisuke Kuroyanagi
6481adca93381d261a6070be2721dbf8b8abafbfe01Keisuke Kuroyanagi    private void testBeginningOfSentence(final int formatVersion) {
6491adca93381d261a6070be2721dbf8b8abafbfe01Keisuke Kuroyanagi        setCurrentTimeForTestMode(mCurrentTime);
6501adca93381d261a6070be2721dbf8b8abafbfe01Keisuke Kuroyanagi        File dictFile = null;
6511adca93381d261a6070be2721dbf8b8abafbfe01Keisuke Kuroyanagi        try {
6521adca93381d261a6070be2721dbf8b8abafbfe01Keisuke Kuroyanagi            dictFile = createEmptyDictionaryAndGetFile("TestBinaryDictionary", formatVersion);
6531adca93381d261a6070be2721dbf8b8abafbfe01Keisuke Kuroyanagi        } catch (IOException e) {
6541adca93381d261a6070be2721dbf8b8abafbfe01Keisuke Kuroyanagi            fail("IOException while writing an initial dictionary : " + e);
6551adca93381d261a6070be2721dbf8b8abafbfe01Keisuke Kuroyanagi        }
6561adca93381d261a6070be2721dbf8b8abafbfe01Keisuke Kuroyanagi        final BinaryDictionary binaryDictionary = new BinaryDictionary(dictFile.getAbsolutePath(),
6571adca93381d261a6070be2721dbf8b8abafbfe01Keisuke Kuroyanagi                0 /* offset */, dictFile.length(), true /* useFullEditDistance */,
6581adca93381d261a6070be2721dbf8b8abafbfe01Keisuke Kuroyanagi                Locale.getDefault(), TEST_LOCALE, true /* isUpdatable */);
6591adca93381d261a6070be2721dbf8b8abafbfe01Keisuke Kuroyanagi
6601adca93381d261a6070be2721dbf8b8abafbfe01Keisuke Kuroyanagi        binaryDictionary.addUnigramEntry("", DUMMY_PROBABILITY, "" /* shortcutTarget */,
6611adca93381d261a6070be2721dbf8b8abafbfe01Keisuke Kuroyanagi                BinaryDictionary.NOT_A_PROBABILITY /* shortcutProbability */,
6621adca93381d261a6070be2721dbf8b8abafbfe01Keisuke Kuroyanagi                true /* isBeginningOfSentence */, true /* isNotAWord */, false /* isBlacklisted */,
6631adca93381d261a6070be2721dbf8b8abafbfe01Keisuke Kuroyanagi                mCurrentTime);
6641adca93381d261a6070be2721dbf8b8abafbfe01Keisuke Kuroyanagi        final PrevWordsInfo prevWordsInfoStartOfSentence = PrevWordsInfo.BEGINNING_OF_SENTENCE;
6651adca93381d261a6070be2721dbf8b8abafbfe01Keisuke Kuroyanagi        addUnigramWord(binaryDictionary, "aaa", DUMMY_PROBABILITY);
6661adca93381d261a6070be2721dbf8b8abafbfe01Keisuke Kuroyanagi        binaryDictionary.addNgramEntry(prevWordsInfoStartOfSentence, "aaa", DUMMY_PROBABILITY,
6671adca93381d261a6070be2721dbf8b8abafbfe01Keisuke Kuroyanagi                mCurrentTime);
6681adca93381d261a6070be2721dbf8b8abafbfe01Keisuke Kuroyanagi        assertTrue(binaryDictionary.isValidNgram(prevWordsInfoStartOfSentence, "aaa"));
6691adca93381d261a6070be2721dbf8b8abafbfe01Keisuke Kuroyanagi        binaryDictionary.addNgramEntry(prevWordsInfoStartOfSentence, "aaa", DUMMY_PROBABILITY,
6701adca93381d261a6070be2721dbf8b8abafbfe01Keisuke Kuroyanagi                mCurrentTime);
6711adca93381d261a6070be2721dbf8b8abafbfe01Keisuke Kuroyanagi        addUnigramWord(binaryDictionary, "bbb", DUMMY_PROBABILITY);
6721adca93381d261a6070be2721dbf8b8abafbfe01Keisuke Kuroyanagi        binaryDictionary.addNgramEntry(prevWordsInfoStartOfSentence, "bbb", DUMMY_PROBABILITY,
6731adca93381d261a6070be2721dbf8b8abafbfe01Keisuke Kuroyanagi                mCurrentTime);
6741adca93381d261a6070be2721dbf8b8abafbfe01Keisuke Kuroyanagi        assertTrue(binaryDictionary.isValidNgram(prevWordsInfoStartOfSentence, "aaa"));
6751adca93381d261a6070be2721dbf8b8abafbfe01Keisuke Kuroyanagi        assertTrue(binaryDictionary.isValidNgram(prevWordsInfoStartOfSentence, "bbb"));
6761adca93381d261a6070be2721dbf8b8abafbfe01Keisuke Kuroyanagi
6771adca93381d261a6070be2721dbf8b8abafbfe01Keisuke Kuroyanagi        forcePassingLongTime(binaryDictionary);
6781adca93381d261a6070be2721dbf8b8abafbfe01Keisuke Kuroyanagi        assertFalse(binaryDictionary.isValidNgram(prevWordsInfoStartOfSentence, "aaa"));
6791adca93381d261a6070be2721dbf8b8abafbfe01Keisuke Kuroyanagi        assertFalse(binaryDictionary.isValidNgram(prevWordsInfoStartOfSentence, "bbb"));
6801adca93381d261a6070be2721dbf8b8abafbfe01Keisuke Kuroyanagi
6811adca93381d261a6070be2721dbf8b8abafbfe01Keisuke Kuroyanagi        addUnigramWord(binaryDictionary, "aaa", DUMMY_PROBABILITY);
6821adca93381d261a6070be2721dbf8b8abafbfe01Keisuke Kuroyanagi        binaryDictionary.addNgramEntry(prevWordsInfoStartOfSentence, "aaa", DUMMY_PROBABILITY,
6831adca93381d261a6070be2721dbf8b8abafbfe01Keisuke Kuroyanagi                mCurrentTime);
6841adca93381d261a6070be2721dbf8b8abafbfe01Keisuke Kuroyanagi        addUnigramWord(binaryDictionary, "bbb", DUMMY_PROBABILITY);
6851adca93381d261a6070be2721dbf8b8abafbfe01Keisuke Kuroyanagi        binaryDictionary.addNgramEntry(prevWordsInfoStartOfSentence, "bbb", DUMMY_PROBABILITY,
6861adca93381d261a6070be2721dbf8b8abafbfe01Keisuke Kuroyanagi                mCurrentTime);
6871adca93381d261a6070be2721dbf8b8abafbfe01Keisuke Kuroyanagi        assertTrue(binaryDictionary.isValidNgram(prevWordsInfoStartOfSentence, "aaa"));
6881adca93381d261a6070be2721dbf8b8abafbfe01Keisuke Kuroyanagi        assertTrue(binaryDictionary.isValidNgram(prevWordsInfoStartOfSentence, "bbb"));
6891adca93381d261a6070be2721dbf8b8abafbfe01Keisuke Kuroyanagi        binaryDictionary.close();
6901adca93381d261a6070be2721dbf8b8abafbfe01Keisuke Kuroyanagi        dictFile.delete();
6911adca93381d261a6070be2721dbf8b8abafbfe01Keisuke Kuroyanagi    }
692fd02b2d6ee55d4aee7faab89a7a2b72764eafc47Keisuke Kuroyanagi}
693