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

Commit 32638419 authored by Amith Yamasani's avatar Amith Yamasani Committed by Jean-Baptiste Queru
Browse files

Some performance optimizations.

Makes the user/contacts dictionary lookup faster. This is necessary because
there's more in these dictionaries now and it's written in Java.

Fix an auto-caps issue when moving the cursor. And do it a little lazily.

Fixed a bug that was causing user dictionary words to get a much
higher weightage than the main dictionary.
parent f1150889
Loading
Loading
Loading
Loading
+0 −2
Original line number Diff line number Diff line
@@ -66,8 +66,6 @@ public class BinaryDictionary extends Dictionary {
    private native int getSuggestionsNative(int dict, int[] inputCodes, int codesSize, 
            char[] outputChars, int[] frequencies,
            int maxWordLength, int maxWords, int maxAlternatives, int skipPos);
    private native void setParamsNative(int typedLetterMultiplier,
            int fullWordMultiplier);

    private final void loadDictionary(Context context, int resId) {
        AssetManager am = context.getResources().getAssets();
+57 −34
Original line number Diff line number Diff line
@@ -18,13 +18,6 @@ package com.android.inputmethod.latin;

import android.content.Context;

import com.android.inputmethod.latin.Dictionary;
import com.android.inputmethod.latin.WordComposer;
import com.android.inputmethod.latin.Dictionary.WordCallback;

import java.util.ArrayList;
import java.util.List;

/**
 * Base class for an in-memory dictionary that can grow dynamically and can
 * be searched for suggestions and valid words.
@@ -42,14 +35,38 @@ public class ExpandableDictionary extends Dictionary {
        char code;
        int frequency;
        boolean terminal;
        List<Node> children;
        NodeArray children;
    }

    static class NodeArray {
        Node[] data;
        int length = 0;
        private static final int INCREMENT = 2;

        NodeArray() {
            data = new Node[INCREMENT];
        }

        void add(Node n) {
            if (length + 1 > data.length) {
                Node[] tempData = new Node[length + INCREMENT];
                if (length > 0) {
                    System.arraycopy(data, 0, tempData, 0, length);
                }
                data = tempData;
            }
            data[length++] = n;
        }
    }

    private NodeArray mRoots;

    private ArrayList<Node> mRoots;
    private int[][] mCodes;

    ExpandableDictionary(Context context) {
        mContext = context;
        clearDictionary();
        mCodes = new int[MAX_WORD_LENGTH][];
    }

    Context getContext() {
@@ -64,17 +81,17 @@ public class ExpandableDictionary extends Dictionary {
        addWordRec(mRoots, word, 0, frequency);
    }

    private void addWordRec(List<Node> children, final String word, 
    private void addWordRec(NodeArray children, final String word,
            final int depth, final int frequency) {
        
        final int wordLength = word.length();
        final char c = word.charAt(depth);
        // Does children have the current character?
        final int childrenLength = children.size();
        final int childrenLength = children.length;
        Node childNode = null;
        boolean found = false;
        for (int i = 0; i < childrenLength; i++) {
            childNode = children.get(i);
            childNode = children.data[i];
            if (childNode.code == c) {
                found = true;
                break;
@@ -93,7 +110,7 @@ public class ExpandableDictionary extends Dictionary {
            return;
        }
        if (childNode.children == null) {
            childNode.children = new ArrayList<Node>();
            childNode.children = new NodeArray();
        }
        addWordRec(childNode.children, word, depth + 1, frequency);
    }
@@ -101,10 +118,15 @@ public class ExpandableDictionary extends Dictionary {
    @Override
    public void getWords(final WordComposer codes, final WordCallback callback) {
        mInputLength = codes.size();
        if (mCodes.length < mInputLength) mCodes = new int[mInputLength][];
        // Cache the codes so that we don't have to lookup an array list
        for (int i = 0; i < mInputLength; i++) {
            mCodes[i] = codes.getCodesAt(i);
        }
        mMaxDepth = mInputLength * 3;
        getWordsRec(mRoots, codes, mWordBuilder, 0, false, 1.0f, 0, -1, callback);
        getWordsRec(mRoots, codes, mWordBuilder, 0, false, 1, 0, -1, callback);
        for (int i = 0; i < mInputLength; i++) {
            getWordsRec(mRoots, codes, mWordBuilder, 0, false, 1.0f, 0, i, callback);
            getWordsRec(mRoots, codes, mWordBuilder, 0, false, 1, 0, i, callback);
        }
    }

@@ -124,12 +146,12 @@ public class ExpandableDictionary extends Dictionary {
    /**
     * Returns the word's frequency or -1 if not found
     */
    private int getWordFrequencyRec(final List<Node> children, final CharSequence word, 
    private int getWordFrequencyRec(final NodeArray children, final CharSequence word, 
            final int offset, final int length) {
        final int count = children.size();
        final int count = children.length;
        char currentChar = word.charAt(offset);
        for (int j = 0; j < count; j++) {
            final Node node = children.get(j);
            final Node node = children.data[j];
            if (node.code == currentChar) {
                if (offset == length - 1) {
                    if (node.terminal) {
@@ -165,10 +187,10 @@ public class ExpandableDictionary extends Dictionary {
     * inputIndex
     * @param callback the callback class for adding a word
     */
    protected void getWordsRec(List<Node> roots, final WordComposer codes, final char[] word, 
            final int depth, boolean completion, float snr, int inputIndex, int skipPos,
    protected void getWordsRec(NodeArray roots, final WordComposer codes, final char[] word, 
            final int depth, boolean completion, int snr, int inputIndex, int skipPos,
            WordCallback callback) {
        final int count = roots.size();
        final int count = roots.length;
        final int codeSize = mInputLength;
        // Optimization: Prune out words that are too long compared to how much was typed.
        if (depth > mMaxDepth) {
@@ -178,20 +200,20 @@ public class ExpandableDictionary extends Dictionary {
        if (codeSize <= inputIndex) {
            completion = true;
        } else {
            currentChars = codes.getCodesAt(inputIndex);
            currentChars = mCodes[inputIndex];
        }

        for (int i = 0; i < count; i++) {
            final Node node = roots.get(i); 
            final Node node = roots.data[i];
            final char c = node.code;
            final char lowerC = toLowerCase(c);
            boolean terminal = node.terminal;
            List<Node> children = node.children;
            int freq = node.frequency;
            final boolean terminal = node.terminal;
            final NodeArray children = node.children;
            final int freq = node.frequency;
            if (completion) {
                word[depth] = c;
                if (terminal) {
                    if (!callback.addWord(word, 0, depth + 1, (int) (freq * snr))) {
                    if (!callback.addWord(word, 0, depth + 1, freq * snr)) {
                        return;
                    }
                }
@@ -210,14 +232,15 @@ public class ExpandableDictionary extends Dictionary {
                // Don't use alternatives if we're looking for missing characters
                final int alternativesSize = skipPos >= 0? 1 : currentChars.length;
                for (int j = 0; j < alternativesSize; j++) {
                    float addedAttenuation = (j > 0 ? 1f : 3f);
                    if (currentChars[j] == -1) {
                    final int addedAttenuation = (j > 0 ? 1 : 2);
                    final int currentChar = currentChars[j];
                    if (currentChar == -1) {
                        break;
                    }
                    if (currentChars[j] == lowerC || currentChars[j] == c) {
                    if (currentChar == lowerC || currentChar == c) {
                        word[depth] = c;

                        if (codes.size() == depth + 1) {
                        if (codeSize == depth + 1) {
                            if (terminal) {
                                if (INCLUDE_TYPED_WORD_IF_VALID 
                                        || !same(word, depth + 1, codes.getTypedWord())) {
@@ -243,7 +266,7 @@ public class ExpandableDictionary extends Dictionary {
    }

    protected void clearDictionary() {
        mRoots = new ArrayList<Node>();
        mRoots = new NodeArray();
    }

    static char toLowerCase(char c) {
@@ -252,7 +275,7 @@ public class ExpandableDictionary extends Dictionary {
        }
        if (c >= 'A' && c <= 'Z') {
            c = (char) (c | 32);
        } else {
        } else if (c > 127) {
            c = Character.toLowerCase(c);
        }
        return c;
+12 −3
Original line number Diff line number Diff line
@@ -371,6 +371,7 @@ public class LatinIME extends InputMethodService
            TextEntryState.reset();
        }
        mJustAccepted = false;
        postUpdateShiftKeyState();
    }

    @Override
@@ -498,6 +499,11 @@ public class LatinIME extends InputMethodService
        }
    }

    private void postUpdateShiftKeyState() {
        mHandler.removeMessages(MSG_UPDATE_SHIFT_STATE);
        mHandler.sendMessageDelayed(mHandler.obtainMessage(MSG_UPDATE_SHIFT_STATE), 300);
    }

    public void updateShiftKeyState(EditorInfo attr) {
        InputConnection ic = getCurrentInputConnection();
        if (attr != null && mInputView != null && mKeyboardSwitcher.isAlphabetMode()
@@ -637,8 +643,7 @@ public class LatinIME extends InputMethodService
        } else {
            deleteChar = true;
        }
        mHandler.removeMessages(MSG_UPDATE_SHIFT_STATE);
        mHandler.sendMessageDelayed(mHandler.obtainMessage(MSG_UPDATE_SHIFT_STATE), 300);
        postUpdateShiftKeyState();
        TextEntryState.backspace();
        if (TextEntryState.getState() == TextEntryState.STATE_UNDO_COMMIT) {
            revertLastWord(deleteChar);
@@ -688,7 +693,11 @@ public class LatinIME extends InputMethodService
        } else {
            sendKeyChar((char)primaryCode);
        }
        if (mPredicting && mComposing.length() == 1) {
            updateShiftKeyState(getCurrentInputEditorInfo());
        } else {
            postUpdateShiftKeyState();
        }
        measureCps();
        TextEntryState.typedCharacter((char) primaryCode, isWordSeparator(primaryCode));
    }
+1 −1
Original line number Diff line number Diff line
@@ -26,7 +26,7 @@ public class WordComposer {
    /**
     * The list of unicode values for each keystroke (including surrounding keys)
     */
    private List<int[]> mCodes;
    private ArrayList<int[]> mCodes;
    
    /**
     * The word chosen from the candidate list, until it is committed.