Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 78ab1bb6 authored by Keisuke Kuroyanagi's avatar Keisuke Kuroyanagi Committed by Android (Google) Code Review
Browse files

Merge "Make DynamicPred...Base extend ExpandableBinaryDictionary."

parents d5a3c593 6e04d659
Loading
Loading
Loading
Loading
+80 −4
Original line number Diff line number Diff line
@@ -29,6 +29,7 @@ import com.android.inputmethod.latin.utils.CollectionUtils;
import java.io.File;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.concurrent.atomic.AtomicReference;
import java.util.concurrent.locks.ReentrantReadWriteLock;

/**
@@ -92,6 +93,9 @@ abstract public class ExpandableBinaryDictionary extends Dictionary {
    /* A extension for a binary dictionary file. */
    public static final String DICT_FILE_EXTENSION = ".dict";

    private final AtomicReference<AsyncWriteBinaryDictionaryTask> mWaitingTask =
            new AtomicReference<AsyncWriteBinaryDictionaryTask>();

    /**
     * Abstract method for loading the unigrams and bigrams of a given dictionary in a background
     * thread.
@@ -180,6 +184,15 @@ abstract public class ExpandableBinaryDictionary extends Dictionary {
        }
    }

    protected void clear() {
        mLocalDictionaryController.writeLock().lock();
        try {
            mDictionaryWriter.clear();
        } finally {
            mLocalDictionaryController.writeLock().unlock();
        }
    }

    /**
     * Adds a word unigram to the dictionary. Used for loading a dictionary.
     */
