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

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

Merge "Remove DictionaryUpdateController."

parents 0a774443 07c5b307
Loading
Loading
Loading
Loading
+3 −3
Original line number Original line Diff line number Diff line
@@ -89,8 +89,8 @@ public class ContactsBinaryDictionary extends ExpandableBinaryDictionary {
        registerObserver(context);
        registerObserver(context);


        // Load the current binary dictionary from internal storage. If no binary dictionary exists,
        // Load the current binary dictionary from internal storage. If no binary dictionary exists,
        // loadDictionary will start a new thread to generate one asynchronously.
        // reloadDictionaryIfRequired will start a new thread to generate one asynchronously.
        loadDictionary();
        reloadDictionaryIfRequired();
    }
    }


    private synchronized void registerObserver(final Context context) {
    private synchronized void registerObserver(final Context context) {
@@ -100,7 +100,7 @@ public class ContactsBinaryDictionary extends ExpandableBinaryDictionary {
                new ContentObserver(null) {
                new ContentObserver(null) {
                    @Override
                    @Override
                    public void onChange(boolean self) {
                    public void onChange(boolean self) {
                        setRequiresReload(true);
                        setNeedsToReload();
                    }
                    }
                });
                });
    }
    }
+16 −102
Original line number Original line Diff line number Diff line
@@ -27,7 +27,6 @@ import com.android.inputmethod.latin.makedict.UnsupportedFormatException;
import com.android.inputmethod.latin.makedict.WordProperty;
import com.android.inputmethod.latin.makedict.WordProperty;
import com.android.inputmethod.latin.SuggestedWords.SuggestedWordInfo;
import com.android.inputmethod.latin.SuggestedWords.SuggestedWordInfo;
import com.android.inputmethod.latin.utils.AsyncResultHolder;
import com.android.inputmethod.latin.utils.AsyncResultHolder;
import com.android.inputmethod.latin.utils.CollectionUtils;
import com.android.inputmethod.latin.utils.CombinedFormatUtils;
import com.android.inputmethod.latin.utils.CombinedFormatUtils;
import com.android.inputmethod.latin.utils.ExecutorUtils;
import com.android.inputmethod.latin.utils.ExecutorUtils;
import com.android.inputmethod.latin.utils.FileUtils;
import com.android.inputmethod.latin.utils.FileUtils;
@@ -38,7 +37,6 @@ import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashMap;
import java.util.Locale;
import java.util.Locale;
import java.util.Map;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicBoolean;
@@ -74,15 +72,6 @@ abstract public class ExpandableBinaryDictionary extends Dictionary {


    private static final int DICTIONARY_FORMAT_VERSION = FormatSpec.VERSION4;
    private static final int DICTIONARY_FORMAT_VERSION = FormatSpec.VERSION4;


    /**
     * A static map of update controllers, each of which records the time of accesses to a single
     * binary dictionary file and tracks whether the file is regenerating. The key for this map is
     * the dictionary name  and the value is the shared dictionary time recorder associated with
     * that dictionary name.
     */
    private static final ConcurrentHashMap<String, DictionaryUpdateController>
            sDictNameDictionaryUpdateControllerMap = CollectionUtils.newConcurrentHashMap();

    /** The application context. */
    /** The application context. */
    protected final Context mContext;
    protected final Context mContext;


@@ -105,14 +94,9 @@ abstract public class ExpandableBinaryDictionary extends Dictionary {
    /** Dictionary file */
    /** Dictionary file */
    private final File mDictFile;
    private final File mDictFile;


    // TODO: remove, once dynamic operations is serialized
    private final AtomicBoolean mProcessingLargeTask;
    /** Controls updating the shared binary dictionary file across multiple instances. */
    private boolean mNeedsToReload;
    private final DictionaryUpdateController mDictNameDictionaryUpdateController;


    // TODO: remove, once dynamic operations is serialized
    /** Controls updating the local binary dictionary for this instance. */
    private final DictionaryUpdateController mPerInstanceDictionaryUpdateController =
            new DictionaryUpdateController();


    /* A extension for a binary dictionary file. */
    /* A extension for a binary dictionary file. */
    protected static final String DICT_FILE_EXTENSION = ".dict";
    protected static final String DICT_FILE_EXTENSION = ".dict";
@@ -145,21 +129,6 @@ abstract public class ExpandableBinaryDictionary extends Dictionary {
        return mBinaryDictionary.isValidDictionary();
        return mBinaryDictionary.isValidDictionary();
    }
    }


    /**
     * Gets the dictionary update controller for the given dictionary name.
     */
    private static DictionaryUpdateController getDictionaryUpdateController(
            final String dictName) {
        DictionaryUpdateController recorder = sDictNameDictionaryUpdateControllerMap.get(dictName);
        if (recorder == null) {
            synchronized(sDictNameDictionaryUpdateControllerMap) {
                recorder = new DictionaryUpdateController();
                sDictNameDictionaryUpdateControllerMap.put(dictName, recorder);
            }
        }
        return recorder;
    }

    /**
    /**
     * Creates a new expandable binary dictionary.
     * Creates a new expandable binary dictionary.
     *
     *
@@ -179,7 +148,8 @@ abstract public class ExpandableBinaryDictionary extends Dictionary {
        mLocale = locale;
        mLocale = locale;
        mDictFile = getDictFile(context, dictName, dictFile);
        mDictFile = getDictFile(context, dictName, dictFile);
        mBinaryDictionary = null;
        mBinaryDictionary = null;
        mDictNameDictionaryUpdateController = getDictionaryUpdateController(dictName);
        mProcessingLargeTask = new AtomicBoolean();
        mNeedsToReload = false;
    }
    }


    public static File getDictFile(final Context context, final String dictName,
    public static File getDictFile(final Context context, final String dictName,
@@ -286,7 +256,7 @@ abstract public class ExpandableBinaryDictionary extends Dictionary {
                        try {
                        try {
                            mBinaryDictionary.flushWithGC();
                            mBinaryDictionary.flushWithGC();
                        } finally {
                        } finally {
                            mDictNameDictionaryUpdateController.mProcessingLargeTask.set(false);
                            mProcessingLargeTask.set(false);
                        }
                        }
                    }
                    }
                });
                });
@@ -388,7 +358,7 @@ abstract public class ExpandableBinaryDictionary extends Dictionary {
                        callback.onFinished();
                        callback.onFinished();
                    }
                    }
                    if (locked) {
                    if (locked) {
                        mDictNameDictionaryUpdateController.mProcessingLargeTask.set(false);
                        mProcessingLargeTask.set(false);
                    }
                    }
                }
                }
            }
            }
@@ -461,25 +431,11 @@ abstract public class ExpandableBinaryDictionary extends Dictionary {
        return mBinaryDictionary.isValidBigram(word1, word2);
        return mBinaryDictionary.isValidBigram(word1, word2);
    }
    }


    /**
     * Load the current binary dictionary from internal storage in a background thread. If no binary
     * dictionary exists, this method will generate one.
     */
    protected void loadDictionary() {
        mPerInstanceDictionaryUpdateController.mLastUpdateRequestTime = System.currentTimeMillis();
        reloadDictionaryIfRequired();
    }

    /**
    /**
     * Loads the current binary dictionary from internal storage. Assumes the dictionary file
     * Loads the current binary dictionary from internal storage. Assumes the dictionary file
     * exists.
     * exists.
     */
     */
    private void loadBinaryDictionaryLocked() {
    private void loadBinaryDictionaryLocked() {
        if (DEBUG) {
            Log.d(TAG, "Loading binary dictionary: " + mDictName + " request="
                    + mDictNameDictionaryUpdateController.mLastUpdateRequestTime + " update="
                    + mDictNameDictionaryUpdateController.mLastUpdateTime);
        }
        if (DBG_STRESS_TEST) {
        if (DBG_STRESS_TEST) {
            // Test if this class does not cause problems when it takes long time to load binary
            // Test if this class does not cause problems when it takes long time to load binary
            // dictionary.
            // dictionary.
@@ -505,11 +461,6 @@ abstract public class ExpandableBinaryDictionary extends Dictionary {
     * Create a new binary dictionary and load initial contents.
     * Create a new binary dictionary and load initial contents.
     */
     */
    private void createNewDictionaryLocked() {
    private void createNewDictionaryLocked() {
        if (DEBUG) {
            Log.d(TAG, "Generating binary dictionary: " + mDictName + " request="
                    + mDictNameDictionaryUpdateController.mLastUpdateRequestTime + " update="
                    + mDictNameDictionaryUpdateController.mLastUpdateTime);
        }
        removeBinaryDictionaryLocked();
        removeBinaryDictionaryLocked();
        createOnMemoryBinaryDictionaryLocked();
        createOnMemoryBinaryDictionaryLocked();
        loadInitialContentsLocked();
        loadInitialContentsLocked();
@@ -529,20 +480,11 @@ abstract public class ExpandableBinaryDictionary extends Dictionary {
    }
    }


    /**
    /**
     * Marks that the dictionary is out of date and requires a reload.
     * Marks that the dictionary needs to be reloaded.
     *
     *
     * @param requiresRebuild Indicates that the source dictionary content has changed and a rebuild
     *        of the binary file is required. If not true, the next reload process will only read
     *        the current binary dictionary from file.
     */
     */
    protected void setRequiresReload(final boolean requiresRebuild) {
    protected void setNeedsToReload() {
        final long time = System.currentTimeMillis();
        mNeedsToReload = true;
        mPerInstanceDictionaryUpdateController.mLastUpdateRequestTime = time;
        mDictNameDictionaryUpdateController.mLastUpdateRequestTime = time;
        if (DEBUG) {
            Log.d(TAG, "Reload request: " + mDictName + ": request=" + time + " update="
                    + mDictNameDictionaryUpdateController.mLastUpdateTime);
        }
    }
    }


    /**
    /**
@@ -559,18 +501,17 @@ abstract public class ExpandableBinaryDictionary extends Dictionary {
     * Returns whether a dictionary reload is required.
     * Returns whether a dictionary reload is required.
     */
     */
    private boolean isReloadRequired() {
    private boolean isReloadRequired() {
        return mBinaryDictionary == null || mPerInstanceDictionaryUpdateController.isOutOfDate();
        return mBinaryDictionary == null || mNeedsToReload;
    }
    }


    private boolean processingLargeTask() {
    private boolean processingLargeTask() {
        return mDictNameDictionaryUpdateController.mProcessingLargeTask.get();
        return mProcessingLargeTask.get();
    }
    }


    // Returns whether the dictionary is being used for a large task. If true, we should not use
    // Returns whether the dictionary is being used for a large task. If true, we should not use
    // this dictionary for latency sensitive operations.
    // this dictionary for latency sensitive operations.
    private boolean setProcessingLargeTaskIfNot() {
    private boolean setProcessingLargeTaskIfNot() {
        return mDictNameDictionaryUpdateController.mProcessingLargeTask.compareAndSet(
        return mProcessingLargeTask.compareAndSet(false /* expect */ , true /* update */);
                false /* expect */ , true /* update */);
    }
    }


    /**
    /**
@@ -584,28 +525,17 @@ abstract public class ExpandableBinaryDictionary extends Dictionary {
            @Override
            @Override
            public void run() {
            public void run() {
                try {
                try {
                    final long time = System.currentTimeMillis();
                    if (!dictionaryFileExists() || haveContentsChanged()) {
                    final boolean openedDictIsOutOfDate =
                            mDictNameDictionaryUpdateController.isOutOfDate();
                    if (!dictionaryFileExists()
                            || (openedDictIsOutOfDate && haveContentsChanged())) {
                        // If the shared dictionary file does not exist or is out of date and
                        // If the shared dictionary file does not exist or is out of date and
                        // contents have been updated, the first instance that acquires the lock
                        // contents have been updated, the first instance that acquires the lock
                        // will generate a new one
                        // will generate a new one
                        mDictNameDictionaryUpdateController.mLastUpdateTime = time;
                        createNewDictionaryLocked();
                        createNewDictionaryLocked();
                    } else if (openedDictIsOutOfDate) {
                    } else if (mBinaryDictionary == null) {
                        // If not, the reload request was unnecessary so revert
                        // LastUpdateRequestTime to LastUpdateTime.
                        mDictNameDictionaryUpdateController.mLastUpdateRequestTime =
                                mDictNameDictionaryUpdateController.mLastUpdateTime;
                    } else if (mBinaryDictionary == null ||
                            mPerInstanceDictionaryUpdateController.mLastUpdateTime
                                    < mDictNameDictionaryUpdateController.mLastUpdateTime) {
                        // Otherwise, if the local dictionary is older than the shared dictionary,
                        // Otherwise, if the local dictionary is older than the shared dictionary,
                        // load the shared dictionary.
                        // load the shared dictionary.
                        loadBinaryDictionaryLocked();
                        loadBinaryDictionaryLocked();
                    }
                    }
                    mNeedsToReload = false;
                    if (mBinaryDictionary != null && !(isValidDictionaryLocked()
                    if (mBinaryDictionary != null && !(isValidDictionaryLocked()
                            // TODO: remove the check below
                            // TODO: remove the check below
                            && matchesExpectedBinaryDictFormatVersionForThisType(
                            && matchesExpectedBinaryDictFormatVersionForThisType(
@@ -613,12 +543,10 @@ abstract public class ExpandableBinaryDictionary extends Dictionary {
                        // Binary dictionary or its format version is not valid. Regenerate
                        // Binary dictionary or its format version is not valid. Regenerate
                        // the dictionary file. writeBinaryDictionary will remove the
                        // the dictionary file. writeBinaryDictionary will remove the
                        // existing files if appropriate.
                        // existing files if appropriate.
                        mDictNameDictionaryUpdateController.mLastUpdateTime = time;
                        createNewDictionaryLocked();
                        createNewDictionaryLocked();
                    }
                    }
                    mPerInstanceDictionaryUpdateController.mLastUpdateTime = time;
                } finally {
                } finally {
                    mDictNameDictionaryUpdateController.mProcessingLargeTask.set(false);
                    mProcessingLargeTask.set(false);
                }
                }
            }
            }
        });
        });
@@ -643,20 +571,6 @@ abstract public class ExpandableBinaryDictionary extends Dictionary {
        ExecutorUtils.getExecutor(mDictName).replaceAndExecute(oldTask, newTask);
        ExecutorUtils.getExecutor(mDictName).replaceAndExecute(oldTask, newTask);
    }
    }


    /**
     * For tracking whether the dictionary is out of date and the dictionary is used in a large
     * task. Can be shared across multiple dictionary instances that access the same filename.
     */
    private static class DictionaryUpdateController {
        public volatile long mLastUpdateTime = 0;
        public volatile long mLastUpdateRequestTime = 0;
        public volatile AtomicBoolean mProcessingLargeTask = new AtomicBoolean();

        public boolean isOutOfDate() {
            return (mLastUpdateRequestTime > mLastUpdateTime);
        }
    }

    // TODO: Implement BinaryDictionary.isInDictionary().
    // TODO: Implement BinaryDictionary.isInDictionary().
    @UsedForTesting
    @UsedForTesting
    public boolean isInUnderlyingBinaryDictionaryForTests(final String word) {
    public boolean isInUnderlyingBinaryDictionaryForTests(final String word) {
+2 −2
Original line number Original line Diff line number Diff line
@@ -116,12 +116,12 @@ public class UserBinaryDictionary extends ExpandableBinaryDictionary {
            // devices. On older versions of the platform, the hook above will be called instead.
            // devices. On older versions of the platform, the hook above will be called instead.
            @Override
            @Override
            public void onChange(final boolean self, final Uri uri) {
            public void onChange(final boolean self, final Uri uri) {
                setRequiresReload(true);
                setNeedsToReload();
            }
            }
        };
        };
        cres.registerContentObserver(Words.CONTENT_URI, true, mObserver);
        cres.registerContentObserver(Words.CONTENT_URI, true, mObserver);
        mEnabled = readIsEnabled();
        mEnabled = readIsEnabled();
        loadDictionary();
        reloadDictionaryIfRequired();
    }
    }


    @Override
    @Override