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

Commit a8c13e79 authored by Satoshi Kataoka's avatar Satoshi Kataoka
Browse files

Avoid redundant access to DB

Bug: 6603257
Change-Id: I2e8017f9e2e222aeab0a80faa239ce83d3b212ad
parent fe824948
Loading
Loading
Loading
Loading
+52 −38
Original line number Diff line number Diff line
@@ -72,10 +72,10 @@ public class UserHistoryDictionary extends ExpandableDictionary {
    private static final String FREQ_TABLE_NAME = "frequency";
    private static final String FREQ_COLUMN_ID = BaseColumns._ID;
    private static final String FREQ_COLUMN_PAIR_ID = "pair_id";
    private static final String FREQ_COLUMN_FREQUENCY = "freq";
    private static final String COLUMN_FORGETTING_CURVE_VALUE = "freq";

    /** Locale for which this auto dictionary is storing words */
    private String mLocale;
    /** Locale for which this user history dictionary is storing words */
    private final String mLocale;

    private UserHistoryDictionaryBigramList mBigramList =
            new UserHistoryDictionaryBigramList();
@@ -94,7 +94,7 @@ public class UserHistoryDictionary extends ExpandableDictionary {

        sDictProjectionMap.put(FREQ_COLUMN_ID, FREQ_COLUMN_ID);
        sDictProjectionMap.put(FREQ_COLUMN_PAIR_ID, FREQ_COLUMN_PAIR_ID);
        sDictProjectionMap.put(FREQ_COLUMN_FREQUENCY, FREQ_COLUMN_FREQUENCY);
        sDictProjectionMap.put(COLUMN_FORGETTING_CURVE_VALUE, COLUMN_FORGETTING_CURVE_VALUE);
    }

    private static DatabaseHelper sOpenHelper = null;
@@ -214,25 +214,26 @@ public class UserHistoryDictionary extends ExpandableDictionary {
            if (cursor.moveToFirst()) {
                final int word1Index = cursor.getColumnIndex(MAIN_COLUMN_WORD1);
                final int word2Index = cursor.getColumnIndex(MAIN_COLUMN_WORD2);
                final int frequencyIndex = cursor.getColumnIndex(FREQ_COLUMN_FREQUENCY);
                final int fcIndex = cursor.getColumnIndex(COLUMN_FORGETTING_CURVE_VALUE);
                while (!cursor.isAfterLast()) {
                    final String word1 = cursor.getString(word1Index);
                    final String word2 = cursor.getString(word2Index);
                    final int frequency = cursor.getInt(frequencyIndex);
                    final int fc = cursor.getInt(fcIndex);
                    if (DBG_SAVE_RESTORE) {
                        Log.d(TAG, "--- Load user history: " + word1 + ", " + word2);
                        Log.d(TAG, "--- Load user history: " + word1 + ", " + word2 + ","
                                + mLocale + "," + this);
                    }
                    // Safeguard against adding really long words. Stack may overflow due
                    // to recursive lookup
                    if (null == word1) {
                        super.addWord(word2, null /* shortcut */, frequency);
                        super.addWord(word2, null /* shortcut */, fc);
                    } else if (word1.length() < BinaryDictionary.MAX_WORD_LENGTH
                            && word2.length() < BinaryDictionary.MAX_WORD_LENGTH) {
                        super.setBigramAndGetFrequency(
                                word1, word2, new ForgettingCurveParams(frequency, now, last));
                                word1, word2, new ForgettingCurveParams(fc, now, last));
                    }
                    synchronized(mPendingWritesLock) {
                        mBigramList.addBigram(word1, word2);
                        mBigramList.addBigram(word1, word2, (byte)fc);
                    }
                    cursor.moveToNext();
                }
@@ -259,7 +260,8 @@ public class UserHistoryDictionary extends ExpandableDictionary {
        try {
            SQLiteDatabase db = sOpenHelper.getReadableDatabase();
            Cursor c = qb.query(db,
                    new String[] { MAIN_COLUMN_WORD1, MAIN_COLUMN_WORD2, FREQ_COLUMN_FREQUENCY },
                    new String[] {
                            MAIN_COLUMN_WORD1, MAIN_COLUMN_WORD2, COLUMN_FORGETTING_CURVE_VALUE },
                    selection, selectionArgs, null, null, null);
            return c;
        } catch (android.database.sqlite.SQLiteCantOpenDatabaseException e) {
@@ -290,7 +292,7 @@ public class UserHistoryDictionary extends ExpandableDictionary {
            db.execSQL("CREATE TABLE " + FREQ_TABLE_NAME + " ("
                    + FREQ_COLUMN_ID + " INTEGER PRIMARY KEY,"
                    + FREQ_COLUMN_PAIR_ID + " INTEGER,"
                    + FREQ_COLUMN_FREQUENCY + " INTEGER,"
                    + COLUMN_FORGETTING_CURVE_VALUE + " INTEGER,"
                    + "FOREIGN KEY(" + FREQ_COLUMN_PAIR_ID + ") REFERENCES " + MAIN_TABLE_NAME
                    + "(" + MAIN_COLUMN_ID + ")" + " ON DELETE CASCADE"
                    + ");");
@@ -378,10 +380,40 @@ public class UserHistoryDictionary extends ExpandableDictionary {

            // Write all the entries to the db
            for (String word1 : mBigramList.keySet()) {
                for (String word2 : mBigramList.getBigrams(word1)) {
                final HashMap<String, Byte> word1Bigrams = mBigramList.getBigrams(word1);
                for (String word2 : word1Bigrams.keySet()) {
                    // Get new frequency. Do not insert shortcuts/bigrams which freq is "-1".
                    final int freq; // -1, or 0~255
                    if (word1 == null) {
                        freq = FREQUENCY_FOR_TYPED;
                    } else {
                        final NextWord nw = mUserHistoryDictionary.getBigramWord(word1, word2);
                        if (nw != null) {
                            final ForgettingCurveParams fcp = nw.getFcParams();
                            final byte prevFc = word1Bigrams.get(word2);
                            final byte fc = (byte)fcp.getFc();
                            final boolean isValid = fcp.isValid();
                            if (prevFc > 0 && prevFc == fc) {
                                // No need to update since we found no changes for this entry.
                                // Just skip to the next entry.
                                if (DBG_SAVE_RESTORE) {
                                    Log.d(TAG, "Skip update user history: " + word1 + "," + word2
                                            + "," + prevFc);
                                }
                                continue;
                            } else if (UserHistoryForgettingCurveUtils.
                                    needsToSave(fc, isValid, addLevel0Bigram)) {
                                freq = fc;
                            } else {
                                freq = -1;
                            }
                        } else {
                            freq = -1;
                        }
                    }
                    // TODO: this process of making a text search for each pair each time
                    // is terribly inefficient. Optimize this.
                    // find pair id
                    // Find pair id
                    Cursor c = null;
                    try {
                        if (null != word1) {
@@ -399,40 +431,22 @@ public class UserHistoryDictionary extends ExpandableDictionary {

                        final int pairId;
                        if (c.moveToFirst()) {
                            // existing pair
                            // Delete existing pair
                            pairId = c.getInt(c.getColumnIndex(MAIN_COLUMN_ID));
                            db.delete(FREQ_TABLE_NAME, FREQ_COLUMN_PAIR_ID + "=?",
                                    new String[] { Integer.toString(pairId) });
                        } else {
                            // new pair
                            // Create new pair
                            Long pairIdLong = db.insert(MAIN_TABLE_NAME, null,
                                    getContentValues(word1, word2, mLocale));
                            pairId = pairIdLong.intValue();
                        }
                        // insert new frequency
                        final int freq;
                        if (word1 == null) {
                            freq = FREQUENCY_FOR_TYPED;
                        } else {
                            final NextWord nw = mUserHistoryDictionary.getBigramWord(word1, word2);
                            if (nw != null) {
                                final ForgettingCurveParams fcp = nw.getFcParams();
                                final int tempFreq = fcp.getFc();
                                final boolean isValid = fcp.isValid();
                                if (UserHistoryForgettingCurveUtils.needsToSave(
                                        (byte)tempFreq, isValid, addLevel0Bigram)) {
                                    freq = tempFreq;
                                } else {
                                    freq = -1;
                                }
                            } else {
                                freq = -1;
                            }
                        }
                        if (freq > 0) {
                            if (DBG_SAVE_RESTORE) {
                                Log.d(TAG, "--- Save user history: " + word1 + ", " + word2);
                                Log.d(TAG, "--- Save user history: " + word1 + ", " + word2
                                        + mLocale + "," + this);
                            }
                            // Insert new frequency
                            db.insert(FREQ_TABLE_NAME, null,
                                    getFrequencyContentValues(pairId, freq));
                        }
@@ -461,7 +475,7 @@ public class UserHistoryDictionary extends ExpandableDictionary {
        private static ContentValues getFrequencyContentValues(int pairId, int frequency) {
           ContentValues values = new ContentValues(2);
           values.put(FREQ_COLUMN_PAIR_ID, pairId);
           values.put(FREQ_COLUMN_FREQUENCY, frequency);
           values.put(COLUMN_FORGETTING_CURVE_VALUE, frequency);
           return values;
        }
    }
+18 −14
Original line number Diff line number Diff line
@@ -19,7 +19,6 @@ package com.android.inputmethod.latin;
import android.util.Log;

import java.util.HashMap;
import java.util.HashSet;
import java.util.Set;

/**
@@ -28,10 +27,11 @@ import java.util.Set;
 * bigrams when we write to the SQL DB.
 */
public class UserHistoryDictionaryBigramList {
    public static final byte FORGETTING_CURVE_INITIAL_VALUE = 0;
    private static final String TAG = UserHistoryDictionaryBigramList.class.getSimpleName();
    private static final HashSet<String> EMPTY_STRING_SET = new HashSet<String>();
    private final HashMap<String, HashSet<String>> mBigramMap =
            new HashMap<String, HashSet<String>>();
    private static final HashMap<String, Byte> EMPTY_BIGRAM_MAP = new HashMap<String, Byte>();
    private final HashMap<String, HashMap<String, Byte>> mBigramMap =
            new HashMap<String, HashMap<String, Byte>>();
    private int mSize = 0;

    public void evictAll() {
@@ -40,19 +40,23 @@ public class UserHistoryDictionaryBigramList {
    }

    public void addBigram(String word1, String word2) {
        addBigram(word1, word2, FORGETTING_CURVE_INITIAL_VALUE);
    }

    public void addBigram(String word1, String word2, byte fcValue) {
        if (UserHistoryDictionary.DBG_SAVE_RESTORE) {
            Log.d(TAG, "--- add bigram: " + word1 + ", " + word2);
        }
        final HashSet<String> set;
        final HashMap<String, Byte> map;
        if (mBigramMap.containsKey(word1)) {
            set = mBigramMap.get(word1);
            map = mBigramMap.get(word1);
        } else {
            set = new HashSet<String>();
            mBigramMap.put(word1, set);
            map = new HashMap<String, Byte>();
            mBigramMap.put(word1, map);
        }
        if (!set.contains(word2)) {
        if (!map.containsKey(word2)) {
            ++mSize;
            set.add(word2);
            map.put(word2, fcValue);
        }
    }

@@ -68,20 +72,20 @@ public class UserHistoryDictionaryBigramList {
        return mBigramMap.keySet();
    }

    public HashSet<String> getBigrams(String word1) {
    public HashMap<String, Byte> getBigrams(String word1) {
        if (!mBigramMap.containsKey(word1)) {
            return EMPTY_STRING_SET;
            return EMPTY_BIGRAM_MAP;
        } else {
            return mBigramMap.get(word1);
        }
    }

    public boolean removeBigram(String word1, String word2) {
        final HashSet<String> set = getBigrams(word1);
        final HashMap<String, Byte> set = getBigrams(word1);
        if (set.isEmpty()) {
            return false;
        }
        if (set.contains(word2)) {
        if (set.containsKey(word2)) {
            set.remove(word2);
            --mSize;
            return true;