@@ -267,7 +280,8 @@ abstract public class ExpandableBinaryDictionary extends Dictionary {
                final ArrayList<SuggestedWordInfo> inMemDictSuggestion =
                        mDictionaryWriter.getSuggestions(composer, prevWord, proximityInfo,
                                blockOffensiveWords);
                if (mBinaryDictionary != null) {
                // TODO: Remove checking mIsUpdatable and use native suggestion.
                if (mBinaryDictionary != null && !mIsUpdatable) {
                    final ArrayList<SuggestedWordInfo> binarySuggestion =
                            mBinaryDictionary.getSuggestions(composer, prevWord, proximityInfo,
                                    blockOffensiveWords);
@@ -276,7 +290,7 @@ abstract public class ExpandableBinaryDictionary extends Dictionary {
                    } else if (binarySuggestion == null) {
                        return inMemDictSuggestion;
                    } else {
                        binarySuggestion.addAll(binarySuggestion);
                        binarySuggestion.addAll(inMemDictSuggestion);
                        return binarySuggestion;
                    }
                } else {
@@ -402,7 +416,7 @@ abstract public class ExpandableBinaryDictionary extends Dictionary {
    /**
     * Reloads the dictionary if required. Reload will occur asynchronously in a separate thread.
     */
    void asyncReloadDictionaryIfRequired() {
    public void asyncReloadDictionaryIfRequired() {
        if (!isReloadRequired()) return;
        if (DEBUG) {
            Log.d(TAG, "Starting AsyncReloadDictionaryTask: " + mFilename);
@@ -413,7 +427,7 @@ abstract public class ExpandableBinaryDictionary extends Dictionary {
    /**
     * Reloads the dictionary if required.
     */
    protected final void syncReloadDictionaryIfRequired() {
    public final void syncReloadDictionaryIfRequired() {
        if (!isReloadRequired()) return;
        syncReloadDictionaryInternal();
    }
@@ -492,6 +506,68 @@ abstract public class ExpandableBinaryDictionary extends Dictionary {
        }
    }

    /**
     * Load the dictionary to memory.
     */
    protected void asyncLoadDictionaryToMemory() {
        new AsyncLoadDictionaryToMemoryTask().start();
    }

    /**
     * Thread class for asynchronously loading dictionary to memory.
     */
    private class AsyncLoadDictionaryToMemoryTask extends Thread {
        @Override
        public void run() {
            mLocalDictionaryController.writeLock().lock();
            try {
                mSharedDictionaryController.readLock().lock();
                try {
                    loadDictionaryAsync();
                } finally {
                    mSharedDictionaryController.readLock().unlock();
                }
            } finally {
                mLocalDictionaryController.writeLock().unlock();
            }
        }
    }

    /**
     * Generate binary dictionary using DictionaryWriter.
     */
    protected void asyncWriteBinaryDictionary() {
        final AsyncWriteBinaryDictionaryTask newTask = new AsyncWriteBinaryDictionaryTask();
        newTask.start();
        final AsyncWriteBinaryDictionaryTask oldTask = mWaitingTask.getAndSet(newTask);
        if (oldTask != null) {
            oldTask.interrupt();
        }
    }

    /**
     * Thread class for asynchronously writing the binary dictionary.
     */
    private class AsyncWriteBinaryDictionaryTask extends Thread {
        @Override
        public void run() {
            mSharedDictionaryController.writeLock().lock();
            try {
                mLocalDictionaryController.writeLock().lock();
                try {
                    if (isInterrupted()) {
                        return;
                    }
                    writeBinaryDictionary();
                } finally {
                    mLocalDictionaryController.writeLock().unlock();
                }
            } finally {
                mSharedDictionaryController.writeLock().unlock();
            }
        }
    }

    /**
     * Lock for controlling access to a given binary dictionary and for tracking whether the
     * dictionary is out of date. Can be shared across multiple dictionary instances that access the
+6 −79
Original line number Diff line number Diff line
@@ -16,7 +16,6 @@

package com.android.inputmethod.latin;

import android.content.Context;
import android.text.TextUtils;
import android.util.Log;

@@ -30,9 +29,10 @@ import java.util.ArrayList;
import java.util.LinkedList;

/**
 * Base class for an in-memory dictionary that can grow dynamically and can
 * Class for an in-memory dictionary that can grow dynamically and can
 * be searched for suggestions and valid words.
 */
// TODO: Remove after binary dictionary supports dynamic update.
public class ExpandableDictionary extends Dictionary {
    private static final String TAG = ExpandableDictionary.class.getSimpleName();
    /**
@@ -40,23 +40,11 @@ public class ExpandableDictionary extends Dictionary {
     */
    private static final int FULL_WORD_SCORE_MULTIPLIER = 2;

    // Bigram frequency is a fixed point number with 1 meaning 1.2 and 255 meaning 1.8.
    protected static final int BIGRAM_MAX_FREQUENCY = 255;

    private Context mContext;
    private char[] mWordBuilder = new char[Constants.DICTIONARY_MAX_WORD_LENGTH];
    private int mMaxDepth;
    private int mInputLength;

    private boolean mRequiresReload;

    private boolean mUpdatingDictionary;

    // Use this lock before touching mUpdatingDictionary & mRequiresDownload
    private Object mUpdatingLock = new Object();

    private static final class Node {
        Node() {}
        char mCode;
        int mFrequency;
        boolean mTerminal;
@@ -158,46 +146,12 @@ public class ExpandableDictionary extends Dictionary {

    private int[][] mCodes;

    public ExpandableDictionary(final Context context, final String dictType) {
    public ExpandableDictionary(final String dictType) {
        super(dictType);
        mContext = context;
        clearDictionary();
        mCodes = new int[Constants.DICTIONARY_MAX_WORD_LENGTH][];
    }

    public void loadDictionary() {
        synchronized (mUpdatingLock) {
            startDictionaryLoadingTaskLocked();
        }
    }

    public void startDictionaryLoadingTaskLocked() {
        if (!mUpdatingDictionary) {
            mUpdatingDictionary = true;
            mRequiresReload = false;
            new LoadDictionaryTask().start();
        }
    }

    public void setRequiresReload(final boolean reload) {
        synchronized (mUpdatingLock) {
            mRequiresReload = reload;
        }
    }

    public boolean getRequiresReload() {
        return mRequiresReload;
    }

    /** Override to load your dictionary here, on a background thread. */
    public void loadDictionaryAsync() {
        // empty base implementation
    }

    public Context getContext() {
        return mContext;
    }

    public int getMaxWordLength() {
        return Constants.DICTIONARY_MAX_WORD_LENGTH;
    }
@@ -257,7 +211,6 @@ public class ExpandableDictionary extends Dictionary {
    public ArrayList<SuggestedWordInfo> getSuggestions(final WordComposer composer,
            final String prevWord, final ProximityInfo proximityInfo,
            final boolean blockOffensiveWords) {
        if (reloadDictionaryIfRequired()) return null;
        if (composer.size() > 1) {
            if (composer.size() >= Constants.DICTIONARY_MAX_WORD_LENGTH) {
                return null;
@@ -273,17 +226,7 @@ public class ExpandableDictionary extends Dictionary {
        }
    }

    // This reloads the dictionary if required, and returns whether it's currently updating its
    // contents or not.
    private boolean reloadDictionaryIfRequired() {
        synchronized (mUpdatingLock) {
            // If we need to update, start off a background task
            if (mRequiresReload) startDictionaryLoadingTaskLocked();
            return mUpdatingDictionary;
        }
    }

    protected ArrayList<SuggestedWordInfo> getWordsInner(final WordComposer codes,
    private ArrayList<SuggestedWordInfo> getWordsInner(final WordComposer codes,
            final String prevWordForBigrams, final ProximityInfo proximityInfo) {
        final ArrayList<SuggestedWordInfo> suggestions = CollectionUtils.newArrayList();
        mInputLength = codes.size();
@@ -313,11 +256,6 @@ public class ExpandableDictionary extends Dictionary {

    @Override
    public synchronized boolean isValidWord(final String word) {
        synchronized (mUpdatingLock) {
            // If we need to update, start off a background task
            if (mRequiresReload) startDictionaryLoadingTaskLocked();
            if (mUpdatingDictionary) return false;
        }
        final Node node = searchNode(mRoots, word, 0, word.length());
        // If node is null, we didn't find the word, so it's not valid.
        // If node.mShortcutOnly is true, then it exists as a shortcut but not as a word,
@@ -353,7 +291,7 @@ public class ExpandableDictionary extends Dictionary {
     * Returns the word's frequency or -1 if not found
     */
    @UsedForTesting
    protected int getWordFrequency(final String word) {
    public int getWordFrequency(final String word) {
        // Case-sensitive search
        final Node node = searchNode(mRoots, word, 0, word.length());
        return (node == null) ? -1 : node.mFrequency;
@@ -442,7 +380,7 @@ public class ExpandableDictionary extends Dictionary {
     * @param suggestions the list in which to add suggestions
     */
    // TODO: Share this routine with the native code for BinaryDictionary
    protected void getWordsRec(final NodeArray roots, final WordComposer codes, final char[] word,
    private void getWordsRec(final NodeArray roots, final WordComposer codes, final char[] word,
            final int depth, final boolean completion, final int snr, final int inputIndex,
            final int skipPos, final ArrayList<SuggestedWordInfo> suggestions) {
        final int count = roots.mLength;
@@ -704,17 +642,6 @@ public class ExpandableDictionary extends Dictionary {
        mRoots = new NodeArray();
    }

    private final class LoadDictionaryTask extends Thread {
        LoadDictionaryTask() {}
        @Override
        public void run() {
            loadDictionaryAsync();
            synchronized (mUpdatingLock) {
                mUpdatingDictionary = false;
            }
        }
    }

    private static char toLowerCase(final char c) {
        char baseChar = c;
        if (c < BASE_CHARS.length) {
+4 −4
Original line number Diff line number Diff line
@@ -74,8 +74,8 @@ import com.android.inputmethod.keyboard.MainKeyboardView;
import com.android.inputmethod.latin.SuggestedWords.SuggestedWordInfo;
import com.android.inputmethod.latin.define.ProductionFlag;
import com.android.inputmethod.latin.personalization.PersonalizationDictionary;
import com.android.inputmethod.latin.personalization.PersonalizationDictionaryHelper;
import com.android.inputmethod.latin.personalization.PersonalizationDictionarySessionRegister;
import com.android.inputmethod.latin.personalization.PersonalizationHelper;
import com.android.inputmethod.latin.personalization.PersonalizationPredictionDictionary;
import com.android.inputmethod.latin.personalization.UserHistoryPredictionDictionary;
import com.android.inputmethod.latin.settings.Settings;
@@ -566,13 +566,13 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen

        final SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this);

        mUserHistoryPredictionDictionary = PersonalizationDictionaryHelper
        mUserHistoryPredictionDictionary = PersonalizationHelper
                .getUserHistoryPredictionDictionary(this, localeStr, prefs);
        newSuggest.setUserHistoryPredictionDictionary(mUserHistoryPredictionDictionary);
        mPersonalizationDictionary = PersonalizationDictionaryHelper
        mPersonalizationDictionary = PersonalizationHelper
                .getPersonalizationDictionary(this, localeStr, prefs);
        newSuggest.setPersonalizationDictionary(mPersonalizationDictionary);
        mPersonalizationPredictionDictionary = PersonalizationDictionaryHelper
        mPersonalizationPredictionDictionary = PersonalizationHelper
                .getPersonalizationPredictionDictionary(this, localeStr, prefs);
        newSuggest.setPersonalizationPredictionDictionary(mPersonalizationPredictionDictionary);

+1 −1
Original line number Diff line number Diff line
@@ -55,7 +55,7 @@ public class DynamicPersonalizationDictionaryWriter extends AbstractDictionaryWr

    public DynamicPersonalizationDictionaryWriter(final Context context, final String dictType) {
        super(context, dictType);
        mExpandableDictionary = new ExpandableDictionary(context, dictType);
        mExpandableDictionary = new ExpandableDictionary(dictType);
    }

    @Override
+52 −247

File changed.

Preview size limit exceeded, changes collapsed.

Loading