1 /* 2 * Copyright (C) 2012 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package com.android.inputmethod.latin.makedict; 18 19 import android.test.AndroidTestCase; 20 import android.test.MoreAsserts; 21 import android.test.suitebuilder.annotation.LargeTest; 22 import android.util.Log; 23 import android.util.SparseArray; 24 25 import com.android.inputmethod.latin.CollectionUtils; 26 import com.android.inputmethod.latin.UserHistoryDictIOUtils; 27 import com.android.inputmethod.latin.makedict.BinaryDictInputOutput.FusionDictionaryBufferInterface; 28 import com.android.inputmethod.latin.makedict.FormatSpec.FileHeader; 29 import com.android.inputmethod.latin.makedict.FusionDictionary.CharGroup; 30 import com.android.inputmethod.latin.makedict.FusionDictionary.Node; 31 import com.android.inputmethod.latin.makedict.FusionDictionary.WeightedString; 32 33 import java.io.File; 34 import java.io.FileInputStream; 35 import java.io.FileOutputStream; 36 import java.io.IOException; 37 import java.nio.ByteBuffer; 38 import java.nio.channels.FileChannel; 39 import java.util.ArrayList; 40 import java.util.HashMap; 41 import java.util.HashSet; 42 import java.util.List; 43 import java.util.Map; 44 import java.util.Map.Entry; 45 import java.util.Random; 46 import java.util.Set; 47 48 /** 49 * Unit tests for BinaryDictInputOutput 50 */ 51 @LargeTest 52 public class BinaryDictIOTests extends AndroidTestCase { 53 private static final String TAG = BinaryDictIOTests.class.getSimpleName(); 54 private static final int MAX_UNIGRAMS = 100; 55 private static final int UNIGRAM_FREQ = 10; 56 private static final int BIGRAM_FREQ = 50; 57 private static final int TOLERANCE_OF_BIGRAM_FREQ = 5; 58 59 private static final int USE_BYTE_ARRAY = 1; 60 private static final int USE_BYTE_BUFFER = 2; 61 62 private static final List<String> sWords = CollectionUtils.newArrayList(); 63 private static final SparseArray<List<Integer>> sEmptyBigrams = 64 CollectionUtils.newSparseArray(); 65 private static final SparseArray<List<Integer>> sStarBigrams = CollectionUtils.newSparseArray(); 66 private static final SparseArray<List<Integer>> sChainBigrams = 67 CollectionUtils.newSparseArray(); 68 69 private static final FormatSpec.FormatOptions VERSION2 = new FormatSpec.FormatOptions(2); 70 private static final FormatSpec.FormatOptions VERSION3_WITHOUT_DYNAMIC_UPDATE = 71 new FormatSpec.FormatOptions(3, false /* supportsDynamicUpdate */); 72 private static final FormatSpec.FormatOptions VERSION3_WITH_DYNAMIC_UPDATE = 73 new FormatSpec.FormatOptions(3, true /* supportsDynamicUpdate */); 74 75 public BinaryDictIOTests() { 76 super(); 77 78 final long time = System.currentTimeMillis(); 79 Log.e(TAG, "Testing dictionary: seed is " + time); 80 final Random random = new Random(time); 81 sWords.clear(); 82 generateWords(MAX_UNIGRAMS, random); 83 84 for (int i = 0; i < sWords.size(); ++i) { 85 sChainBigrams.put(i, new ArrayList<Integer>()); 86 if (i > 0) { 87 sChainBigrams.get(i - 1).add(i); 88 } 89 } 90 91 sStarBigrams.put(0, new ArrayList<Integer>()); 92 for (int i = 1; i < sWords.size(); ++i) { 93 sStarBigrams.get(0).add(i); 94 } 95 } 96 97 // Utilities for test 98 99 /** 100 * Makes new buffer according to BUFFER_TYPE. 101 */ 102 private FusionDictionaryBufferInterface getBuffer(final File file, final int bufferType) { 103 FileInputStream inStream = null; 104 try { 105 inStream = new FileInputStream(file); 106 if (bufferType == USE_BYTE_ARRAY) { 107 final byte[] array = new byte[(int)file.length()]; 108 inStream.read(array); 109 return new UserHistoryDictIOUtils.ByteArrayWrapper(array); 110 } else if (bufferType == USE_BYTE_BUFFER){ 111 final ByteBuffer buffer = inStream.getChannel().map( 112 FileChannel.MapMode.READ_ONLY, 0, file.length()); 113 return new BinaryDictInputOutput.ByteBufferWrapper(buffer); 114 } 115 } catch (IOException e) { 116 Log.e(TAG, "IOException while making buffer", e); 117 } finally { 118 if (inStream != null) { 119 try { 120 inStream.close(); 121 } catch (IOException e) { 122 Log.e(TAG, "IOException while closing stream", e); 123 } 124 } 125 } 126 return null; 127 } 128 129 /** 130 * Generates a random word. 131 */ 132 private String generateWord(final Random random) { 133 StringBuilder builder = new StringBuilder("a"); 134 int count = random.nextInt() % 30; // Arbitrarily 30 chars max 135 while (count > 0) { 136 final long r = Math.abs(random.nextInt()); 137 if (r < 0) continue; 138 // Don't insert 0~0x20, but insert any other code point. 139 // Code points are in the range 0~0x10FFFF. 140 final int candidateCodePoint = (int)(0x20 + r % (Character.MAX_CODE_POINT - 0x20)); 141 // Code points between MIN_ and MAX_SURROGATE are not valid on their own. 142 if (candidateCodePoint >= Character.MIN_SURROGATE 143 && candidateCodePoint <= Character.MAX_SURROGATE) continue; 144 builder.appendCodePoint(candidateCodePoint); 145 --count; 146 } 147 return builder.toString(); 148 } 149 150 private void generateWords(final int number, final Random random) { 151 final Set<String> wordSet = CollectionUtils.newHashSet(); 152 while (wordSet.size() < number) { 153 wordSet.add(generateWord(random)); 154 } 155 sWords.addAll(wordSet); 156 } 157 158 /** 159 * Adds unigrams to the dictionary. 160 */ 161 private void addUnigrams(final int number, final FusionDictionary dict, 162 final List<String> words, final Map<String, List<String>> shortcutMap) { 163 for (int i = 0; i < number; ++i) { 164 final String word = words.get(i); 165 final ArrayList<WeightedString> shortcuts = CollectionUtils.newArrayList(); 166 if (shortcutMap != null && shortcutMap.containsKey(word)) { 167 for (final String shortcut : shortcutMap.get(word)) { 168 shortcuts.add(new WeightedString(shortcut, UNIGRAM_FREQ)); 169 } 170 } 171 dict.add(word, UNIGRAM_FREQ, (shortcutMap == null) ? null : shortcuts, 172 false /* isNotAWord */); 173 } 174 } 175 176 private void addBigrams(final FusionDictionary dict, 177 final List<String> words, 178 final SparseArray<List<Integer>> bigrams) { 179 for (int i = 0; i < bigrams.size(); ++i) { 180 final int w1 = bigrams.keyAt(i); 181 for (int w2 : bigrams.valueAt(i)) { 182 dict.setBigram(words.get(w1), words.get(w2), BIGRAM_FREQ); 183 } 184 } 185 } 186 187 private long timeWritingDictToFile(final File file, final FusionDictionary dict, 188 final FormatSpec.FormatOptions formatOptions) { 189 190 long now = -1, diff = -1; 191 192 try { 193 final FileOutputStream out = new FileOutputStream(file); 194 195 now = System.currentTimeMillis(); 196 BinaryDictInputOutput.writeDictionaryBinary(out, dict, formatOptions); 197 diff = System.currentTimeMillis() - now; 198 199 out.flush(); 200 out.close(); 201 } catch (IOException e) { 202 Log.e(TAG, "IO exception while writing file", e); 203 } catch (UnsupportedFormatException e) { 204 Log.e(TAG, "UnsupportedFormatException", e); 205 } 206 207 return diff; 208 } 209 210 private void checkDictionary(final FusionDictionary dict, final List<String> words, 211 final SparseArray<List<Integer>> bigrams, final Map<String, List<String>> shortcutMap) { 212 assertNotNull(dict); 213 214 // check unigram 215 for (final String word : words) { 216 final CharGroup cg = FusionDictionary.findWordInTree(dict.mRoot, word); 217 assertNotNull(cg); 218 } 219 220 // check bigram 221 for (int i = 0; i < bigrams.size(); ++i) { 222 final int w1 = bigrams.keyAt(i); 223 for (final int w2 : bigrams.valueAt(i)) { 224 final CharGroup cg = FusionDictionary.findWordInTree(dict.mRoot, words.get(w1)); 225 assertNotNull(words.get(w1) + "," + words.get(w2), cg.getBigram(words.get(w2))); 226 } 227 } 228 229 // check shortcut 230 if (shortcutMap != null) { 231 for (final Map.Entry<String, List<String>> entry : shortcutMap.entrySet()) { 232 final CharGroup group = FusionDictionary.findWordInTree(dict.mRoot, entry.getKey()); 233 for (final String word : entry.getValue()) { 234 assertNotNull("shortcut not found: " + entry.getKey() + ", " + word, 235 group.getShortcut(word)); 236 } 237 } 238 } 239 } 240 241 private String outputOptions(final int bufferType, 242 final FormatSpec.FormatOptions formatOptions) { 243 String result = " : buffer type = " 244 + ((bufferType == USE_BYTE_BUFFER) ? "byte buffer" : "byte array"); 245 result += " : version = " + formatOptions.mVersion; 246 return result + ", supportsDynamicUpdate = " + formatOptions.mSupportsDynamicUpdate; 247 } 248 249 // Tests for readDictionaryBinary and writeDictionaryBinary 250 251 private long timeReadingAndCheckDict(final File file, final List<String> words, 252 final SparseArray<List<Integer>> bigrams, final Map<String, List<String>> shortcutMap, 253 final int bufferType) { 254 long now, diff = -1; 255 final FusionDictionaryBufferInterface buffer = getBuffer(file, bufferType); 256 assertNotNull(buffer); 257 258 FusionDictionary dict = null; 259 try { 260 now = System.currentTimeMillis(); 261 dict = BinaryDictInputOutput.readDictionaryBinary(buffer, null); 262 diff = System.currentTimeMillis() - now; 263 } catch (IOException e) { 264 Log.e(TAG, "IOException while reading dictionary", e); 265 } catch (UnsupportedFormatException e) { 266 Log.e(TAG, "Unsupported format", e); 267 } 268 269 checkDictionary(dict, words, bigrams, shortcutMap); 270 return diff; 271 } 272 273 // Tests for readDictionaryBinary and writeDictionaryBinary 274 private String runReadAndWrite(final List<String> words, 275 final SparseArray<List<Integer>> bigrams, final Map<String, List<String>> shortcuts, 276 final int bufferType, final FormatSpec.FormatOptions formatOptions, 277 final String message) { 278 File file = null; 279 try { 280 file = File.createTempFile("runReadAndWrite", ".dict", getContext().getCacheDir()); 281 } catch (IOException e) { 282 Log.e(TAG, "IOException", e); 283 } 284 assertNotNull(file); 285 286 final FusionDictionary dict = new FusionDictionary(new Node(), 287 new FusionDictionary.DictionaryOptions(new HashMap<String,String>(), false, false)); 288 addUnigrams(words.size(), dict, words, shortcuts); 289 addBigrams(dict, words, bigrams); 290 checkDictionary(dict, words, bigrams, shortcuts); 291 292 final long write = timeWritingDictToFile(file, dict, formatOptions); 293 final long read = timeReadingAndCheckDict(file, words, bigrams, shortcuts, bufferType); 294 295 return "PROF: read=" + read + "ms, write=" + write + "ms :" + message 296 + " : " + outputOptions(bufferType, formatOptions); 297 } 298 299 private void runReadAndWriteTests(final List<String> results, final int bufferType, 300 final FormatSpec.FormatOptions formatOptions) { 301 results.add(runReadAndWrite(sWords, sEmptyBigrams, null /* shortcuts */, bufferType, 302 formatOptions, "unigram")); 303 results.add(runReadAndWrite(sWords, sChainBigrams, null /* shortcuts */, bufferType, 304 formatOptions, "chain")); 305 results.add(runReadAndWrite(sWords, sStarBigrams, null /* shortcuts */, bufferType, 306 formatOptions, "star")); 307 } 308 309 public void testReadAndWriteWithByteBuffer() { 310 final List<String> results = CollectionUtils.newArrayList(); 311 312 runReadAndWriteTests(results, USE_BYTE_BUFFER, VERSION2); 313 runReadAndWriteTests(results, USE_BYTE_BUFFER, VERSION3_WITHOUT_DYNAMIC_UPDATE); 314 runReadAndWriteTests(results, USE_BYTE_BUFFER, VERSION3_WITH_DYNAMIC_UPDATE); 315 316 for (final String result : results) { 317 Log.d(TAG, result); 318 } 319 } 320 321 public void testReadAndWriteWithByteArray() { 322 final List<String> results = CollectionUtils.newArrayList(); 323 324 runReadAndWriteTests(results, USE_BYTE_ARRAY, VERSION2); 325 runReadAndWriteTests(results, USE_BYTE_ARRAY, VERSION3_WITHOUT_DYNAMIC_UPDATE); 326 runReadAndWriteTests(results, USE_BYTE_ARRAY, VERSION3_WITH_DYNAMIC_UPDATE); 327 328 for (final String result : results) { 329 Log.d(TAG, result); 330 } 331 } 332 333 // Tests for readUnigramsAndBigramsBinary 334 335 private void checkWordMap(final List<String> expectedWords, 336 final SparseArray<List<Integer>> expectedBigrams, 337 final Map<Integer, String> resultWords, 338 final Map<Integer, Integer> resultFrequencies, 339 final Map<Integer, ArrayList<PendingAttribute>> resultBigrams) { 340 // check unigrams 341 final Set<String> actualWordsSet = new HashSet<String>(resultWords.values()); 342 final Set<String> expectedWordsSet = new HashSet<String>(expectedWords); 343 assertEquals(actualWordsSet, expectedWordsSet); 344 345 for (int freq : resultFrequencies.values()) { 346 assertEquals(freq, UNIGRAM_FREQ); 347 } 348 349 // check bigrams 350 final Map<String, List<String>> expBigrams = new HashMap<String, List<String>>(); 351 for (int i = 0; i < expectedBigrams.size(); ++i) { 352 final String word1 = expectedWords.get(expectedBigrams.keyAt(i)); 353 for (int w2 : expectedBigrams.valueAt(i)) { 354 if (expBigrams.get(word1) == null) { 355 expBigrams.put(word1, new ArrayList<String>()); 356 } 357 expBigrams.get(word1).add(expectedWords.get(w2)); 358 } 359 } 360 361 final Map<String, List<String>> actBigrams = new HashMap<String, List<String>>(); 362 for (Entry<Integer, ArrayList<PendingAttribute>> entry : resultBigrams.entrySet()) { 363 final String word1 = resultWords.get(entry.getKey()); 364 final int unigramFreq = resultFrequencies.get(entry.getKey()); 365 for (PendingAttribute attr : entry.getValue()) { 366 final String word2 = resultWords.get(attr.mAddress); 367 if (actBigrams.get(word1) == null) { 368 actBigrams.put(word1, new ArrayList<String>()); 369 } 370 actBigrams.get(word1).add(word2); 371 372 final int bigramFreq = BinaryDictInputOutput.reconstructBigramFrequency( 373 unigramFreq, attr.mFrequency); 374 assertTrue(Math.abs(bigramFreq - BIGRAM_FREQ) < TOLERANCE_OF_BIGRAM_FREQ); 375 } 376 } 377 378 assertEquals(actBigrams, expBigrams); 379 } 380 381 private long timeAndCheckReadUnigramsAndBigramsBinary(final File file, final List<String> words, 382 final SparseArray<List<Integer>> bigrams, final int bufferType) { 383 FileInputStream inStream = null; 384 385 final Map<Integer, String> resultWords = CollectionUtils.newTreeMap(); 386 final Map<Integer, ArrayList<PendingAttribute>> resultBigrams = 387 CollectionUtils.newTreeMap(); 388 final Map<Integer, Integer> resultFreqs = CollectionUtils.newTreeMap(); 389 390 long now = -1, diff = -1; 391 final FusionDictionaryBufferInterface buffer = getBuffer(file, bufferType); 392 assertNotNull("Can't get buffer.", buffer); 393 try { 394 now = System.currentTimeMillis(); 395 BinaryDictIOUtils.readUnigramsAndBigramsBinary(buffer, resultWords, resultFreqs, 396 resultBigrams); 397 diff = System.currentTimeMillis() - now; 398 } catch (IOException e) { 399 Log.e(TAG, "IOException", e); 400 } catch (UnsupportedFormatException e) { 401 Log.e(TAG, "UnsupportedFormatException", e); 402 } finally { 403 if (inStream != null) { 404 try { 405 inStream.close(); 406 } catch (IOException e) { 407 // do nothing 408 } 409 } 410 } 411 412 checkWordMap(words, bigrams, resultWords, resultFreqs, resultBigrams); 413 return diff; 414 } 415 416 private String runReadUnigramsAndBigramsBinary(final List<String> words, 417 final SparseArray<List<Integer>> bigrams, final int bufferType, 418 final FormatSpec.FormatOptions formatOptions, final String message) { 419 File file = null; 420 try { 421 file = File.createTempFile("runReadUnigrams", ".dict", getContext().getCacheDir()); 422 } catch (IOException e) { 423 Log.e(TAG, "IOException", e); 424 } 425 assertNotNull(file); 426 427 // making the dictionary from lists of words. 428 final FusionDictionary dict = new FusionDictionary(new Node(), 429 new FusionDictionary.DictionaryOptions( 430 new HashMap<String, String>(), false, false)); 431 addUnigrams(words.size(), dict, words, null /* shortcutMap */); 432 addBigrams(dict, words, bigrams); 433 434 timeWritingDictToFile(file, dict, formatOptions); 435 436 long wordMap = timeAndCheckReadUnigramsAndBigramsBinary(file, words, bigrams, bufferType); 437 long fullReading = timeReadingAndCheckDict(file, words, bigrams, null /* shortcutMap */, 438 bufferType); 439 440 return "readDictionaryBinary=" + fullReading + ", readUnigramsAndBigramsBinary=" + wordMap 441 + " : " + message + " : " + outputOptions(bufferType, formatOptions); 442 } 443 444 private void runReadUnigramsAndBigramsTests(final List<String> results, final int bufferType, 445 final FormatSpec.FormatOptions formatOptions) { 446 results.add(runReadUnigramsAndBigramsBinary(sWords, sEmptyBigrams, bufferType, 447 formatOptions, "unigram")); 448 results.add(runReadUnigramsAndBigramsBinary(sWords, sChainBigrams, bufferType, 449 formatOptions, "chain")); 450 results.add(runReadUnigramsAndBigramsBinary(sWords, sChainBigrams, bufferType, 451 formatOptions, "star")); 452 } 453 454 public void testReadUnigramsAndBigramsBinaryWithByteBuffer() { 455 final List<String> results = CollectionUtils.newArrayList(); 456 457 runReadUnigramsAndBigramsTests(results, USE_BYTE_BUFFER, VERSION2); 458 runReadUnigramsAndBigramsTests(results, USE_BYTE_BUFFER, VERSION3_WITHOUT_DYNAMIC_UPDATE); 459 runReadUnigramsAndBigramsTests(results, USE_BYTE_BUFFER, VERSION3_WITH_DYNAMIC_UPDATE); 460 461 for (final String result : results) { 462 Log.d(TAG, result); 463 } 464 } 465 466 public void testReadUnigramsAndBigramsBinaryWithByteArray() { 467 final List<String> results = CollectionUtils.newArrayList(); 468 469 runReadUnigramsAndBigramsTests(results, USE_BYTE_ARRAY, VERSION2); 470 runReadUnigramsAndBigramsTests(results, USE_BYTE_ARRAY, VERSION3_WITHOUT_DYNAMIC_UPDATE); 471 runReadUnigramsAndBigramsTests(results, USE_BYTE_ARRAY, VERSION3_WITH_DYNAMIC_UPDATE); 472 473 for (final String result : results) { 474 Log.d(TAG, result); 475 } 476 } 477 478 // Tests for getTerminalPosition 479 private String getWordFromBinary(final FusionDictionaryBufferInterface buffer, 480 final int address) { 481 if (buffer.position() != 0) buffer.position(0); 482 483 FileHeader header = null; 484 try { 485 header = BinaryDictInputOutput.readHeader(buffer); 486 } catch (IOException e) { 487 return null; 488 } catch (UnsupportedFormatException e) { 489 return null; 490 } 491 if (header == null) return null; 492 return BinaryDictInputOutput.getWordAtAddress(buffer, header.mHeaderSize, 493 address - header.mHeaderSize, header.mFormatOptions).mWord; 494 } 495 496 private long runGetTerminalPosition(final FusionDictionaryBufferInterface buffer, 497 final String word, int index, boolean contained) { 498 final int expectedFrequency = (UNIGRAM_FREQ + index) % 255; 499 long diff = -1; 500 int position = -1; 501 try { 502 final long now = System.nanoTime(); 503 position = BinaryDictIOUtils.getTerminalPosition(buffer, word); 504 diff = System.nanoTime() - now; 505 } catch (IOException e) { 506 Log.e(TAG, "IOException while getTerminalPosition", e); 507 } catch (UnsupportedFormatException e) { 508 Log.e(TAG, "UnsupportedFormatException while getTerminalPosition", e); 509 } 510 511 assertEquals(FormatSpec.NOT_VALID_WORD != position, contained); 512 if (contained) assertEquals(getWordFromBinary(buffer, position), word); 513 return diff; 514 } 515 516 public void testGetTerminalPosition() { 517 File file = null; 518 try { 519 file = File.createTempFile("testGetTerminalPosition", ".dict", 520 getContext().getCacheDir()); 521 } catch (IOException e) { 522 // do nothing 523 } 524 assertNotNull(file); 525 526 final FusionDictionary dict = new FusionDictionary(new Node(), 527 new FusionDictionary.DictionaryOptions( 528 new HashMap<String, String>(), false, false)); 529 addUnigrams(sWords.size(), dict, sWords, null /* shortcutMap */); 530 timeWritingDictToFile(file, dict, VERSION3_WITH_DYNAMIC_UPDATE); 531 532 final FusionDictionaryBufferInterface buffer = getBuffer(file, USE_BYTE_ARRAY); 533 534 try { 535 // too long word 536 final String longWord = "abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz"; 537 assertEquals(FormatSpec.NOT_VALID_WORD, 538 BinaryDictIOUtils.getTerminalPosition(buffer, longWord)); 539 540 // null 541 assertEquals(FormatSpec.NOT_VALID_WORD, 542 BinaryDictIOUtils.getTerminalPosition(buffer, null)); 543 544 // empty string 545 assertEquals(FormatSpec.NOT_VALID_WORD, 546 BinaryDictIOUtils.getTerminalPosition(buffer, "")); 547 } catch (IOException e) { 548 } catch (UnsupportedFormatException e) { 549 } 550 551 // Test a word that is contained within the dictionary. 552 long sum = 0; 553 for (int i = 0; i < sWords.size(); ++i) { 554 final long time = runGetTerminalPosition(buffer, sWords.get(i), i, true); 555 sum += time == -1 ? 0 : time; 556 } 557 Log.d(TAG, "per a search : " + (((double)sum) / sWords.size() / 1000000)); 558 559 // Test a word that isn't contained within the dictionary. 560 final Random random = new Random((int)System.currentTimeMillis()); 561 for (int i = 0; i < 1000; ++i) { 562 final String word = generateWord(random); 563 if (sWords.indexOf(word) != -1) continue; 564 runGetTerminalPosition(buffer, word, i, false); 565 } 566 } 567 568 public void testDeleteWord() { 569 File file = null; 570 try { 571 file = File.createTempFile("testDeleteWord", ".dict", getContext().getCacheDir()); 572 } catch (IOException e) { 573 // do nothing 574 } 575 assertNotNull(file); 576 577 final FusionDictionary dict = new FusionDictionary(new Node(), 578 new FusionDictionary.DictionaryOptions( 579 new HashMap<String, String>(), false, false)); 580 addUnigrams(sWords.size(), dict, sWords, null /* shortcutMap */); 581 timeWritingDictToFile(file, dict, VERSION3_WITH_DYNAMIC_UPDATE); 582 583 final FusionDictionaryBufferInterface buffer = getBuffer(file, USE_BYTE_ARRAY); 584 585 try { 586 MoreAsserts.assertNotEqual(FormatSpec.NOT_VALID_WORD, 587 BinaryDictIOUtils.getTerminalPosition(buffer, sWords.get(0))); 588 BinaryDictIOUtils.deleteWord(buffer, sWords.get(0)); 589 assertEquals(FormatSpec.NOT_VALID_WORD, 590 BinaryDictIOUtils.getTerminalPosition(buffer, sWords.get(0))); 591 592 MoreAsserts.assertNotEqual(FormatSpec.NOT_VALID_WORD, 593 BinaryDictIOUtils.getTerminalPosition(buffer, sWords.get(5))); 594 BinaryDictIOUtils.deleteWord(buffer, sWords.get(5)); 595 assertEquals(FormatSpec.NOT_VALID_WORD, 596 BinaryDictIOUtils.getTerminalPosition(buffer, sWords.get(5))); 597 } catch (IOException e) { 598 } catch (UnsupportedFormatException e) { 599 } 600 } 601 } 602