Loading java/src/com/android/inputmethod/latin/DictionaryFactory.java +15 −16 Original line number Diff line number Diff line Loading @@ -51,7 +51,7 @@ public final class DictionaryFactory { if (null == locale) { Log.e(TAG, "No locale defined for dictionary"); return new DictionaryCollection(Dictionary.TYPE_MAIN, createBinaryDictionary(context, locale)); createReadOnlyBinaryDictionary(context, locale)); } final LinkedList<Dictionary> dictList = CollectionUtils.newLinkedList(); Loading @@ -59,11 +59,11 @@ public final class DictionaryFactory { BinaryDictionaryGetter.getDictionaryFiles(locale, context); if (null != assetFileList) { for (final AssetFileAddress f : assetFileList) { final BinaryDictionary binaryDictionary = new BinaryDictionary(f.mFilename, f.mOffset, f.mLength, useFullEditDistance, locale, Dictionary.TYPE_MAIN, false /* isUpdatable */); if (binaryDictionary.isValidDictionary()) { dictList.add(binaryDictionary); final ReadOnlyBinaryDictionary readOnlyBinaryDictionary = new ReadOnlyBinaryDictionary(f.mFilename, f.mOffset, f.mLength, useFullEditDistance, locale, Dictionary.TYPE_MAIN); if (readOnlyBinaryDictionary.isValidDictionary()) { dictList.add(readOnlyBinaryDictionary); } } } Loading @@ -89,12 +89,12 @@ public final class DictionaryFactory { } /** * Initializes a dictionary from a raw resource file * Initializes a read-only binary dictionary from a raw resource file * @param context application context for reading resources * @param locale the locale to use for the resource * @return an initialized instance of BinaryDictionary * @return an initialized instance of ReadOnlyBinaryDictionary */ protected static BinaryDictionary createBinaryDictionary(final Context context, protected static ReadOnlyBinaryDictionary createReadOnlyBinaryDictionary(final Context context, final Locale locale) { AssetFileDescriptor afd = null; try { Loading @@ -113,9 +113,8 @@ public final class DictionaryFactory { Log.e(TAG, "sourceDir is not a file: " + sourceDir); return null; } return new BinaryDictionary(sourceDir, afd.getStartOffset(), afd.getLength(), false /* useFullEditDistance */, locale, Dictionary.TYPE_MAIN, false /* isUpdatable */); return new ReadOnlyBinaryDictionary(sourceDir, afd.getStartOffset(), afd.getLength(), false /* useFullEditDistance */, locale, Dictionary.TYPE_MAIN); } catch (android.content.res.Resources.NotFoundException e) { Log.e(TAG, "Could not find the resource"); return null; Loading @@ -142,10 +141,10 @@ public final class DictionaryFactory { final DictionaryCollection dictionaryCollection = new DictionaryCollection(Dictionary.TYPE_MAIN); for (final AssetFileAddress address : dictionaryList) { final BinaryDictionary binaryDictionary = new BinaryDictionary(address.mFilename, address.mOffset, address.mLength, useFullEditDistance, locale, Dictionary.TYPE_MAIN, false /* isUpdatable */); dictionaryCollection.addDictionary(binaryDictionary); final ReadOnlyBinaryDictionary readOnlyBinaryDictionary = new ReadOnlyBinaryDictionary( address.mFilename, address.mOffset, address.mLength, useFullEditDistance, locale, Dictionary.TYPE_MAIN); dictionaryCollection.addDictionary(readOnlyBinaryDictionary); } return dictionaryCollection; } Loading java/src/com/android/inputmethod/latin/ReadOnlyBinaryDictionary.java 0 → 100644 +120 −0 Original line number Diff line number Diff line /* * Copyright (C) 2013 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.android.inputmethod.latin; import com.android.inputmethod.keyboard.ProximityInfo; import com.android.inputmethod.latin.SuggestedWords.SuggestedWordInfo; import java.util.ArrayList; import java.util.Locale; import java.util.concurrent.locks.ReentrantReadWriteLock; /** * This class provides binary dictionary reading operations with locking. An instance of this class * can be used by multiple threads. Note that different session IDs must be used when multiple * threads get suggestions using this class. */ public final class ReadOnlyBinaryDictionary extends Dictionary { /** * A lock for accessing binary dictionary. Only closing binary dictionary is the operation * that change the state of dictionary. */ private final ReentrantReadWriteLock mLock = new ReentrantReadWriteLock(); private final BinaryDictionary mBinaryDictionary; public ReadOnlyBinaryDictionary(final String filename, final long offset, final long length, final boolean useFullEditDistance, final Locale locale, final String dictType) { super(dictType); mBinaryDictionary = new BinaryDictionary(filename, offset, length, useFullEditDistance, locale, dictType, false /* isUpdatable */); } public boolean isValidDictionary() { return mBinaryDictionary.isValidDictionary(); } @Override public ArrayList<SuggestedWordInfo> getSuggestions(final WordComposer composer, final String prevWord, final ProximityInfo proximityInfo, final boolean blockOffensiveWords, final int[] additionalFeaturesOptions) { return getSuggestionsWithSessionId(composer, prevWord, proximityInfo, blockOffensiveWords, additionalFeaturesOptions, 0 /* sessionId */); } @Override public ArrayList<SuggestedWordInfo> getSuggestionsWithSessionId(final WordComposer composer, final String prevWord, final ProximityInfo proximityInfo, final boolean blockOffensiveWords, final int[] additionalFeaturesOptions, final int sessionId) { if (mLock.readLock().tryLock()) { try { return mBinaryDictionary.getSuggestions(composer, prevWord, proximityInfo, blockOffensiveWords, additionalFeaturesOptions); } finally { mLock.readLock().unlock(); } } return null; } @Override public boolean isValidWord(final String word) { if (mLock.readLock().tryLock()) { try { return mBinaryDictionary.isValidWord(word); } finally { mLock.readLock().unlock(); } } return false; } @Override public boolean shouldAutoCommit(final SuggestedWordInfo candidate) { if (mLock.readLock().tryLock()) { try { return mBinaryDictionary.shouldAutoCommit(candidate); } finally { mLock.readLock().unlock(); } } return false; } @Override public int getFrequency(final String word) { if (mLock.readLock().tryLock()) { try { return mBinaryDictionary.getFrequency(word); } finally { mLock.readLock().unlock(); } } return NOT_A_PROBABILITY; } @Override public void close() { mLock.writeLock().lock(); try { mBinaryDictionary.close(); } finally { mLock.writeLock().unlock(); } } } Loading
java/src/com/android/inputmethod/latin/DictionaryFactory.java +15 −16 Original line number Diff line number Diff line Loading @@ -51,7 +51,7 @@ public final class DictionaryFactory { if (null == locale) { Log.e(TAG, "No locale defined for dictionary"); return new DictionaryCollection(Dictionary.TYPE_MAIN, createBinaryDictionary(context, locale)); createReadOnlyBinaryDictionary(context, locale)); } final LinkedList<Dictionary> dictList = CollectionUtils.newLinkedList(); Loading @@ -59,11 +59,11 @@ public final class DictionaryFactory { BinaryDictionaryGetter.getDictionaryFiles(locale, context); if (null != assetFileList) { for (final AssetFileAddress f : assetFileList) { final BinaryDictionary binaryDictionary = new BinaryDictionary(f.mFilename, f.mOffset, f.mLength, useFullEditDistance, locale, Dictionary.TYPE_MAIN, false /* isUpdatable */); if (binaryDictionary.isValidDictionary()) { dictList.add(binaryDictionary); final ReadOnlyBinaryDictionary readOnlyBinaryDictionary = new ReadOnlyBinaryDictionary(f.mFilename, f.mOffset, f.mLength, useFullEditDistance, locale, Dictionary.TYPE_MAIN); if (readOnlyBinaryDictionary.isValidDictionary()) { dictList.add(readOnlyBinaryDictionary); } } } Loading @@ -89,12 +89,12 @@ public final class DictionaryFactory { } /** * Initializes a dictionary from a raw resource file * Initializes a read-only binary dictionary from a raw resource file * @param context application context for reading resources * @param locale the locale to use for the resource * @return an initialized instance of BinaryDictionary * @return an initialized instance of ReadOnlyBinaryDictionary */ protected static BinaryDictionary createBinaryDictionary(final Context context, protected static ReadOnlyBinaryDictionary createReadOnlyBinaryDictionary(final Context context, final Locale locale) { AssetFileDescriptor afd = null; try { Loading @@ -113,9 +113,8 @@ public final class DictionaryFactory { Log.e(TAG, "sourceDir is not a file: " + sourceDir); return null; } return new BinaryDictionary(sourceDir, afd.getStartOffset(), afd.getLength(), false /* useFullEditDistance */, locale, Dictionary.TYPE_MAIN, false /* isUpdatable */); return new ReadOnlyBinaryDictionary(sourceDir, afd.getStartOffset(), afd.getLength(), false /* useFullEditDistance */, locale, Dictionary.TYPE_MAIN); } catch (android.content.res.Resources.NotFoundException e) { Log.e(TAG, "Could not find the resource"); return null; Loading @@ -142,10 +141,10 @@ public final class DictionaryFactory { final DictionaryCollection dictionaryCollection = new DictionaryCollection(Dictionary.TYPE_MAIN); for (final AssetFileAddress address : dictionaryList) { final BinaryDictionary binaryDictionary = new BinaryDictionary(address.mFilename, address.mOffset, address.mLength, useFullEditDistance, locale, Dictionary.TYPE_MAIN, false /* isUpdatable */); dictionaryCollection.addDictionary(binaryDictionary); final ReadOnlyBinaryDictionary readOnlyBinaryDictionary = new ReadOnlyBinaryDictionary( address.mFilename, address.mOffset, address.mLength, useFullEditDistance, locale, Dictionary.TYPE_MAIN); dictionaryCollection.addDictionary(readOnlyBinaryDictionary); } return dictionaryCollection; } Loading
java/src/com/android/inputmethod/latin/ReadOnlyBinaryDictionary.java 0 → 100644 +120 −0 Original line number Diff line number Diff line /* * Copyright (C) 2013 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.android.inputmethod.latin; import com.android.inputmethod.keyboard.ProximityInfo; import com.android.inputmethod.latin.SuggestedWords.SuggestedWordInfo; import java.util.ArrayList; import java.util.Locale; import java.util.concurrent.locks.ReentrantReadWriteLock; /** * This class provides binary dictionary reading operations with locking. An instance of this class * can be used by multiple threads. Note that different session IDs must be used when multiple * threads get suggestions using this class. */ public final class ReadOnlyBinaryDictionary extends Dictionary { /** * A lock for accessing binary dictionary. Only closing binary dictionary is the operation * that change the state of dictionary. */ private final ReentrantReadWriteLock mLock = new ReentrantReadWriteLock(); private final BinaryDictionary mBinaryDictionary; public ReadOnlyBinaryDictionary(final String filename, final long offset, final long length, final boolean useFullEditDistance, final Locale locale, final String dictType) { super(dictType); mBinaryDictionary = new BinaryDictionary(filename, offset, length, useFullEditDistance, locale, dictType, false /* isUpdatable */); } public boolean isValidDictionary() { return mBinaryDictionary.isValidDictionary(); } @Override public ArrayList<SuggestedWordInfo> getSuggestions(final WordComposer composer, final String prevWord, final ProximityInfo proximityInfo, final boolean blockOffensiveWords, final int[] additionalFeaturesOptions) { return getSuggestionsWithSessionId(composer, prevWord, proximityInfo, blockOffensiveWords, additionalFeaturesOptions, 0 /* sessionId */); } @Override public ArrayList<SuggestedWordInfo> getSuggestionsWithSessionId(final WordComposer composer, final String prevWord, final ProximityInfo proximityInfo, final boolean blockOffensiveWords, final int[] additionalFeaturesOptions, final int sessionId) { if (mLock.readLock().tryLock()) { try { return mBinaryDictionary.getSuggestions(composer, prevWord, proximityInfo, blockOffensiveWords, additionalFeaturesOptions); } finally { mLock.readLock().unlock(); } } return null; } @Override public boolean isValidWord(final String word) { if (mLock.readLock().tryLock()) { try { return mBinaryDictionary.isValidWord(word); } finally { mLock.readLock().unlock(); } } return false; } @Override public boolean shouldAutoCommit(final SuggestedWordInfo candidate) { if (mLock.readLock().tryLock()) { try { return mBinaryDictionary.shouldAutoCommit(candidate); } finally { mLock.readLock().unlock(); } } return false; } @Override public int getFrequency(final String word) { if (mLock.readLock().tryLock()) { try { return mBinaryDictionary.getFrequency(word); } finally { mLock.readLock().unlock(); } } return NOT_A_PROBABILITY; } @Override public void close() { mLock.writeLock().lock(); try { mBinaryDictionary.close(); } finally { mLock.writeLock().unlock(); } } }