1/*
2 * Copyright (C) 2013 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
17package com.android.inputmethod.latin;
18
19import com.android.inputmethod.keyboard.ProximityInfo;
20import com.android.inputmethod.latin.SuggestedWords.SuggestedWordInfo;
21
22import java.util.ArrayList;
23import java.util.Locale;
24import java.util.concurrent.locks.ReentrantReadWriteLock;
25
26/**
27 * This class provides binary dictionary reading operations with locking. An instance of this class
28 * can be used by multiple threads. Note that different session IDs must be used when multiple
29 * threads get suggestions using this class.
30 */
31public final class ReadOnlyBinaryDictionary extends Dictionary {
32    /**
33     * A lock for accessing binary dictionary. Only closing binary dictionary is the operation
34     * that change the state of dictionary.
35     */
36    private final ReentrantReadWriteLock mLock = new ReentrantReadWriteLock();
37
38    private final BinaryDictionary mBinaryDictionary;
39
40    public ReadOnlyBinaryDictionary(final String filename, final long offset, final long length,
41            final boolean useFullEditDistance, final Locale locale, final String dictType) {
42        super(dictType);
43        mBinaryDictionary = new BinaryDictionary(filename, offset, length, useFullEditDistance,
44                locale, dictType, false /* isUpdatable */);
45    }
46
47    public boolean isValidDictionary() {
48        return mBinaryDictionary.isValidDictionary();
49    }
50
51    @Override
52    public ArrayList<SuggestedWordInfo> getSuggestions(final WordComposer composer,
53            final String prevWord, final ProximityInfo proximityInfo,
54            final boolean blockOffensiveWords, final int[] additionalFeaturesOptions) {
55        return getSuggestionsWithSessionId(composer, prevWord, proximityInfo, blockOffensiveWords,
56                additionalFeaturesOptions, 0 /* sessionId */);
57    }
58
59    @Override
60    public ArrayList<SuggestedWordInfo> getSuggestionsWithSessionId(final WordComposer composer,
61            final String prevWord, final ProximityInfo proximityInfo,
62            final boolean blockOffensiveWords, final int[] additionalFeaturesOptions,
63            final int sessionId) {
64        if (mLock.readLock().tryLock()) {
65            try {
66                return mBinaryDictionary.getSuggestions(composer, prevWord, proximityInfo,
67                        blockOffensiveWords, additionalFeaturesOptions);
68            } finally {
69                mLock.readLock().unlock();
70            }
71        }
72        return null;
73    }
74
75    @Override
76    public boolean isValidWord(final String word) {
77        if (mLock.readLock().tryLock()) {
78            try {
79                return mBinaryDictionary.isValidWord(word);
80            } finally {
81                mLock.readLock().unlock();
82            }
83        }
84        return false;
85    }
86
87    @Override
88    public boolean shouldAutoCommit(final SuggestedWordInfo candidate) {
89        if (mLock.readLock().tryLock()) {
90            try {
91                return mBinaryDictionary.shouldAutoCommit(candidate);
92            } finally {
93                mLock.readLock().unlock();
94            }
95        }
96        return false;
97    }
98
99    @Override
100    public int getFrequency(final String word) {
101        if (mLock.readLock().tryLock()) {
102            try {
103                return mBinaryDictionary.getFrequency(word);
104            } finally {
105                mLock.readLock().unlock();
106            }
107        }
108        return NOT_A_PROBABILITY;
109    }
110
111    @Override
112    public void close() {
113        mLock.writeLock().lock();
114        try {
115            mBinaryDictionary.close();
116        } finally {
117            mLock.writeLock().unlock();
118        }
119    }
120}
121