aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--java/res/values-fr-rCA/donottranslate.xml31
-rw-r--r--java/src/com/android/inputmethod/latin/LatinIME.java33
-rw-r--r--java/src/com/android/inputmethod/latin/UserBinaryDictionary.java21
-rw-r--r--java/src/com/android/inputmethod/latin/makedict/BinaryDictDecoderUtils.java60
-rw-r--r--java/src/com/android/inputmethod/latin/makedict/BinaryDictIOUtils.java35
-rw-r--r--java/src/com/android/inputmethod/latin/makedict/DictDecoder.java27
-rw-r--r--java/src/com/android/inputmethod/latin/makedict/Ver3DictDecoder.java29
-rw-r--r--java/src/com/android/inputmethod/latin/utils/PositionalInfoForUserDictPendingAddition.java108
-rw-r--r--native/jni/src/defines.h9
-rw-r--r--native/jni/src/suggest/core/dicnode/dic_node_priority_queue.h61
-rw-r--r--native/jni/src/suggest/core/dicnode/dic_nodes_cache.h36
-rw-r--r--native/jni/src/suggest/core/session/dic_traverse_session.cpp5
-rw-r--r--native/jni/src/suggest/core/session/dic_traverse_session.h2
13 files changed, 187 insertions, 270 deletions
diff --git a/java/res/values-fr-rCA/donottranslate.xml b/java/res/values-fr-rCA/donottranslate.xml
new file mode 100644
index 000000000..21f18d852
--- /dev/null
+++ b/java/res/values-fr-rCA/donottranslate.xml
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+**
+** Copyright 2009, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+** http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+-->
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <!-- Symbols that are normally preceded by a space (used to add an auto-space before these) -->
+ <!-- This is similar to French with the exception of "!" "?" and ";" which do not take a space before in Canadian French. Note that ":" does take a space before according to Canadian rules. -->
+ <string name="symbols_preceded_by_space">([{&amp;:</string>
+ <!-- Symbols that are normally followed by a space (used to add an auto-space after these) -->
+ <string name="symbols_followed_by_space">.,;:!?)]}&amp;</string>
+ <!-- Symbols that separate words -->
+ <!-- Don't remove the enclosing double quotes, they protect whitespace (not just U+0020) -->
+ <string name="symbols_word_separators">"&#x0009;&#x0020;\n"()[]{}*&amp;&lt;&gt;+=|.,;:!?/_\"</string>
+ <!-- Word connectors -->
+ <string name="symbols_word_connectors">\'-</string>
+</resources>
diff --git a/java/src/com/android/inputmethod/latin/LatinIME.java b/java/src/com/android/inputmethod/latin/LatinIME.java
index 6c83ac7ed..a325c40c4 100644
--- a/java/src/com/android/inputmethod/latin/LatinIME.java
+++ b/java/src/com/android/inputmethod/latin/LatinIME.java
@@ -95,7 +95,6 @@ import com.android.inputmethod.latin.utils.InputTypeUtils;
import com.android.inputmethod.latin.utils.IntentUtils;
import com.android.inputmethod.latin.utils.JniUtils;
import com.android.inputmethod.latin.utils.LatinImeLoggerUtils;
-import com.android.inputmethod.latin.utils.PositionalInfoForUserDictPendingAddition;
import com.android.inputmethod.latin.utils.RecapitalizeStatus;
import com.android.inputmethod.latin.utils.StaticInnerHandlerWrapper;
import com.android.inputmethod.latin.utils.TargetPackageInfoGetterTask;
@@ -185,8 +184,6 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
private boolean mIsUserDictionaryAvailable;
private LastComposedWord mLastComposedWord = LastComposedWord.NOT_A_COMPOSED_WORD;
- private PositionalInfoForUserDictPendingAddition
- mPositionalInfoForUserDictPendingAddition = null;
private final WordComposer mWordComposer = new WordComposer();
private final RichInputConnection mConnection = new RichInputConnection(this);
private final RecapitalizeStatus mRecapitalizeStatus = new RecapitalizeStatus();
@@ -898,19 +895,6 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
currentSettingsValues.mGestureTrailEnabled,
currentSettingsValues.mGestureFloatingPreviewTextEnabled);
- // If we have a user dictionary addition in progress, we should check now if we should
- // replace the previously committed string with the word that has actually been added
- // to the user dictionary.
- if (null != mPositionalInfoForUserDictPendingAddition
- && mPositionalInfoForUserDictPendingAddition.tryReplaceWithActualWord(
- mConnection, editorInfo, mLastSelectionEnd, currentLocale)) {
- mPositionalInfoForUserDictPendingAddition = null;
- }
- // If tryReplaceWithActualWord returns false, we don't know what word was
- // added to the user dictionary yet, so we keep the data and defer processing. The word will
- // be replaced when the user dictionary reports back with the actual word, which ends
- // up calling #onWordAddedToUserDictionary() in this class.
-
initPersonalizationDebugSettings(currentSettingsValues);
if (TRACE) Debug.startMethodTracing("/data/trace/latinime");
@@ -1416,7 +1400,6 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
public void addWordToUserDictionary(final String word) {
if (TextUtils.isEmpty(word)) {
// Probably never supposed to happen, but just in case.
- mPositionalInfoForUserDictPendingAddition = null;
return;
}
final String wordToEdit;
@@ -1428,22 +1411,6 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
mUserDictionary.addWordToUserDictionary(wordToEdit);
}
- public void onWordAddedToUserDictionary(final String newSpelling) {
- // If word was added but not by us, bail out
- if (null == mPositionalInfoForUserDictPendingAddition) return;
- if (mWordComposer.isComposingWord()) {
- // We are late... give up and return
- mPositionalInfoForUserDictPendingAddition = null;
- return;
- }
- mPositionalInfoForUserDictPendingAddition.setActualWordBeingAdded(newSpelling);
- if (mPositionalInfoForUserDictPendingAddition.tryReplaceWithActualWord(
- mConnection, getCurrentInputEditorInfo(), mLastSelectionEnd,
- mSubtypeSwitcher.getCurrentSubtypeLocale())) {
- mPositionalInfoForUserDictPendingAddition = null;
- }
- }
-
private void onSettingsKeyPressed() {
if (isShowingOptionDialog()) return;
showSubtypeSelectorAndSettings();
diff --git a/java/src/com/android/inputmethod/latin/UserBinaryDictionary.java b/java/src/com/android/inputmethod/latin/UserBinaryDictionary.java
index b2bb61596..a241b5505 100644
--- a/java/src/com/android/inputmethod/latin/UserBinaryDictionary.java
+++ b/java/src/com/android/inputmethod/latin/UserBinaryDictionary.java
@@ -103,14 +103,6 @@ public class UserBinaryDictionary extends ExpandableBinaryDictionary {
@Override
public void onChange(final boolean self, final Uri uri) {
setRequiresReload(true);
- // We want to report back to Latin IME in case the user just entered the word.
- // If the user changed the word in the dialog box, then we want to replace
- // what was entered in the text field.
- if (null == uri || !(context instanceof LatinIME)) return;
- final long changedRowId = ContentUris.parseId(uri);
- if (-1 == changedRowId) return; // Unknown content... Not sure why we're here
- final String changedWord = getChangedWordForUri(uri);
- ((LatinIME)context).onWordAddedToUserDictionary(changedWord);
}
};
cres.registerContentObserver(Words.CONTENT_URI, true, mObserver);
@@ -118,19 +110,6 @@ public class UserBinaryDictionary extends ExpandableBinaryDictionary {
loadDictionary();
}
- private String getChangedWordForUri(final Uri uri) {
- final Cursor cursor = mContext.getContentResolver().query(uri,
- PROJECTION_QUERY, null, null, null);
- if (cursor == null) return null;
- try {
- if (!cursor.moveToFirst()) return null;
- final int indexWord = cursor.getColumnIndex(Words.WORD);
- return cursor.getString(indexWord);
- } finally {
- cursor.close();
- }
- }
-
@Override
public synchronized void close() {
if (mObserver != null) {
diff --git a/java/src/com/android/inputmethod/latin/makedict/BinaryDictDecoderUtils.java b/java/src/com/android/inputmethod/latin/makedict/BinaryDictDecoderUtils.java
index ceb8fa81f..5b319ad90 100644
--- a/java/src/com/android/inputmethod/latin/makedict/BinaryDictDecoderUtils.java
+++ b/java/src/com/android/inputmethod/latin/makedict/BinaryDictDecoderUtils.java
@@ -342,13 +342,11 @@ public final class BinaryDictDecoderUtils {
* @param formatOptions file format options.
* @return the word with its frequency, as a weighted string.
*/
- /* package for tests */ static WeightedString getWordAtPosition(
- final Ver3DictDecoder dictDecoder, final int headerSize, final int pos,
- final FormatOptions formatOptions) {
- final DictBuffer dictBuffer = dictDecoder.getDictBuffer();
+ /* package for tests */ static WeightedString getWordAtPosition(final DictDecoder dictDecoder,
+ final int headerSize, final int pos, final FormatOptions formatOptions) {
final WeightedString result;
- final int originalPos = dictBuffer.position();
- dictBuffer.position(pos);
+ final int originalPos = dictDecoder.getPosition();
+ dictDecoder.setPosition(pos);
if (BinaryDictIOUtils.supportsDynamicUpdate(formatOptions)) {
result = getWordAtPositionWithParentAddress(dictDecoder, pos, formatOptions);
@@ -357,14 +355,13 @@ public final class BinaryDictDecoderUtils {
formatOptions);
}
- dictBuffer.position(originalPos);
+ dictDecoder.setPosition(originalPos);
return result;
}
@SuppressWarnings("unused")
- private static WeightedString getWordAtPositionWithParentAddress(
- final Ver3DictDecoder dictDecoder, final int pos, final FormatOptions options) {
- final DictBuffer dictBuffer = dictDecoder.getDictBuffer();
+ private static WeightedString getWordAtPositionWithParentAddress(final DictDecoder dictDecoder,
+ final int pos, final FormatOptions options) {
int currentPos = pos;
int frequency = Integer.MIN_VALUE;
final StringBuilder builder = new StringBuilder();
@@ -373,7 +370,7 @@ public final class BinaryDictDecoderUtils {
PtNodeInfo currentInfo;
int loopCounter = 0;
do {
- dictBuffer.position(currentPos);
+ dictDecoder.setPosition(currentPos);
currentInfo = dictDecoder.readPtNode(currentPos, options);
if (BinaryDictIOUtils.isMovedPtNode(currentInfo.mFlags, options)) {
currentPos = currentInfo.mParentAddress + currentInfo.mOriginalAddress;
@@ -392,11 +389,10 @@ public final class BinaryDictDecoderUtils {
}
private static WeightedString getWordAtPositionWithoutParentAddress(
- final Ver3DictDecoder dictDecoder, final int headerSize, final int pos,
+ final DictDecoder dictDecoder, final int headerSize, final int pos,
final FormatOptions options) {
- final DictBuffer dictBuffer = dictDecoder.getDictBuffer();
- dictBuffer.position(headerSize);
- final int count = readPtNodeCount(dictBuffer);
+ dictDecoder.setPosition(headerSize);
+ final int count = dictDecoder.readPtNodeCount();
int groupPos = headerSize + BinaryDictIOUtils.getPtNodeCountSize(count);
final StringBuilder builder = new StringBuilder();
WeightedString result = null;
@@ -414,8 +410,8 @@ public final class BinaryDictDecoderUtils {
if (info.mChildrenAddress > pos) {
if (null == last) continue;
builder.append(new String(last.mCharacters, 0, last.mCharacters.length));
- dictBuffer.position(last.mChildrenAddress);
- i = readPtNodeCount(dictBuffer);
+ dictDecoder.setPosition(last.mChildrenAddress);
+ i = dictDecoder.readPtNodeCount();
groupPos = last.mChildrenAddress + BinaryDictIOUtils.getPtNodeCountSize(i);
last = null;
continue;
@@ -424,8 +420,8 @@ public final class BinaryDictDecoderUtils {
}
if (0 == i && BinaryDictIOUtils.hasChildrenAddress(last.mChildrenAddress)) {
builder.append(new String(last.mCharacters, 0, last.mCharacters.length));
- dictBuffer.position(last.mChildrenAddress);
- i = readPtNodeCount(dictBuffer);
+ dictDecoder.setPosition(last.mChildrenAddress);
+ i = dictDecoder.readPtNodeCount();
groupPos = last.mChildrenAddress + BinaryDictIOUtils.getPtNodeCountSize(i);
last = null;
continue;
@@ -449,17 +445,16 @@ public final class BinaryDictDecoderUtils {
* @param options file format options.
* @return the read node array with all his children already read.
*/
- private static PtNodeArray readNodeArray(final Ver3DictDecoder dictDecoder,
+ private static PtNodeArray readNodeArray(final DictDecoder dictDecoder,
final int headerSize, final Map<Integer, PtNodeArray> reverseNodeArrayMap,
final Map<Integer, PtNode> reversePtNodeMap, final FormatOptions options)
throws IOException {
- final DictBuffer dictBuffer = dictDecoder.getDictBuffer();
final ArrayList<PtNode> nodeArrayContents = new ArrayList<PtNode>();
- final int nodeArrayOriginPos = dictBuffer.position();
+ final int nodeArrayOriginPos = dictDecoder.getPosition();
do { // Scan the linked-list node.
- final int nodeArrayHeadPos = dictBuffer.position();
- final int count = readPtNodeCount(dictBuffer);
+ final int nodeArrayHeadPos = dictDecoder.getPosition();
+ final int count = dictDecoder.readPtNodeCount();
int groupOffsetPos = nodeArrayHeadPos + BinaryDictIOUtils.getPtNodeCountSize(count);
for (int i = count; i > 0; --i) { // Scan the array of PtNode.
PtNodeInfo info = dictDecoder.readPtNode(groupOffsetPos, options);
@@ -480,11 +475,11 @@ public final class BinaryDictDecoderUtils {
if (BinaryDictIOUtils.hasChildrenAddress(info.mChildrenAddress)) {
PtNodeArray children = reverseNodeArrayMap.get(info.mChildrenAddress);
if (null == children) {
- final int currentPosition = dictBuffer.position();
- dictBuffer.position(info.mChildrenAddress);
+ final int currentPosition = dictDecoder.getPosition();
+ dictDecoder.setPosition(info.mChildrenAddress);
children = readNodeArray(dictDecoder, headerSize, reverseNodeArrayMap,
reversePtNodeMap, options);
- dictBuffer.position(currentPosition);
+ dictDecoder.setPosition(currentPosition);
}
nodeArrayContents.add(
new PtNode(info.mCharacters, shortcutTargets, bigrams,
@@ -503,15 +498,10 @@ public final class BinaryDictDecoderUtils {
// reach the end of the array.
if (options.mSupportsDynamicUpdate) {
- final int nextAddress = dictBuffer.readUnsignedInt24();
- if (nextAddress >= 0 && nextAddress < dictBuffer.limit()) {
- dictBuffer.position(nextAddress);
- } else {
- break;
- }
+ final boolean hasValidForwardLink = dictDecoder.readForwardLinkAndAdvancePosition();
+ if (!hasValidForwardLink) break;
}
- } while (options.mSupportsDynamicUpdate &&
- dictBuffer.position() != FormatSpec.NO_FORWARD_LINK_ADDRESS);
+ } while (options.mSupportsDynamicUpdate && dictDecoder.hasNextPtNodeArray());
final PtNodeArray nodeArray = new PtNodeArray(nodeArrayContents);
nodeArray.mCachedAddressBeforeUpdate = nodeArrayOriginPos;
diff --git a/java/src/com/android/inputmethod/latin/makedict/BinaryDictIOUtils.java b/java/src/com/android/inputmethod/latin/makedict/BinaryDictIOUtils.java
index 106f02519..5cb40f30c 100644
--- a/java/src/com/android/inputmethod/latin/makedict/BinaryDictIOUtils.java
+++ b/java/src/com/android/inputmethod/latin/makedict/BinaryDictIOUtils.java
@@ -61,12 +61,11 @@ public final class BinaryDictIOUtils {
/**
* Retrieves all node arrays without recursive call.
*/
- private static void readUnigramsAndBigramsBinaryInner(
- final Ver3DictDecoder dictDecoder, final int headerSize,
- final Map<Integer, String> words, final Map<Integer, Integer> frequencies,
+ private static void readUnigramsAndBigramsBinaryInner(final DictDecoder dictDecoder,
+ final int headerSize, final Map<Integer, String> words,
+ final Map<Integer, Integer> frequencies,
final Map<Integer, ArrayList<PendingAttribute>> bigrams,
final FormatOptions formatOptions) {
- final DictBuffer dictBuffer = dictDecoder.getDictBuffer();
int[] pushedChars = new int[FormatSpec.MAX_WORD_LENGTH + 1];
Stack<Position> stack = new Stack<Position>();
@@ -83,11 +82,11 @@ public final class BinaryDictIOUtils {
p.mNumOfPtNode + ", position=" + p.mPosition + ", length=" + p.mLength);
}
- if (dictBuffer.position() != p.mAddress) dictBuffer.position(p.mAddress);
+ if (dictDecoder.getPosition() != p.mAddress) dictDecoder.setPosition(p.mAddress);
if (index != p.mLength) index = p.mLength;
if (p.mNumOfPtNode == Position.NOT_READ_PTNODE_COUNT) {
- p.mNumOfPtNode = BinaryDictDecoderUtils.readPtNodeCount(dictBuffer);
+ p.mNumOfPtNode = dictDecoder.readPtNodeCount();
p.mAddress += getPtNodeCountSize(p.mNumOfPtNode);
p.mPosition = 0;
}
@@ -114,11 +113,12 @@ public final class BinaryDictIOUtils {
if (p.mPosition == p.mNumOfPtNode) {
if (formatOptions.mSupportsDynamicUpdate) {
- final int forwardLinkAddress = dictBuffer.readUnsignedInt24();
- if (forwardLinkAddress != FormatSpec.NO_FORWARD_LINK_ADDRESS) {
+ final boolean hasValidForwardLinkAddress =
+ dictDecoder.readForwardLinkAndAdvancePosition();
+ if (hasValidForwardLinkAddress && dictDecoder.hasNextPtNodeArray()) {
// The node array has a forward link.
p.mNumOfPtNode = Position.NOT_READ_PTNODE_COUNT;
- p.mAddress = forwardLinkAddress;
+ p.mAddress = dictDecoder.getPosition();
} else {
stack.pop();
}
@@ -127,7 +127,7 @@ public final class BinaryDictIOUtils {
}
} else {
// The Ptnode array has more PtNodes.
- p.mAddress = dictBuffer.position();
+ p.mAddress = dictDecoder.getPosition();
}
if (!isMovedPtNode && hasChildrenAddress(info.mChildrenAddress)) {
@@ -171,9 +171,8 @@ public final class BinaryDictIOUtils {
@UsedForTesting
/* package */ static int getTerminalPosition(final Ver3DictDecoder dictDecoder,
final String word) throws IOException, UnsupportedFormatException {
- final DictBuffer dictBuffer = dictDecoder.getDictBuffer();
if (word == null) return FormatSpec.NOT_VALID_WORD;
- if (dictBuffer.position() != 0) dictBuffer.position(0);
+ dictDecoder.setPosition(0);
final FileHeader header = dictDecoder.readHeader();
int wordPos = 0;
@@ -182,10 +181,10 @@ public final class BinaryDictIOUtils {
if (wordPos >= wordLen) return FormatSpec.NOT_VALID_WORD;
do {
- final int ptNodeCount = BinaryDictDecoderUtils.readPtNodeCount(dictBuffer);
+ final int ptNodeCount = dictDecoder.readPtNodeCount();
boolean foundNextPtNode = false;
for (int i = 0; i < ptNodeCount; ++i) {
- final int ptNodePos = dictBuffer.position();
+ final int ptNodePos = dictDecoder.getPosition();
final PtNodeInfo currentInfo = dictDecoder.readPtNode(ptNodePos,
header.mFormatOptions);
final boolean isMovedNode = isMovedPtNode(currentInfo.mFlags,
@@ -219,7 +218,7 @@ public final class BinaryDictIOUtils {
return FormatSpec.NOT_VALID_WORD;
}
foundNextPtNode = true;
- dictBuffer.position(currentInfo.mChildrenAddress);
+ dictDecoder.setPosition(currentInfo.mChildrenAddress);
break;
}
}
@@ -233,11 +232,11 @@ public final class BinaryDictIOUtils {
return FormatSpec.NOT_VALID_WORD;
}
- final int forwardLinkAddress = dictBuffer.readUnsignedInt24();
- if (forwardLinkAddress == FormatSpec.NO_FORWARD_LINK_ADDRESS) {
+ final boolean hasValidForwardLinkAddress =
+ dictDecoder.readForwardLinkAndAdvancePosition();
+ if (!hasValidForwardLinkAddress || !dictDecoder.hasNextPtNodeArray()) {
return FormatSpec.NOT_VALID_WORD;
}
- dictBuffer.position(forwardLinkAddress);
} while(true);
}
return FormatSpec.NOT_VALID_WORD;
diff --git a/java/src/com/android/inputmethod/latin/makedict/DictDecoder.java b/java/src/com/android/inputmethod/latin/makedict/DictDecoder.java
index 64638fd98..5e398bd41 100644
--- a/java/src/com/android/inputmethod/latin/makedict/DictDecoder.java
+++ b/java/src/com/android/inputmethod/latin/makedict/DictDecoder.java
@@ -91,6 +91,33 @@ public interface DictDecoder {
final TreeMap<Integer, ArrayList<PendingAttribute>> bigrams)
throws IOException, UnsupportedFormatException;
+ /**
+ * Sets the position of the buffer to the given value.
+ *
+ * @param newPos the new position
+ */
+ public void setPosition(final int newPos);
+
+ /**
+ * Gets the position of the buffer.
+ *
+ * @return the position
+ */
+ public int getPosition();
+
+ /**
+ * Reads and returns the PtNode count out of a buffer and forwards the pointer.
+ */
+ public int readPtNodeCount();
+
+ /**
+ * Reads the forward link and advances the position.
+ *
+ * @return if this method advances the position then true else false.
+ */
+ public boolean readForwardLinkAndAdvancePosition();
+ public boolean hasNextPtNodeArray();
+
// Flags for DictionaryBufferFactory.
public static final int USE_READONLY_BYTEBUFFER = 0x01000000;
public static final int USE_BYTEARRAY = 0x02000000;
diff --git a/java/src/com/android/inputmethod/latin/makedict/Ver3DictDecoder.java b/java/src/com/android/inputmethod/latin/makedict/Ver3DictDecoder.java
index b98aa0f60..6dff9b6d2 100644
--- a/java/src/com/android/inputmethod/latin/makedict/Ver3DictDecoder.java
+++ b/java/src/com/android/inputmethod/latin/makedict/Ver3DictDecoder.java
@@ -348,4 +348,33 @@ public class Ver3DictDecoder implements DictDecoder {
BinaryDictIOUtils.readUnigramsAndBigramsBinary(this, words, frequencies, bigrams);
}
+ @Override
+ public void setPosition(int newPos) {
+ mDictBuffer.position(newPos);
+ }
+
+ @Override
+ public int getPosition() {
+ return mDictBuffer.position();
+ }
+
+ @Override
+ public int readPtNodeCount() {
+ return BinaryDictDecoderUtils.readPtNodeCount(mDictBuffer);
+ }
+
+ @Override
+ public boolean readForwardLinkAndAdvancePosition() {
+ final int nextAddress = mDictBuffer.readUnsignedInt24();
+ if (nextAddress >= 0 && nextAddress < mDictBuffer.limit()) {
+ mDictBuffer.position(nextAddress);
+ return true;
+ }
+ return false;
+ }
+
+ @Override
+ public boolean hasNextPtNodeArray() {
+ return mDictBuffer.position() != FormatSpec.NO_FORWARD_LINK_ADDRESS;
+ }
}
diff --git a/java/src/com/android/inputmethod/latin/utils/PositionalInfoForUserDictPendingAddition.java b/java/src/com/android/inputmethod/latin/utils/PositionalInfoForUserDictPendingAddition.java
deleted file mode 100644
index 1fc7eccc6..000000000
--- a/java/src/com/android/inputmethod/latin/utils/PositionalInfoForUserDictPendingAddition.java
+++ /dev/null
@@ -1,108 +0,0 @@
-/*
- * Copyright (C) 2012 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.inputmethod.latin.utils;
-
-import android.view.inputmethod.EditorInfo;
-
-import com.android.inputmethod.latin.RichInputConnection;
-
-import java.util.Locale;
-
-/**
- * Holder class for data about a word already committed but that may still be edited.
- *
- * When the user chooses to add a word to the user dictionary by pressing the appropriate
- * suggestion, a dialog is presented to give a chance to edit the word before it is actually
- * registered as a user dictionary word. If the word is actually modified, the IME needs to
- * go back and replace the word that was committed with the amended version.
- * The word we need to replace with will only be known after it's actually committed, so
- * the IME needs to take a note of what it has to replace and where it is.
- * This class encapsulates this data.
- */
-public final class PositionalInfoForUserDictPendingAddition {
- final private String mOriginalWord;
- final private int mCursorPos; // Position of the cursor after the word
- final private EditorInfo mEditorInfo; // On what binding this has been added
- final private int mCapitalizedMode;
- private String mActualWordBeingAdded;
-
- public PositionalInfoForUserDictPendingAddition(final String word, final int cursorPos,
- final EditorInfo editorInfo, final int capitalizedMode) {
- mOriginalWord = word;
- mCursorPos = cursorPos;
- mEditorInfo = editorInfo;
- mCapitalizedMode = capitalizedMode;
- }
-
- public void setActualWordBeingAdded(final String actualWordBeingAdded) {
- mActualWordBeingAdded = actualWordBeingAdded;
- }
-
- /**
- * Try to replace the string at the remembered position with the actual word being added.
- *
- * After the user validated the word being added, the IME has to replace the old version
- * (which has been committed in the text view) with the amended version if it's different.
- * This method tries to do that, but may fail because the IME is not yet ready to do so -
- * for example, it is still waiting for the new string, or it is waiting to return to the text
- * view in which the amendment should be made. In these cases, we should keep the data
- * and wait until all conditions are met.
- * This method returns true if the replacement has been successfully made and this data
- * can be forgotten; it returns false if the replacement can't be made yet and we need to
- * keep this until a later time.
- * The IME knows about the actual word being added through a callback called by the
- * user dictionary facility of the device. When this callback comes, the keyboard may still
- * be connected to the edition dialog, or it may have already returned to the original text
- * field. Replacement has to work in both cases.
- * Accordingly, this method is called at two different points in time : upon getting the
- * event that a new word was added to the user dictionary, and upon starting up in a
- * new text field.
- * @param connection The RichInputConnection through which to contact the editor.
- * @param editorInfo Information pertaining to the editor we are currently in.
- * @param currentCursorPosition The current cursor position, for checking purposes.
- * @param locale The locale for changing case, if necessary
- * @return true if the edit has been successfully made, false if we need to try again later
- */
- public boolean tryReplaceWithActualWord(final RichInputConnection connection,
- final EditorInfo editorInfo, final int currentCursorPosition, final Locale locale) {
- // If we still don't know the actual word being added, we need to try again later.
- if (null == mActualWordBeingAdded) return false;
- // The entered text and the registered text were the same anyway : we can
- // return success right away even if focus has not returned yet to the text field we
- // want to amend.
- if (mActualWordBeingAdded.equals(mOriginalWord)) return true;
- // Not the same text field : we need to try again later. This happens when the addition
- // is reported by the user dictionary provider before the focus has moved back to the
- // original text view, so the IME is still in the text view of the dialog and has no way to
- // edit the original text view at this time.
- if (!mEditorInfo.packageName.equals(editorInfo.packageName)
- || mEditorInfo.fieldId != editorInfo.fieldId) {
- return false;
- }
- // Same text field, but not the same cursor position : we give up, so we return success
- // so that it won't be tried again
- if (currentCursorPosition != mCursorPos) return true;
- // We have made all the checks : do the replacement and report success
- // If this was auto-capitalized, we need to restore the case before committing
- final String wordWithCaseFixed = CapsModeUtils.applyAutoCapsMode(mActualWordBeingAdded,
- mCapitalizedMode, locale);
- connection.setComposingRegion(currentCursorPosition - mOriginalWord.length(),
- currentCursorPosition);
- connection.commitText(wordWithCaseFixed, wordWithCaseFixed.length());
- return true;
- }
-}
diff --git a/native/jni/src/defines.h b/native/jni/src/defines.h
index 34a646f80..07f1e52c6 100644
--- a/native/jni/src/defines.h
+++ b/native/jni/src/defines.h
@@ -32,6 +32,8 @@
#define MAX_WORD_LENGTH 48
// Must be equal to BinaryDictionary.MAX_RESULTS in Java
#define MAX_RESULTS 18
+// The biggest value among MAX_CACHE_DIC_NODE_SIZE, MAX_CACHE_DIC_NODE_SIZE_FOR_SINGLE_POINT, ...
+#define MAX_DIC_NODE_PRIORITY_QUEUE_CAPACITY 310
// Must be equal to ProximityInfo.MAX_PROXIMITY_CHARS_SIZE in Java
#define MAX_PROXIMITY_CHARS_SIZE 16
#define ADDITIONAL_PROXIMITY_CHAR_DELIMITER_CODE 2
@@ -322,13 +324,6 @@ static inline void prof_out(void) {
#define MAX_POINTER_COUNT 1
#define MAX_POINTER_COUNT_G 2
-// Queue IDs and size for DicNodesCache
-#define DIC_NODES_CACHE_INITIAL_QUEUE_ID_ACTIVE 0
-#define DIC_NODES_CACHE_INITIAL_QUEUE_ID_NEXT_ACTIVE 1
-#define DIC_NODES_CACHE_INITIAL_QUEUE_ID_TERMINAL 2
-#define DIC_NODES_CACHE_INITIAL_QUEUE_ID_CACHE_FOR_CONTINUOUS_SUGGESTION 3
-#define DIC_NODES_CACHE_PRIORITY_QUEUES_SIZE 4
-
template<typename T> AK_FORCE_INLINE const T &min(const T &a, const T &b) { return a < b ? a : b; }
template<typename T> AK_FORCE_INLINE const T &max(const T &a, const T &b) { return a > b ? a : b; }
diff --git a/native/jni/src/suggest/core/dicnode/dic_node_priority_queue.h b/native/jni/src/suggest/core/dicnode/dic_node_priority_queue.h
index 2a486b804..7461f0cc6 100644
--- a/native/jni/src/suggest/core/dicnode/dic_node_priority_queue.h
+++ b/native/jni/src/suggest/core/dicnode/dic_node_priority_queue.h
@@ -24,20 +24,16 @@
#include "suggest/core/dicnode/dic_node.h"
#include "suggest/core/dicnode/dic_node_release_listener.h"
-// The biggest value among MAX_CACHE_DIC_NODE_SIZE, MAX_CACHE_DIC_NODE_SIZE_FOR_SINGLE_POINT, ...
-#define MAX_DIC_NODE_PRIORITY_QUEUE_CAPACITY 310
-
namespace latinime {
class DicNodePriorityQueue : public DicNodeReleaseListener {
public:
- AK_FORCE_INLINE DicNodePriorityQueue()
- : MAX_CAPACITY(MAX_DIC_NODE_PRIORITY_QUEUE_CAPACITY),
- mMaxSize(MAX_DIC_NODE_PRIORITY_QUEUE_CAPACITY), mDicNodesBuf(), mUnusedNodeIndices(),
- mNextUnusedNodeId(0), mDicNodesQueue() {
- mDicNodesBuf.resize(MAX_CAPACITY + 1);
- mUnusedNodeIndices.resize(MAX_CAPACITY + 1);
- reset();
+ AK_FORCE_INLINE explicit DicNodePriorityQueue(const int capacity)
+ : mCapacity(capacity), mMaxSize(capacity), mDicNodesBuf(),
+ mUnusedNodeIndices(), mNextUnusedNodeId(0), mDicNodesQueue() {
+ mDicNodesBuf.resize(mCapacity + 1);
+ mUnusedNodeIndices.resize(mCapacity + 1);
+ clearAndResizeToCapacity();
}
// Non virtual inline destructor -- never inherit this class
@@ -52,11 +48,12 @@ class DicNodePriorityQueue : public DicNodeReleaseListener {
}
AK_FORCE_INLINE void setMaxSize(const int maxSize) {
- mMaxSize = min(maxSize, MAX_CAPACITY);
+ ASSERT(maxSize <= mCapacity);
+ mMaxSize = min(maxSize, mCapacity);
}
- AK_FORCE_INLINE void reset() {
- clearAndResize(MAX_CAPACITY);
+ AK_FORCE_INLINE void clearAndResizeToCapacity() {
+ clearAndResize(mCapacity);
}
AK_FORCE_INLINE void clear() {
@@ -64,27 +61,19 @@ class DicNodePriorityQueue : public DicNodeReleaseListener {
}
AK_FORCE_INLINE void clearAndResize(const int maxSize) {
+ ASSERT(maxSize <= mCapacity);
while (!mDicNodesQueue.empty()) {
mDicNodesQueue.pop();
}
setMaxSize(maxSize);
- for (int i = 0; i < MAX_CAPACITY + 1; ++i) {
+ for (int i = 0; i < mCapacity + 1; ++i) {
mDicNodesBuf[i].remove();
mDicNodesBuf[i].setReleaseListener(this);
- mUnusedNodeIndices[i] = i == MAX_CAPACITY ? NOT_A_NODE_ID : static_cast<int>(i) + 1;
+ mUnusedNodeIndices[i] = i == mCapacity ? NOT_A_NODE_ID : static_cast<int>(i) + 1;
}
mNextUnusedNodeId = 0;
}
- AK_FORCE_INLINE DicNode *newDicNode(DicNode *dicNode) {
- DicNode *newNode = searchEmptyDicNode();
- if (newNode) {
- DicNodeUtils::initByCopy(dicNode, newNode);
- return newNode;
- }
- return 0;
- }
-
// Copy
AK_FORCE_INLINE DicNode *copyPush(DicNode *dicNode) {
return copyPush(dicNode, mMaxSize);
@@ -111,12 +100,12 @@ class DicNodePriorityQueue : public DicNodeReleaseListener {
}
mUnusedNodeIndices[index] = mNextUnusedNodeId;
mNextUnusedNodeId = index;
- ASSERT(index >= 0 && index < (MAX_CAPACITY + 1));
+ ASSERT(index >= 0 && index < (mCapacity + 1));
}
AK_FORCE_INLINE void dump() const {
AKLOGI("\n\n\n\n\n===========================");
- for (int i = 0; i < MAX_CAPACITY + 1; ++i) {
+ for (int i = 0; i < mCapacity + 1; ++i) {
if (mDicNodesBuf[i].isUsed()) {
mDicNodesBuf[i].dump("QUEUE: ");
}
@@ -125,7 +114,7 @@ class DicNodePriorityQueue : public DicNodeReleaseListener {
}
private:
- DISALLOW_COPY_AND_ASSIGN(DicNodePriorityQueue);
+ DISALLOW_IMPLICIT_CONSTRUCTORS(DicNodePriorityQueue);
static const int NOT_A_NODE_ID = -1;
AK_FORCE_INLINE static bool compareDicNode(DicNode *left, DicNode *right) {
@@ -139,7 +128,7 @@ class DicNodePriorityQueue : public DicNodeReleaseListener {
};
typedef std::priority_queue<DicNode *, std::vector<DicNode *>, DicNodeComparator> DicNodesQueue;
- const int MAX_CAPACITY;
+ const int mCapacity;
int mMaxSize;
std::vector<DicNode> mDicNodesBuf; // of each element of mDicNodesBuf respectively
std::vector<int> mUnusedNodeIndices;
@@ -163,13 +152,12 @@ class DicNodePriorityQueue : public DicNodeReleaseListener {
}
AK_FORCE_INLINE DicNode *searchEmptyDicNode() {
- // TODO: Currently O(n) but should be improved to O(1)
- if (MAX_CAPACITY == 0) {
+ if (mCapacity == 0) {
return 0;
}
if (mNextUnusedNodeId == NOT_A_NODE_ID) {
AKLOGI("No unused node found.");
- for (int i = 0; i < MAX_CAPACITY + 1; ++i) {
+ for (int i = 0; i < mCapacity + 1; ++i) {
AKLOGI("Dump node availability, %d, %d, %d",
i, mDicNodesBuf[i].isUsed(), mUnusedNodeIndices[i]);
}
@@ -185,7 +173,7 @@ class DicNodePriorityQueue : public DicNodeReleaseListener {
const int index = static_cast<int>(dicNode - &mDicNodesBuf[0]);
mNextUnusedNodeId = mUnusedNodeIndices[index];
mUnusedNodeIndices[index] = NOT_A_NODE_ID;
- ASSERT(index >= 0 && index < (MAX_CAPACITY + 1));
+ ASSERT(index >= 0 && index < (mCapacity + 1));
}
AK_FORCE_INLINE DicNode *pushPoolNodeWithMaxSize(DicNode *dicNode, const int maxSize) {
@@ -209,6 +197,15 @@ class DicNodePriorityQueue : public DicNodeReleaseListener {
AK_FORCE_INLINE DicNode *copyPush(DicNode *dicNode, const int maxSize) {
return pushPoolNodeWithMaxSize(newDicNode(dicNode), maxSize);
}
+
+ AK_FORCE_INLINE DicNode *newDicNode(DicNode *dicNode) {
+ DicNode *newNode = searchEmptyDicNode();
+ if (newNode) {
+ DicNodeUtils::initByCopy(dicNode, newNode);
+ }
+ return newNode;
+ }
+
};
} // namespace latinime
#endif // LATINIME_DIC_NODE_PRIORITY_QUEUE_H
diff --git a/native/jni/src/suggest/core/dicnode/dic_nodes_cache.h b/native/jni/src/suggest/core/dicnode/dic_nodes_cache.h
index 7aab0906e..f085848aa 100644
--- a/native/jni/src/suggest/core/dicnode/dic_nodes_cache.h
+++ b/native/jni/src/suggest/core/dicnode/dic_nodes_cache.h
@@ -32,24 +32,29 @@ class DicNode;
class DicNodesCache {
public:
AK_FORCE_INLINE DicNodesCache()
- : mActiveDicNodes(&mDicNodePriorityQueues[DIC_NODES_CACHE_INITIAL_QUEUE_ID_ACTIVE]),
- mNextActiveDicNodes(&mDicNodePriorityQueues[
- DIC_NODES_CACHE_INITIAL_QUEUE_ID_NEXT_ACTIVE]),
- mTerminalDicNodes(&mDicNodePriorityQueues[DIC_NODES_CACHE_INITIAL_QUEUE_ID_TERMINAL]),
- mCachedDicNodesForContinuousSuggestion(&mDicNodePriorityQueues[
- DIC_NODES_CACHE_INITIAL_QUEUE_ID_CACHE_FOR_CONTINUOUS_SUGGESTION]),
- mInputIndex(0), mLastCachedInputIndex(0) {
- }
+ : mDicNodePriorityQueue0(MAX_DIC_NODE_PRIORITY_QUEUE_CAPACITY),
+ mDicNodePriorityQueue1(MAX_DIC_NODE_PRIORITY_QUEUE_CAPACITY),
+ mDicNodePriorityQueue2(MAX_DIC_NODE_PRIORITY_QUEUE_CAPACITY),
+ mDicNodePriorityQueueForTerminal(MAX_RESULTS),
+ mActiveDicNodes(&mDicNodePriorityQueue0),
+ mNextActiveDicNodes(&mDicNodePriorityQueue1),
+ mCachedDicNodesForContinuousSuggestion(&mDicNodePriorityQueue2),
+ mTerminalDicNodes(&mDicNodePriorityQueueForTerminal),
+ mInputIndex(0), mLastCachedInputIndex(0) {}
AK_FORCE_INLINE virtual ~DicNodesCache() {}
AK_FORCE_INLINE void reset(const int nextActiveSize, const int terminalSize) {
mInputIndex = 0;
mLastCachedInputIndex = 0;
- mActiveDicNodes->reset();
+ // We want to use the max capacity for the current active dic node queue.
+ mActiveDicNodes->clearAndResizeToCapacity();
+ // nextActiveSize is used to limit the next iteration's active dic node size.
mNextActiveDicNodes->clearAndResize(nextActiveSize);
mTerminalDicNodes->clearAndResize(terminalSize);
- mCachedDicNodesForContinuousSuggestion->reset();
+ // We want to use the max capacity for the cached dic nodes that will be used for the
+ // continuous suggestion.
+ mCachedDicNodesForContinuousSuggestion->clearAndResizeToCapacity();
}
AK_FORCE_INLINE void continueSearch() {
@@ -163,15 +168,20 @@ class DicNodesCache {
mTerminalDicNodes->clear();
}
- DicNodePriorityQueue mDicNodePriorityQueues[DIC_NODES_CACHE_PRIORITY_QUEUES_SIZE];
+ // Instances
+ DicNodePriorityQueue mDicNodePriorityQueue0;
+ DicNodePriorityQueue mDicNodePriorityQueue1;
+ DicNodePriorityQueue mDicNodePriorityQueue2;
+ DicNodePriorityQueue mDicNodePriorityQueueForTerminal;
+
// Active dicNodes currently being expanded.
DicNodePriorityQueue *mActiveDicNodes;
// Next dicNodes to be expanded.
DicNodePriorityQueue *mNextActiveDicNodes;
- // Current top terminal dicNodes.
- DicNodePriorityQueue *mTerminalDicNodes;
// Cached dicNodes used for continuous suggestion.
DicNodePriorityQueue *mCachedDicNodesForContinuousSuggestion;
+ // Current top terminal dicNodes.
+ DicNodePriorityQueue *mTerminalDicNodes;
int mInputIndex;
int mLastCachedInputIndex;
};
diff --git a/native/jni/src/suggest/core/session/dic_traverse_session.cpp b/native/jni/src/suggest/core/session/dic_traverse_session.cpp
index 0ca583f90..e7b386b2d 100644
--- a/native/jni/src/suggest/core/session/dic_traverse_session.cpp
+++ b/native/jni/src/suggest/core/session/dic_traverse_session.cpp
@@ -59,8 +59,9 @@ const DictionaryStructureWithBufferPolicy *DicTraverseSession::getDictionaryStru
return mDictionary->getDictionaryStructurePolicy();
}
-void DicTraverseSession::resetCache(const int nextActiveCacheSize, const int maxWords) {
- mDicNodesCache.reset(nextActiveCacheSize, maxWords);
+void DicTraverseSession::resetCache(const int thresholdForNextActiveDicNodes, const int maxWords) {
+ mDicNodesCache.reset(thresholdForNextActiveDicNodes /* nextActiveSize */,
+ maxWords /* terminalSize */);
mMultiBigramMap.clear();
mPartiallyCommited = false;
}
diff --git a/native/jni/src/suggest/core/session/dic_traverse_session.h b/native/jni/src/suggest/core/session/dic_traverse_session.h
index 23de5cc65..b25580b96 100644
--- a/native/jni/src/suggest/core/session/dic_traverse_session.h
+++ b/native/jni/src/suggest/core/session/dic_traverse_session.h
@@ -73,7 +73,7 @@ class DicTraverseSession {
const int inputSize, const int *const inputXs, const int *const inputYs,
const int *const times, const int *const pointerIds, const float maxSpatialDistance,
const int maxPointerCount);
- void resetCache(const int nextActiveCacheSize, const int maxWords);
+ void resetCache(const int thresholdForNextActiveDicNodes, const int maxWords);
const DictionaryStructureWithBufferPolicy *getDictionaryStructurePolicy() const;