diff options
33 files changed, 304 insertions, 209 deletions
diff --git a/java/res/drawable-hdpi/ic_add_circle_wht_24dp.png b/java/res/drawable-hdpi/ic_add_circle_wht_24dp.png Binary files differnew file mode 100644 index 000000000..314c52137 --- /dev/null +++ b/java/res/drawable-hdpi/ic_add_circle_wht_24dp.png diff --git a/java/res/drawable-mdpi/ic_add_circle_wht_24dp.png b/java/res/drawable-mdpi/ic_add_circle_wht_24dp.png Binary files differnew file mode 100644 index 000000000..11363b173 --- /dev/null +++ b/java/res/drawable-mdpi/ic_add_circle_wht_24dp.png diff --git a/java/res/drawable-xhdpi/ic_add_circle_wht_24dp.png b/java/res/drawable-xhdpi/ic_add_circle_wht_24dp.png Binary files differnew file mode 100644 index 000000000..32a5b05ba --- /dev/null +++ b/java/res/drawable-xhdpi/ic_add_circle_wht_24dp.png diff --git a/java/res/drawable-xxhdpi/ic_add_circle_wht_24dp.png b/java/res/drawable-xxhdpi/ic_add_circle_wht_24dp.png Binary files differnew file mode 100644 index 000000000..a22c463f9 --- /dev/null +++ b/java/res/drawable-xxhdpi/ic_add_circle_wht_24dp.png diff --git a/java/res/drawable/btn_keyboard_key_lxx_dark.xml b/java/res/drawable/btn_keyboard_key_lxx_dark.xml index bb1789ae3..c82c13829 100644 --- a/java/res/drawable/btn_keyboard_key_lxx_dark.xml +++ b/java/res/drawable/btn_keyboard_key_lxx_dark.xml @@ -15,6 +15,11 @@ --> <selector xmlns:android="http://schemas.android.com/apk/res/android"> + <!-- Custom label action keys. --> + <item android:state_active="true" android:state_checked="true" android:state_pressed="true" + android:drawable="@color/key_background_pressed_lxx_dark" /> + <item android:state_active="true" android:state_checked="true" + android:drawable="@color/key_background_lxx_dark" /> <!-- Action keys. --> <item android:state_active="true" android:state_pressed="true" android:drawable="@drawable/btn_keyboard_key_active_pressed_lxx_dark" /> diff --git a/java/res/drawable/btn_keyboard_key_lxx_light.xml b/java/res/drawable/btn_keyboard_key_lxx_light.xml index 60fe02dd2..f237fbea9 100644 --- a/java/res/drawable/btn_keyboard_key_lxx_light.xml +++ b/java/res/drawable/btn_keyboard_key_lxx_light.xml @@ -15,6 +15,11 @@ --> <selector xmlns:android="http://schemas.android.com/apk/res/android"> + <!-- Custom label action keys. --> + <item android:state_active="true" android:state_checked="true" android:state_pressed="true" + android:drawable="@color/key_background_pressed_lxx_light" /> + <item android:state_active="true" android:state_checked="true" + android:drawable="@color/key_background_lxx_light" /> <!-- Action keys. --> <item android:state_active="true" android:state_pressed="true" android:drawable="@drawable/btn_keyboard_key_active_pressed_lxx_light" /> diff --git a/java/res/menu/add_style.xml b/java/res/menu/add_style.xml new file mode 100644 index 000000000..d1cab4bb5 --- /dev/null +++ b/java/res/menu/add_style.xml @@ -0,0 +1,26 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- +/* +** +** Copyright 2014, 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. +*/ +--> +<menu xmlns:android="http://schemas.android.com/apk/res/android"> + <item + android:id="@+id/action_add_style" + android:icon="@drawable/ic_add_circle_wht_24dp" + android:title="@string/add_style" + android:showAsAction="always" /> +</menu>
\ No newline at end of file diff --git a/java/res/values/attrs.xml b/java/res/values/attrs.xml index 9a2227321..e6215c254 100644 --- a/java/res/values/attrs.xml +++ b/java/res/values/attrs.xml @@ -270,9 +270,10 @@ <enum name="empty" value="0" /> <enum name="normal" value="1" /> <enum name="functional" value="2" /> - <enum name="action" value="3" /> - <enum name="stickyOff" value="4" /> - <enum name="stickyOn" value="5" /> + <enum name="stickyOff" value="3" /> + <enum name="stickyOn" value="4" /> + <enum name="action" value="5" /> + <enum name="customAction" value="6" /> </attr> <!-- The key action flags. --> <attr name="keyActionFlags" format="integer"> diff --git a/java/res/xml-sw600dp/key_styles_enter.xml b/java/res/xml-sw600dp/key_styles_enter.xml index 740bf3543..d0167d336 100644 --- a/java/res/xml-sw600dp/key_styles_enter.xml +++ b/java/res/xml-sw600dp/key_styles_enter.xml @@ -230,6 +230,7 @@ latin:styleName="enterKeyStyle" latin:keySpec="dummy_label|!code/key_enter" latin:keyLabelFlags="fromCustomActionLabel" + latin:backgroundType="customAction" latin:parentStyle="defaultEnterKeyStyle" /> </case> <!-- imeAction is either actionNone or actionUnspecified. --> diff --git a/java/res/xml/key_styles_enter.xml b/java/res/xml/key_styles_enter.xml index 770bf3876..960c79c18 100644 --- a/java/res/xml/key_styles_enter.xml +++ b/java/res/xml/key_styles_enter.xml @@ -398,6 +398,7 @@ latin:styleName="enterKeyStyle" latin:keySpec="dummy_label|!code/key_enter" latin:keyLabelFlags="fromCustomActionLabel" + latin:backgroundType="customAction" latin:parentStyle="defaultEnterKeyStyle" /> </case> <!-- imeAction is either actionNone or actionUnspecified. --> diff --git a/java/res/xml/method.xml b/java/res/xml/method.xml index 5021f33ee..cfe25d1c4 100644 --- a/java/res/xml/method.xml +++ b/java/res/xml/method.xml @@ -51,7 +51,7 @@ fr_CH: French (Switzerland)/swiss gl_ES: Galician (Spain)/spanish hi: Hindi/hindi - (hi: Hindi/hindi_compact) # This is a preliminary keyboard layout. + hi: Hindi/hindi_compact hr: Croatian/qwertz hu: Hungarian/qwertz hy_AM: Armenian (Armenia) Phonetic/armenian_phonetic @@ -346,8 +346,6 @@ android:imeSubtypeExtraValue="KeyboardLayoutSet=hindi,EmojiCapable" android:isAsciiCapable="false" /> - <!-- TODO: This hindi_compact keyboard is a preliminary layout. - This isn't based on the final specification. --> <subtype android:icon="@drawable/ic_ime_switcher_dark" android:label="@string/subtype_generic_compact" android:subtypeId="0xe49c89a1" diff --git a/java/src/com/android/inputmethod/keyboard/Key.java b/java/src/com/android/inputmethod/keyboard/Key.java index af54fb674..55ce7dd34 100644 --- a/java/src/com/android/inputmethod/keyboard/Key.java +++ b/java/src/com/android/inputmethod/keyboard/Key.java @@ -123,9 +123,10 @@ public class Key implements Comparable<Key> { public static final int BACKGROUND_TYPE_EMPTY = 0; public static final int BACKGROUND_TYPE_NORMAL = 1; public static final int BACKGROUND_TYPE_FUNCTIONAL = 2; - public static final int BACKGROUND_TYPE_ACTION = 3; - public static final int BACKGROUND_TYPE_STICKY_OFF = 4; - public static final int BACKGROUND_TYPE_STICKY_ON = 5; + public static final int BACKGROUND_TYPE_STICKY_OFF = 3; + public static final int BACKGROUND_TYPE_STICKY_ON = 4; + public static final int BACKGROUND_TYPE_ACTION = 5; + public static final int BACKGROUND_TYPE_CUSTOM_ACTION = 6; private final int mActionFlags; private static final int ACTION_FLAGS_IS_REPEATABLE = 0x01; @@ -483,9 +484,10 @@ public class Key implements Comparable<Key> { case BACKGROUND_TYPE_EMPTY: return "empty"; case BACKGROUND_TYPE_NORMAL: return "normal"; case BACKGROUND_TYPE_FUNCTIONAL: return "functional"; - case BACKGROUND_TYPE_ACTION: return "action"; case BACKGROUND_TYPE_STICKY_OFF: return "stickyOff"; case BACKGROUND_TYPE_STICKY_ON: return "stickyOn"; + case BACKGROUND_TYPE_ACTION: return "action"; + case BACKGROUND_TYPE_CUSTOM_ACTION: return "customAction"; default: return null; } } @@ -814,47 +816,37 @@ public class Key implements Comparable<Key> { return dx * dx + dy * dy; } - private final static int[] KEY_STATE_NORMAL_HIGHLIGHT_ON = { - android.R.attr.state_checkable, - android.R.attr.state_checked - }; - - private final static int[] KEY_STATE_PRESSED_HIGHLIGHT_ON = { - android.R.attr.state_pressed, - android.R.attr.state_checkable, - android.R.attr.state_checked - }; - - private final static int[] KEY_STATE_NORMAL_HIGHLIGHT_OFF = { - android.R.attr.state_checkable - }; - - private final static int[] KEY_STATE_PRESSED_HIGHLIGHT_OFF = { - android.R.attr.state_pressed, - android.R.attr.state_checkable - }; - - private final static int[] KEY_STATE_NORMAL = { - }; + static class KeyBackgroundState { + private final int[] mReleasedState; + private final int[] mPressedState; - private final static int[] KEY_STATE_PRESSED = { - android.R.attr.state_pressed - }; - - private final static int[] KEY_STATE_EMPTY = { - android.R.attr.state_empty - }; + private KeyBackgroundState(final int ... attrs) { + mReleasedState = attrs; + mPressedState = Arrays.copyOf(attrs, attrs.length + 1); + mPressedState[attrs.length] = android.R.attr.state_pressed; + } - // action normal state (with properties) - private static final int[] KEY_STATE_ACTIVE_NORMAL = { - android.R.attr.state_active - }; + public int[] getState(final boolean pressed) { + return pressed ? mPressedState : mReleasedState; + } - // action pressed state (with properties) - private static final int[] KEY_STATE_ACTIVE_PRESSED = { - android.R.attr.state_active, - android.R.attr.state_pressed - }; + public static final KeyBackgroundState[] STATES = { + // 0: BACKGROUND_TYPE_EMPTY + new KeyBackgroundState(android.R.attr.state_empty), + // 1: BACKGROUND_TYPE_NORMAL + new KeyBackgroundState(), + // 2: BACKGROUND_TYPE_FUNCTIONAL + new KeyBackgroundState(), + // 3: BACKGROUND_TYPE_STICKY_OFF + new KeyBackgroundState(android.R.attr.state_checkable), + // 4: BACKGROUND_TYPE_STICKY_ON + new KeyBackgroundState(android.R.attr.state_checkable, android.R.attr.state_checked), + // 5: BACKGROUND_TYPE_ACTION + new KeyBackgroundState(android.R.attr.state_active), + // 6: BACKGROUND_TYPE_CUSTOM_ACTION + new KeyBackgroundState(android.R.attr.state_active, android.R.attr.state_checked) + }; + } /** * Returns the background drawable for the key, based on the current state and type of the key. @@ -871,28 +863,8 @@ public class Key implements Comparable<Key> { } else { background = keyBackground; } - final int[] stateSet; - switch (mBackgroundType) { - case BACKGROUND_TYPE_ACTION: - stateSet = mPressed ? KEY_STATE_ACTIVE_PRESSED : KEY_STATE_ACTIVE_NORMAL; - break; - case BACKGROUND_TYPE_STICKY_OFF: - stateSet = mPressed ? KEY_STATE_PRESSED_HIGHLIGHT_OFF : KEY_STATE_NORMAL_HIGHLIGHT_OFF; - break; - case BACKGROUND_TYPE_STICKY_ON: - stateSet = mPressed ? KEY_STATE_PRESSED_HIGHLIGHT_ON : KEY_STATE_NORMAL_HIGHLIGHT_ON; - break; - case BACKGROUND_TYPE_EMPTY: - stateSet = mPressed ? KEY_STATE_PRESSED : KEY_STATE_EMPTY; - break; - case BACKGROUND_TYPE_FUNCTIONAL: - stateSet = mPressed ? KEY_STATE_PRESSED : KEY_STATE_NORMAL; - break; - default: /* BACKGROUND_TYPE_NORMAL */ - stateSet = mPressed ? KEY_STATE_PRESSED : KEY_STATE_NORMAL; - break; - } - background.setState(stateSet); + final int[] state = KeyBackgroundState.STATES[mBackgroundType].getState(mPressed); + background.setState(state); return background; } diff --git a/java/src/com/android/inputmethod/latin/LatinIME.java b/java/src/com/android/inputmethod/latin/LatinIME.java index 4adc28d7a..f67c2a356 100644 --- a/java/src/com/android/inputmethod/latin/LatinIME.java +++ b/java/src/com/android/inputmethod/latin/LatinIME.java @@ -752,30 +752,8 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen loadKeyboard(); } - /** - * A class that holds information to pass from onStartInputInternal to onStartInputViewInternal - * - * OnStartInput needs to reload the settings and that will prevent onStartInputViewInternal - * from comparing the old settings with the new ones, so we use this memory to pass the - * necessary information along. - */ - private static class EditorChangeInfo { - public final boolean mIsSameInputType; - public final boolean mHasSameOrientation; - public EditorChangeInfo(final boolean isSameInputType, final boolean hasSameOrientation) { - mIsSameInputType = isSameInputType; - mHasSameOrientation = hasSameOrientation; - } - } - - private EditorChangeInfo mLastEditorChangeInfo; - private void onStartInputInternal(final EditorInfo editorInfo, final boolean restarting) { super.onStartInput(editorInfo, restarting); - SettingsValues currentSettingsValues = mSettings.getCurrent(); - mLastEditorChangeInfo = new EditorChangeInfo( - currentSettingsValues.isSameInputType(editorInfo), - currentSettingsValues.hasSameOrientation(getResources().getConfiguration())); } @SuppressWarnings("deprecation") @@ -785,6 +763,9 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen final KeyboardSwitcher switcher = mKeyboardSwitcher; switcher.updateKeyboardTheme(); final MainKeyboardView mainKeyboardView = switcher.getMainKeyboardView(); + // If we are starting input in a different text field from before, we'll have to reload + // settings, so currentSettingsValues can't be final. + SettingsValues currentSettingsValues = mSettings.getCurrent(); if (editorInfo == null) { Log.e(TAG, "Null EditorInfo in onStartInputView()"); @@ -827,7 +808,7 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen accessUtils.onStartInputViewInternal(mainKeyboardView, editorInfo, restarting); } - final boolean inputTypeChanged = !mLastEditorChangeInfo.mIsSameInputType; + final boolean inputTypeChanged = !currentSettingsValues.isSameInputType(editorInfo); final boolean isDifferentTextField = !restarting || inputTypeChanged; if (isDifferentTextField) { mSubtypeSwitcher.updateParametersOnStartInputView(); @@ -872,12 +853,13 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen canReachInputConnection = true; } - if (isDifferentTextField || !mLastEditorChangeInfo.mHasSameOrientation) { + if (isDifferentTextField || + !currentSettingsValues.hasSameOrientation(getResources().getConfiguration())) { loadSettings(); } - final SettingsValues currentSettingsValues = mSettings.getCurrent(); if (isDifferentTextField) { mainKeyboardView.closing(); + currentSettingsValues = mSettings.getCurrent(); if (currentSettingsValues.mAutoCorrectionEnabledPerUserSettings) { suggest.setAutoCorrectionThreshold( @@ -1250,10 +1232,26 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen mSubtypeState.switchSubtype(token, mRichImm); } + // TODO: Instead of checking for alphabetic keyboard here, separate keycodes for + // alphabetic shift and shift while in symbol layout and get rid of this method. + private int getCodePointForKeyboard(final int codePoint) { + if (Constants.CODE_SHIFT == codePoint) { + final Keyboard currentKeyboard = mKeyboardSwitcher.getKeyboard(); + if (null != currentKeyboard && currentKeyboard.mId.isAlphabetKeyboard()) { + return codePoint; + } else { + return Constants.CODE_SYMBOL_SHIFT; + } + } else { + return codePoint; + } + } + // Implementation of {@link KeyboardActionListener}. @Override public void onCodeInput(final int codePoint, final int x, final int y, final boolean isKeyRepeat) { + // TODO: this processing does not belong inside LatinIME, the caller should be doing this. final MainKeyboardView mainKeyboardView = mKeyboardSwitcher.getMainKeyboardView(); // x and y include some padding, but everything down the line (especially native // code) needs the coordinates in the keyboard frame. @@ -1262,30 +1260,23 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen // this transformation, it should be done already before calling onCodeInput. final int keyX = mainKeyboardView.getKeyX(x); final int keyY = mainKeyboardView.getKeyY(y); - final int codeToSend; - if (Constants.CODE_SHIFT == codePoint) { - // TODO: Instead of checking for alphabetic keyboard here, separate keycodes for - // alphabetic shift and shift while in symbol layout. - final Keyboard currentKeyboard = mKeyboardSwitcher.getKeyboard(); - if (null != currentKeyboard && currentKeyboard.mId.isAlphabetKeyboard()) { - codeToSend = codePoint; - } else { - codeToSend = Constants.CODE_SYMBOL_SHIFT; - } - } else { - codeToSend = codePoint; - } - if (Constants.CODE_SHORTCUT == codePoint) { + final Event event = createSoftwareKeypressEvent(getCodePointForKeyboard(codePoint), + keyX, keyY, isKeyRepeat); + onEvent(event); + } + + // This method is public for testability of LatinIME, but also in the future it should + // completely replace #onCodeInput. + public void onEvent(final Event event) { + if (Constants.CODE_SHORTCUT == event.mCodePoint) { mSubtypeSwitcher.switchToShortcutIME(this); - // Still call the *#onCodeInput methods for readability. } - final Event event = createSoftwareKeypressEvent(codeToSend, keyX, keyY, isKeyRepeat); final InputTransaction completeInputTransaction = mInputLogic.onCodeInput(mSettings.getCurrent(), event, mKeyboardSwitcher.getKeyboardShiftMode(), mKeyboardSwitcher.getCurrentKeyboardScriptId(), mHandler); updateStateAfterInputTransaction(completeInputTransaction); - mKeyboardSwitcher.onCodeInput(codePoint, getCurrentAutoCapsState(), + mKeyboardSwitcher.onCodeInput(event.mCodePoint, getCurrentAutoCapsState(), getCurrentRecapitalizeState()); } diff --git a/java/src/com/android/inputmethod/latin/RichInputConnection.java b/java/src/com/android/inputmethod/latin/RichInputConnection.java index a6b3b710b..ea63cef02 100644 --- a/java/src/com/android/inputmethod/latin/RichInputConnection.java +++ b/java/src/com/android/inputmethod/latin/RichInputConnection.java @@ -17,6 +17,7 @@ package com.android.inputmethod.latin; import android.inputmethodservice.InputMethodService; +import android.os.Build; import android.text.TextUtils; import android.util.Log; import android.view.KeyEvent; @@ -811,4 +812,25 @@ public final class RichInputConnection { public boolean isCursorPositionKnown() { return INVALID_CURSOR_POSITION != mExpectedSelStart; } + + /** + * Work around a bug that was present before Jelly Bean upon rotation. + * + * Before Jelly Bean, there is a bug where setComposingRegion and other committing + * functions on the input connection get ignored until the cursor moves. This method works + * around the bug by wiggling the cursor first, which reactivates the connection and has + * the subsequent methods work, then restoring it to its original position. + * + * On platforms on which this method is not present, this is a no-op. + */ + public void maybeMoveTheCursorAroundAndRestoreToWorkaroundABug() { + if (Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN) { + if (mExpectedSelStart > 0) { + mIC.setSelection(mExpectedSelStart - 1, mExpectedSelStart - 1); + } else { + mIC.setSelection(mExpectedSelStart + 1, mExpectedSelStart + 1); + } + mIC.setSelection(mExpectedSelStart, mExpectedSelEnd); + } + } } diff --git a/java/src/com/android/inputmethod/latin/inputlogic/InputLogic.java b/java/src/com/android/inputmethod/latin/inputlogic/InputLogic.java index 97457b2f7..418866ae1 100644 --- a/java/src/com/android/inputmethod/latin/inputlogic/InputLogic.java +++ b/java/src/com/android/inputmethod/latin/inputlogic/InputLogic.java @@ -1437,6 +1437,7 @@ public final class InputLogic { mLatinIME.getCoordinatesForCurrentKeyboard(codePoints)); mWordComposer.setCursorPositionWithinWord( typedWord.codePointCount(0, numberOfCharsInWordBeforeCursor)); + mConnection.maybeMoveTheCursorAroundAndRestoreToWorkaroundABug(); mConnection.setComposingRegion(expectedCursorPosition - numberOfCharsInWordBeforeCursor, expectedCursorPosition + range.getNumberOfCharsInWordAfterCursor()); if (suggestions.size() <= (shouldIncludeResumedWordInSuggestions ? 1 : 0)) { diff --git a/java/src/com/android/inputmethod/latin/settings/CustomInputStyleSettingsFragment.java b/java/src/com/android/inputmethod/latin/settings/CustomInputStyleSettingsFragment.java index 21f2afd01..6d7f53cf0 100644 --- a/java/src/com/android/inputmethod/latin/settings/CustomInputStyleSettingsFragment.java +++ b/java/src/com/android/inputmethod/latin/settings/CustomInputStyleSettingsFragment.java @@ -63,7 +63,6 @@ public final class CustomInputStyleSettingsFragment extends PreferenceFragment { private AlertDialog mSubtypeEnablerNotificationDialog; private String mSubtypePreferenceKeyForSubtypeEnabler; - private static final int MENU_ADD_SUBTYPE = Menu.FIRST; private static final String KEY_IS_ADDING_NEW_SUBTYPE = "is_adding_new_subtype"; private static final String KEY_IS_SUBTYPE_ENABLER_NOTIFICATION_DIALOG_OPEN = "is_subtype_enabler_notification_dialog_open"; @@ -581,14 +580,13 @@ public final class CustomInputStyleSettingsFragment extends PreferenceFragment { @Override public void onCreateOptionsMenu(final Menu menu, final MenuInflater inflater) { - final MenuItem addSubtypeMenu = menu.add(0, MENU_ADD_SUBTYPE, 0, R.string.add_style); - addSubtypeMenu.setShowAsAction(MenuItem.SHOW_AS_ACTION_IF_ROOM); + inflater.inflate(R.menu.add_style, menu); } @Override public boolean onOptionsItemSelected(final MenuItem item) { final int itemId = item.getItemId(); - if (itemId == MENU_ADD_SUBTYPE) { + if (itemId == R.id.action_add_style) { final SubtypePreference newSubtype = SubtypePreference.newIncompleteSubtypePreference(getActivity(), mSubtypeProxy); getPreferenceScreen().addPreference(newSubtype); diff --git a/native/jni/src/suggest/policyimpl/dictionary/structure/backward/v402/ver4_patricia_trie_node_writer.cpp b/native/jni/src/suggest/policyimpl/dictionary/structure/backward/v402/ver4_patricia_trie_node_writer.cpp index 4220a9561..278f2b199 100644 --- a/native/jni/src/suggest/policyimpl/dictionary/structure/backward/v402/ver4_patricia_trie_node_writer.cpp +++ b/native/jni/src/suggest/policyimpl/dictionary/structure/backward/v402/ver4_patricia_trie_node_writer.cpp @@ -231,30 +231,31 @@ bool Ver4PatriciaTrieNodeWriter::writeNewTerminalPtNodeAndAdvancePosition( &probabilityEntryToWrite); } -bool Ver4PatriciaTrieNodeWriter::addNewBigramEntry( - const PtNodeParams *const sourcePtNodeParams, const PtNodeParams *const targetPtNodeParam, - const BigramProperty *const bigramProperty, bool *const outAddedNewBigram) { - if (!mBigramPolicy->addNewEntry(sourcePtNodeParams->getTerminalId(), - targetPtNodeParam->getTerminalId(), bigramProperty, outAddedNewBigram)) { +bool Ver4PatriciaTrieNodeWriter::addNgramEntry(const WordIdArrayView prevWordIds, const int wordId, + const BigramProperty *const bigramProperty, bool *const outAddedNewEntry) { + if (!mBigramPolicy->addNewEntry(prevWordIds[0], wordId, bigramProperty, outAddedNewEntry)) { AKLOGE("Cannot add new bigram entry. terminalId: %d, targetTerminalId: %d", sourcePtNodeParams->getTerminalId(), targetPtNodeParam->getTerminalId()); return false; } - if (!sourcePtNodeParams->hasBigrams()) { + const int ptNodePos = + mBuffers->getTerminalPositionLookupTable()->getTerminalPtNodePosition(prevWordIds[0]); + const PtNodeParams sourcePtNodeParams = + mPtNodeReader->fetchPtNodeParamsInBufferFromPtNodePos(ptNodePos); + if (!sourcePtNodeParams.hasBigrams()) { // Update has bigrams flag. - return updatePtNodeFlags(sourcePtNodeParams->getHeadPos(), - sourcePtNodeParams->isBlacklisted(), sourcePtNodeParams->isNotAWord(), - sourcePtNodeParams->isTerminal(), sourcePtNodeParams->hasShortcutTargets(), + return updatePtNodeFlags(sourcePtNodeParams.getHeadPos(), + sourcePtNodeParams.isBlacklisted(), sourcePtNodeParams.isNotAWord(), + sourcePtNodeParams.isTerminal(), sourcePtNodeParams.hasShortcutTargets(), true /* hasBigrams */, - sourcePtNodeParams->getCodePointCount() > 1 /* hasMultipleChars */); + sourcePtNodeParams.getCodePointCount() > 1 /* hasMultipleChars */); } return true; } -bool Ver4PatriciaTrieNodeWriter::removeBigramEntry( - const PtNodeParams *const sourcePtNodeParams, const PtNodeParams *const targetPtNodeParam) { - return mBigramPolicy->removeEntry(sourcePtNodeParams->getTerminalId(), - targetPtNodeParam->getTerminalId()); +bool Ver4PatriciaTrieNodeWriter::removeNgramEntry(const WordIdArrayView prevWordIds, + const int wordId) { + return mBigramPolicy->removeEntry(prevWordIds[0], wordId); } bool Ver4PatriciaTrieNodeWriter::updateAllBigramEntriesAndDeleteUselessEntries( diff --git a/native/jni/src/suggest/policyimpl/dictionary/structure/backward/v402/ver4_patricia_trie_node_writer.h b/native/jni/src/suggest/policyimpl/dictionary/structure/backward/v402/ver4_patricia_trie_node_writer.h index 08226ea26..d49d9a666 100644 --- a/native/jni/src/suggest/policyimpl/dictionary/structure/backward/v402/ver4_patricia_trie_node_writer.h +++ b/native/jni/src/suggest/policyimpl/dictionary/structure/backward/v402/ver4_patricia_trie_node_writer.h @@ -29,6 +29,7 @@ #include "suggest/policyimpl/dictionary/structure/pt_common/pt_node_params.h" #include "suggest/policyimpl/dictionary/structure/pt_common/pt_node_writer.h" #include "suggest/policyimpl/dictionary/structure/backward/v402/content/probability_entry.h" +#include "utils/int_array_view.h" namespace latinime { namespace backward { @@ -61,8 +62,8 @@ class Ver4PatriciaTrieNodeWriter : public PtNodeWriter { const PtNodeArrayReader *const ptNodeArrayReader, Ver4BigramListPolicy *const bigramPolicy, Ver4ShortcutListPolicy *const shortcutPolicy) : mTrieBuffer(trieBuffer), mBuffers(buffers), mHeaderPolicy(headerPolicy), - mReadingHelper(ptNodeReader, ptNodeArrayReader), mBigramPolicy(bigramPolicy), - mShortcutPolicy(shortcutPolicy) {} + mPtNodeReader(ptNodeReader), mReadingHelper(ptNodeReader, ptNodeArrayReader), + mBigramPolicy(bigramPolicy), mShortcutPolicy(shortcutPolicy) {} virtual ~Ver4PatriciaTrieNodeWriter() {} @@ -92,12 +93,10 @@ class Ver4PatriciaTrieNodeWriter : public PtNodeWriter { virtual bool writeNewTerminalPtNodeAndAdvancePosition(const PtNodeParams *const ptNodeParams, const UnigramProperty *const unigramProperty, int *const ptNodeWritingPos); - virtual bool addNewBigramEntry(const PtNodeParams *const sourcePtNodeParams, - const PtNodeParams *const targetPtNodeParam, const BigramProperty *const bigramProperty, - bool *const outAddedNewBigram); + virtual bool addNgramEntry(const WordIdArrayView prevWordIds, const int wordId, + const BigramProperty *const bigramProperty, bool *const outAddedNewEntry); - virtual bool removeBigramEntry(const PtNodeParams *const sourcePtNodeParams, - const PtNodeParams *const targetPtNodeParam); + virtual bool removeNgramEntry(const WordIdArrayView prevWordIds, const int wordId); virtual bool updateAllBigramEntriesAndDeleteUselessEntries( const PtNodeParams *const sourcePtNodeParams, int *const outBigramEntryCount); @@ -135,6 +134,7 @@ class Ver4PatriciaTrieNodeWriter : public PtNodeWriter { BufferWithExtendableBuffer *const mTrieBuffer; Ver4DictBuffers *const mBuffers; const HeaderPolicy *const mHeaderPolicy; + const PtNodeReader *const mPtNodeReader; DynamicPtReadingHelper mReadingHelper; Ver4BigramListPolicy *const mBigramPolicy; Ver4ShortcutListPolicy *const mShortcutPolicy; diff --git a/native/jni/src/suggest/policyimpl/dictionary/structure/backward/v402/ver4_patricia_trie_policy.cpp b/native/jni/src/suggest/policyimpl/dictionary/structure/backward/v402/ver4_patricia_trie_policy.cpp index baa0c0c37..1296b8acd 100644 --- a/native/jni/src/suggest/policyimpl/dictionary/structure/backward/v402/ver4_patricia_trie_policy.cpp +++ b/native/jni/src/suggest/policyimpl/dictionary/structure/backward/v402/ver4_patricia_trie_policy.cpp @@ -309,8 +309,8 @@ bool Ver4PatriciaTriePolicy::addNgramEntry(const PrevWordsInfo *const prevWordsI return false; } bool addedNewBigram = false; - if (mUpdatingHelper.addBigramWords(prevWordsPtNodePos[0], word1Pos, bigramProperty, - &addedNewBigram)) { + if (mUpdatingHelper.addNgramEntry(PtNodePosArrayView::fromObject(prevWordsPtNodePos), + word1Pos, bigramProperty, &addedNewBigram)) { if (addedNewBigram) { mBigramCount++; } @@ -350,7 +350,8 @@ bool Ver4PatriciaTriePolicy::removeNgramEntry(const PrevWordsInfo *const prevWor if (wordPos == NOT_A_DICT_POS) { return false; } - if (mUpdatingHelper.removeBigramWords(prevWordsPtNodePos[0], wordPos)) { + if (mUpdatingHelper.removeNgramEntry( + PtNodePosArrayView::fromObject(prevWordsPtNodePos), wordPos)) { mBigramCount--; return true; } else { diff --git a/native/jni/src/suggest/policyimpl/dictionary/structure/pt_common/dynamic_pt_updating_helper.cpp b/native/jni/src/suggest/policyimpl/dictionary/structure/pt_common/dynamic_pt_updating_helper.cpp index f31c914d2..3c62e2e56 100644 --- a/native/jni/src/suggest/policyimpl/dictionary/structure/pt_common/dynamic_pt_updating_helper.cpp +++ b/native/jni/src/suggest/policyimpl/dictionary/structure/pt_common/dynamic_pt_updating_helper.cpp @@ -84,23 +84,39 @@ bool DynamicPtUpdatingHelper::addUnigramWord( unigramProperty, &pos); } -bool DynamicPtUpdatingHelper::addBigramWords(const int word0Pos, const int word1Pos, - const BigramProperty *const bigramProperty, bool *const outAddedNewBigram) { - const PtNodeParams sourcePtNodeParams( - mPtNodeReader->fetchPtNodeParamsInBufferFromPtNodePos(word0Pos)); - const PtNodeParams targetPtNodeParams( - mPtNodeReader->fetchPtNodeParamsInBufferFromPtNodePos(word1Pos)); - return mPtNodeWriter->addNewBigramEntry(&sourcePtNodeParams, &targetPtNodeParams, - bigramProperty, outAddedNewBigram); +bool DynamicPtUpdatingHelper::addNgramEntry(const PtNodePosArrayView prevWordsPtNodePos, + const int wordPos, const BigramProperty *const bigramProperty, + bool *const outAddedNewEntry) { + if (prevWordsPtNodePos.empty()) { + return false; + } + ASSERT(prevWordsPtNodePos.size() <= MAX_PREV_WORD_COUNT_FOR_N_GRAM); + int prevWordTerminalIds[MAX_PREV_WORD_COUNT_FOR_N_GRAM]; + for (size_t i = 0; i < prevWordsPtNodePos.size(); ++i) { + prevWordTerminalIds[i] = mPtNodeReader->fetchPtNodeParamsInBufferFromPtNodePos( + prevWordsPtNodePos[i]).getTerminalId(); + } + const WordIdArrayView prevWordIds(prevWordTerminalIds, prevWordsPtNodePos.size()); + const int wordId = + mPtNodeReader->fetchPtNodeParamsInBufferFromPtNodePos(wordPos).getTerminalId(); + return mPtNodeWriter->addNgramEntry(prevWordIds, wordId, bigramProperty, outAddedNewEntry); } -// Remove a bigram relation from word0Pos to word1Pos. -bool DynamicPtUpdatingHelper::removeBigramWords(const int word0Pos, const int word1Pos) { - const PtNodeParams sourcePtNodeParams( - mPtNodeReader->fetchPtNodeParamsInBufferFromPtNodePos(word0Pos)); - const PtNodeParams targetPtNodeParams( - mPtNodeReader->fetchPtNodeParamsInBufferFromPtNodePos(word1Pos)); - return mPtNodeWriter->removeBigramEntry(&sourcePtNodeParams, &targetPtNodeParams); +bool DynamicPtUpdatingHelper::removeNgramEntry(const PtNodePosArrayView prevWordsPtNodePos, + const int wordPos) { + if (prevWordsPtNodePos.empty()) { + return false; + } + ASSERT(prevWordsPtNodePos.size() <= MAX_PREV_WORD_COUNT_FOR_N_GRAM); + int prevWordTerminalIds[MAX_PREV_WORD_COUNT_FOR_N_GRAM]; + for (size_t i = 0; i < prevWordsPtNodePos.size(); ++i) { + prevWordTerminalIds[i] = mPtNodeReader->fetchPtNodeParamsInBufferFromPtNodePos( + prevWordsPtNodePos[i]).getTerminalId(); + } + const WordIdArrayView prevWordIds(prevWordTerminalIds, prevWordsPtNodePos.size()); + const int wordId = + mPtNodeReader->fetchPtNodeParamsInBufferFromPtNodePos(wordPos).getTerminalId(); + return mPtNodeWriter->removeNgramEntry(prevWordIds, wordId); } bool DynamicPtUpdatingHelper::addShortcutTarget(const int wordPos, diff --git a/native/jni/src/suggest/policyimpl/dictionary/structure/pt_common/dynamic_pt_updating_helper.h b/native/jni/src/suggest/policyimpl/dictionary/structure/pt_common/dynamic_pt_updating_helper.h index f10d15a9b..97c05c1ea 100644 --- a/native/jni/src/suggest/policyimpl/dictionary/structure/pt_common/dynamic_pt_updating_helper.h +++ b/native/jni/src/suggest/policyimpl/dictionary/structure/pt_common/dynamic_pt_updating_helper.h @@ -19,6 +19,7 @@ #include "defines.h" #include "suggest/policyimpl/dictionary/structure/pt_common/pt_node_params.h" +#include "utils/int_array_view.h" namespace latinime { @@ -42,12 +43,12 @@ class DynamicPtUpdatingHelper { const int *const wordCodePoints, const int codePointCount, const UnigramProperty *const unigramProperty, bool *const outAddedNewUnigram); - // Add a bigram relation from word0Pos to word1Pos. - bool addBigramWords(const int word0Pos, const int word1Pos, - const BigramProperty *const bigramProperty, bool *const outAddedNewBigram); + // Add an n-gram entry. + bool addNgramEntry(const PtNodePosArrayView prevWordsPtNodePos, const int wordPos, + const BigramProperty *const bigramProperty, bool *const outAddedNewEntry); - // Remove a bigram relation from word0Pos to word1Pos. - bool removeBigramWords(const int word0Pos, const int word1Pos); + // Remove an n-gram entry. + bool removeNgramEntry(const PtNodePosArrayView prevWordsPtNodePos, const int wordPos); // Add a shortcut target. bool addShortcutTarget(const int wordPos, const int *const targetCodePoints, diff --git a/native/jni/src/suggest/policyimpl/dictionary/structure/pt_common/pt_node_writer.h b/native/jni/src/suggest/policyimpl/dictionary/structure/pt_common/pt_node_writer.h index a8029f73f..955d779ac 100644 --- a/native/jni/src/suggest/policyimpl/dictionary/structure/pt_common/pt_node_writer.h +++ b/native/jni/src/suggest/policyimpl/dictionary/structure/pt_common/pt_node_writer.h @@ -21,6 +21,7 @@ #include "defines.h" #include "suggest/policyimpl/dictionary/structure/pt_common/pt_node_params.h" +#include "utils/int_array_view.h" namespace latinime { @@ -70,12 +71,10 @@ class PtNodeWriter { virtual bool writeNewTerminalPtNodeAndAdvancePosition(const PtNodeParams *const ptNodeParams, const UnigramProperty *const unigramProperty, int *const ptNodeWritingPos) = 0; - virtual bool addNewBigramEntry(const PtNodeParams *const sourcePtNodeParams, - const PtNodeParams *const targetPtNodeParam, const BigramProperty *const bigramProperty, - bool *const outAddedNewBigram) = 0; + virtual bool addNgramEntry(const WordIdArrayView prevWordIds, const int wordId, + const BigramProperty *const bigramProperty, bool *const outAddedNewEntry) = 0; - virtual bool removeBigramEntry(const PtNodeParams *const sourcePtNodeParams, - const PtNodeParams *const targetPtNodeParam) = 0; + virtual bool removeNgramEntry(const WordIdArrayView prevWordIds, const int wordId) = 0; virtual bool updateAllBigramEntriesAndDeleteUselessEntries( const PtNodeParams *const sourcePtNodeParams, int *const outBigramEntryCount) = 0; diff --git a/native/jni/src/suggest/policyimpl/dictionary/structure/v4/content/language_model_dict_content.cpp b/native/jni/src/suggest/policyimpl/dictionary/structure/v4/content/language_model_dict_content.cpp index 07e1051bc..5dc91ba10 100644 --- a/native/jni/src/suggest/policyimpl/dictionary/structure/v4/content/language_model_dict_content.cpp +++ b/native/jni/src/suggest/policyimpl/dictionary/structure/v4/content/language_model_dict_content.cpp @@ -32,11 +32,11 @@ bool LanguageModelDictContent::runGC( ProbabilityEntry LanguageModelDictContent::getNgramProbabilityEntry( const WordIdArrayView prevWordIds, const int wordId) const { - if (!prevWordIds.empty()) { - // TODO: Read n-gram entry. + const int bitmapEntryIndex = getBitmapEntryIndex(prevWordIds); + if (bitmapEntryIndex == TrieMap::INVALID_INDEX) { return ProbabilityEntry(); } - const TrieMap::Result result = mTrieMap.getRoot(wordId); + const TrieMap::Result result = mTrieMap.get(wordId, bitmapEntryIndex); if (!result.mIsValid) { // Not found. return ProbabilityEntry(); @@ -46,14 +46,13 @@ ProbabilityEntry LanguageModelDictContent::getNgramProbabilityEntry( bool LanguageModelDictContent::setNgramProbabilityEntry(const WordIdArrayView prevWordIds, const int terminalId, const ProbabilityEntry *const probabilityEntry) { - if (!prevWordIds.empty()) { - // TODO: Add n-gram entry. + const int bitmapEntryIndex = getBitmapEntryIndex(prevWordIds); + if (bitmapEntryIndex == TrieMap::INVALID_INDEX) { return false; } - return mTrieMap.putRoot(terminalId, probabilityEntry->encode(mHasHistoricalInfo)); + return mTrieMap.put(terminalId, probabilityEntry->encode(mHasHistoricalInfo), bitmapEntryIndex); } - bool LanguageModelDictContent::runGCInner( const TerminalPositionLookupTable::TerminalIdMap *const terminalIdMap, const TrieMap::TrieMapRange trieMapRange, @@ -81,4 +80,16 @@ bool LanguageModelDictContent::runGCInner( return true; } +int LanguageModelDictContent::getBitmapEntryIndex(const WordIdArrayView prevWordIds) const { + int bitmapEntryIndex = mTrieMap.getRootBitmapEntryIndex(); + for (const int wordId : prevWordIds) { + const TrieMap::Result result = mTrieMap.get(wordId, bitmapEntryIndex); + if (!result.mIsValid) { + return TrieMap::INVALID_INDEX; + } + bitmapEntryIndex = result.mNextLevelBitmapEntryIndex; + } + return bitmapEntryIndex; +} + } // namespace latinime diff --git a/native/jni/src/suggest/policyimpl/dictionary/structure/v4/content/language_model_dict_content.h b/native/jni/src/suggest/policyimpl/dictionary/structure/v4/content/language_model_dict_content.h index f181dfeee..18f2e0170 100644 --- a/native/jni/src/suggest/policyimpl/dictionary/structure/v4/content/language_model_dict_content.h +++ b/native/jni/src/suggest/policyimpl/dictionary/structure/v4/content/language_model_dict_content.h @@ -76,6 +76,8 @@ class LanguageModelDictContent { bool runGCInner(const TerminalPositionLookupTable::TerminalIdMap *const terminalIdMap, const TrieMap::TrieMapRange trieMapRange, const int nextLevelBitmapEntryIndex, int *const outNgramCount); + + int getBitmapEntryIndex(const WordIdArrayView prevWordIds) const; }; } // namespace latinime #endif /* LATINIME_LANGUAGE_MODEL_DICT_CONTENT_H */ diff --git a/native/jni/src/suggest/policyimpl/dictionary/structure/v4/ver4_patricia_trie_node_writer.cpp b/native/jni/src/suggest/policyimpl/dictionary/structure/v4/ver4_patricia_trie_node_writer.cpp index 1a311b156..857222f5d 100644 --- a/native/jni/src/suggest/policyimpl/dictionary/structure/v4/ver4_patricia_trie_node_writer.cpp +++ b/native/jni/src/suggest/policyimpl/dictionary/structure/v4/ver4_patricia_trie_node_writer.cpp @@ -222,22 +222,19 @@ bool Ver4PatriciaTrieNodeWriter::writeNewTerminalPtNodeAndAdvancePosition( terminalId, &probabilityEntryToWrite); } -bool Ver4PatriciaTrieNodeWriter::addNewBigramEntry( - const PtNodeParams *const sourcePtNodeParams, const PtNodeParams *const targetPtNodeParam, +bool Ver4PatriciaTrieNodeWriter::addNgramEntry(const WordIdArrayView prevWordIds, const int wordId, const BigramProperty *const bigramProperty, bool *const outAddedNewBigram) { - if (!mBigramPolicy->addNewEntry(sourcePtNodeParams->getTerminalId(), - targetPtNodeParam->getTerminalId(), bigramProperty, outAddedNewBigram)) { + if (!mBigramPolicy->addNewEntry(prevWordIds[0], wordId, bigramProperty, outAddedNewBigram)) { AKLOGE("Cannot add new bigram entry. terminalId: %d, targetTerminalId: %d", - sourcePtNodeParams->getTerminalId(), targetPtNodeParam->getTerminalId()); + prevWordIds[0], wordId); return false; } return true; } -bool Ver4PatriciaTrieNodeWriter::removeBigramEntry( - const PtNodeParams *const sourcePtNodeParams, const PtNodeParams *const targetPtNodeParam) { - return mBigramPolicy->removeEntry(sourcePtNodeParams->getTerminalId(), - targetPtNodeParam->getTerminalId()); +bool Ver4PatriciaTrieNodeWriter::removeNgramEntry(const WordIdArrayView prevWordIds, + const int wordId) { + return mBigramPolicy->removeEntry(prevWordIds[0], wordId); } bool Ver4PatriciaTrieNodeWriter::updateAllBigramEntriesAndDeleteUselessEntries( diff --git a/native/jni/src/suggest/policyimpl/dictionary/structure/v4/ver4_patricia_trie_node_writer.h b/native/jni/src/suggest/policyimpl/dictionary/structure/v4/ver4_patricia_trie_node_writer.h index 162dc9b1d..6703dba04 100644 --- a/native/jni/src/suggest/policyimpl/dictionary/structure/v4/ver4_patricia_trie_node_writer.h +++ b/native/jni/src/suggest/policyimpl/dictionary/structure/v4/ver4_patricia_trie_node_writer.h @@ -75,12 +75,10 @@ class Ver4PatriciaTrieNodeWriter : public PtNodeWriter { virtual bool writeNewTerminalPtNodeAndAdvancePosition(const PtNodeParams *const ptNodeParams, const UnigramProperty *const unigramProperty, int *const ptNodeWritingPos); - virtual bool addNewBigramEntry(const PtNodeParams *const sourcePtNodeParams, - const PtNodeParams *const targetPtNodeParam, const BigramProperty *const bigramProperty, - bool *const outAddedNewBigram); + virtual bool addNgramEntry(const WordIdArrayView prevWordIds, const int wordId, + const BigramProperty *const bigramProperty, bool *const outAddedNewEntry); - virtual bool removeBigramEntry(const PtNodeParams *const sourcePtNodeParams, - const PtNodeParams *const targetPtNodeParam); + virtual bool removeNgramEntry(const WordIdArrayView prevWordIds, const int wordId); virtual bool updateAllBigramEntriesAndDeleteUselessEntries( const PtNodeParams *const sourcePtNodeParams, int *const outBigramEntryCount); diff --git a/native/jni/src/suggest/policyimpl/dictionary/structure/v4/ver4_patricia_trie_policy.cpp b/native/jni/src/suggest/policyimpl/dictionary/structure/v4/ver4_patricia_trie_policy.cpp index 2b92d5bea..723808399 100644 --- a/native/jni/src/suggest/policyimpl/dictionary/structure/v4/ver4_patricia_trie_policy.cpp +++ b/native/jni/src/suggest/policyimpl/dictionary/structure/v4/ver4_patricia_trie_policy.cpp @@ -292,6 +292,7 @@ bool Ver4PatriciaTriePolicy::addNgramEntry(const PrevWordsInfo *const prevWordsI int prevWordsPtNodePos[MAX_PREV_WORD_COUNT_FOR_N_GRAM]; prevWordsInfo->getPrevWordsTerminalPtNodePos(this, prevWordsPtNodePos, false /* tryLowerCaseSearch */); + const auto prevWordsPtNodePosView = PtNodePosArrayView::fromFixedSizeArray(prevWordsPtNodePos); // TODO: Support N-gram. if (prevWordsPtNodePos[0] == NOT_A_DICT_POS) { if (prevWordsInfo->isNthPrevWordBeginningOfSentence(1 /* n */)) { @@ -319,10 +320,10 @@ bool Ver4PatriciaTriePolicy::addNgramEntry(const PrevWordsInfo *const prevWordsI if (word1Pos == NOT_A_DICT_POS) { return false; } - bool addedNewBigram = false; - if (mUpdatingHelper.addBigramWords(prevWordsPtNodePos[0], word1Pos, bigramProperty, - &addedNewBigram)) { - if (addedNewBigram) { + bool addedNewEntry = false; + if (mUpdatingHelper.addNgramEntry(prevWordsPtNodePosView, word1Pos, bigramProperty, + &addedNewEntry)) { + if (addedNewEntry) { mBigramCount++; } return true; @@ -352,6 +353,7 @@ bool Ver4PatriciaTriePolicy::removeNgramEntry(const PrevWordsInfo *const prevWor int prevWordsPtNodePos[MAX_PREV_WORD_COUNT_FOR_N_GRAM]; prevWordsInfo->getPrevWordsTerminalPtNodePos(this, prevWordsPtNodePos, false /* tryLowerCaseSerch */); + const auto prevWordsPtNodePosView = PtNodePosArrayView::fromFixedSizeArray(prevWordsPtNodePos); // TODO: Support N-gram. if (prevWordsPtNodePos[0] == NOT_A_DICT_POS) { return false; @@ -361,7 +363,7 @@ bool Ver4PatriciaTriePolicy::removeNgramEntry(const PrevWordsInfo *const prevWor if (wordPos == NOT_A_DICT_POS) { return false; } - if (mUpdatingHelper.removeBigramWords(prevWordsPtNodePos[0], wordPos)) { + if (mUpdatingHelper.removeNgramEntry(prevWordsPtNodePosView, wordPos)) { mBigramCount--; return true; } else { diff --git a/native/jni/src/suggest/policyimpl/dictionary/utils/trie_map.h b/native/jni/src/suggest/policyimpl/dictionary/utils/trie_map.h index a294ab876..3e5c4010c 100644 --- a/native/jni/src/suggest/policyimpl/dictionary/utils/trie_map.h +++ b/native/jni/src/suggest/policyimpl/dictionary/utils/trie_map.h @@ -169,6 +169,10 @@ class TrieMap { return mBuffer.isNearSizeLimit(); } + int getRootBitmapEntryIndex() const { + return ROOT_BITMAP_ENTRY_INDEX; + } + // Returns bitmapEntryIndex. Create the next level map if it doesn't exist. int getNextLevelBitmapEntryIndex(const int key) { return getNextLevelBitmapEntryIndex(key, ROOT_BITMAP_ENTRY_INDEX); diff --git a/native/jni/src/utils/int_array_view.h b/native/jni/src/utils/int_array_view.h index 4bc2487ae..c1ddc9812 100644 --- a/native/jni/src/utils/int_array_view.h +++ b/native/jni/src/utils/int_array_view.h @@ -56,6 +56,16 @@ class IntArrayView { explicit IntArrayView(const std::vector<int> &vector) : mPtr(vector.data()), mSize(vector.size()) {} + template <int N> + AK_FORCE_INLINE static IntArrayView fromFixedSizeArray(const int (&array)[N]) { + return IntArrayView(array, N); + } + + // Returns a view that points one int object. Does not take ownership of the given object. + AK_FORCE_INLINE static IntArrayView fromObject(const int *const object) { + return IntArrayView(object, 1); + } + AK_FORCE_INLINE int operator[](const size_t index) const { ASSERT(index < mSize); return mPtr[index]; @@ -73,6 +83,14 @@ class IntArrayView { return mPtr; } + AK_FORCE_INLINE const int *begin() const { + return mPtr; + } + + AK_FORCE_INLINE const int *end() const { + return mPtr + mSize; + } + private: DISALLOW_ASSIGNMENT_OPERATOR(IntArrayView); @@ -81,6 +99,7 @@ class IntArrayView { }; using WordIdArrayView = IntArrayView; +using PtNodePosArrayView = IntArrayView; } // namespace latinime #endif // LATINIME_MEMORY_VIEW_H diff --git a/native/jni/tests/utils/int_array_view_test.cpp b/native/jni/tests/utils/int_array_view_test.cpp index 9aa8cdc8c..bd843ab02 100644 --- a/native/jni/tests/utils/int_array_view_test.cpp +++ b/native/jni/tests/utils/int_array_view_test.cpp @@ -23,16 +23,39 @@ namespace latinime { namespace { -TEST(MemoryViewTest, TestAccess) { - static const int DATA_SIZE = 10000; - - std::vector<int> intVector = {3, 2, 1, 0, -1, -2}; +TEST(IntArrayViewTest, TestAccess) { + const std::vector<int> intVector = {3, 2, 1, 0, -1, -2}; IntArrayView intArrayView(intVector); EXPECT_EQ(intVector.size(), intArrayView.size()); - for (int i = 0; i < DATA_SIZE; ++i) { + for (int i = 0; i < static_cast<int>(intVector.size()); ++i) { EXPECT_EQ(intVector[i], intArrayView[i]); } } +TEST(IntArrayViewTest, TestIteration) { + const std::vector<int> intVector = {3, 2, 1, 0, -1, -2}; + IntArrayView intArrayView(intVector); + size_t expectedIndex = 0; + for (const int element : intArrayView) { + EXPECT_EQ(intVector[expectedIndex], element); + ++expectedIndex; + } + EXPECT_EQ(expectedIndex, intArrayView.size()); +} + +TEST(IntArrayViewTest, TestConstructFromArray) { + const size_t ARRAY_SIZE = 100; + int intArray[ARRAY_SIZE]; + const auto intArrayView = IntArrayView::fromFixedSizeArray(intArray); + EXPECT_EQ(ARRAY_SIZE, intArrayView.size()); +} + +TEST(IntArrayViewTest, TestConstructFromObject) { + const int object = 10; + const auto intArrayView = IntArrayView::fromObject(&object); + EXPECT_EQ(1, intArrayView.size()); + EXPECT_EQ(object, intArrayView[0]); +} + } // namespace } // namespace latinime diff --git a/tests/src/com/android/inputmethod/latin/InputLogicTestsReorderingMyanmar.java b/tests/src/com/android/inputmethod/latin/InputLogicTestsReorderingMyanmar.java index 61eae4e8b..ab69c8592 100644 --- a/tests/src/com/android/inputmethod/latin/InputLogicTestsReorderingMyanmar.java +++ b/tests/src/com/android/inputmethod/latin/InputLogicTestsReorderingMyanmar.java @@ -17,6 +17,7 @@ package com.android.inputmethod.latin; import android.test.suitebuilder.annotation.LargeTest; +import android.test.suitebuilder.annotation.Suppress; import android.util.Pair; /* @@ -77,6 +78,8 @@ import android.util.Pair; */ @LargeTest +// These tests are inactive until the combining code for Myanmar Reordering is sorted out. +@Suppress @SuppressWarnings("rawtypes") public class InputLogicTestsReorderingMyanmar extends InputTestsBase { // The tests are formatted as follows. diff --git a/tests/src/com/android/inputmethod/latin/InputTestsBase.java b/tests/src/com/android/inputmethod/latin/InputTestsBase.java index 986fb1097..18671fbe8 100644 --- a/tests/src/com/android/inputmethod/latin/InputTestsBase.java +++ b/tests/src/com/android/inputmethod/latin/InputTestsBase.java @@ -36,6 +36,7 @@ import android.widget.EditText; import android.widget.FrameLayout; import com.android.inputmethod.compat.InputMethodSubtypeCompatUtils; +import com.android.inputmethod.event.Event; import com.android.inputmethod.keyboard.Key; import com.android.inputmethod.keyboard.Keyboard; import com.android.inputmethod.latin.SuggestedWords.SuggestedWordInfo; @@ -263,14 +264,17 @@ public class InputTestsBase extends ServiceTestCase<LatinIMEForTests> { // but keep them in mind if something breaks. Commenting them out as is should work. //mLatinIME.onPressKey(codePoint, 0 /* repeatCount */, true /* isSinglePointer */); final Key key = mKeyboard.getKey(codePoint); + final Event event; if (key == null) { - mLatinIME.onCodeInput(codePoint, Constants.NOT_A_COORDINATE, Constants.NOT_A_COORDINATE, - isKeyRepeat); + event = Event.createSoftwareKeypressEvent(codePoint, Event.NOT_A_KEY_CODE, + Constants.NOT_A_COORDINATE, Constants.NOT_A_COORDINATE, isKeyRepeat); } else { final int x = key.getX() + key.getWidth() / 2; final int y = key.getY() + key.getHeight() / 2; - mLatinIME.onCodeInput(codePoint, x, y, isKeyRepeat); + event = Event.createSoftwareKeypressEvent(codePoint, Event.NOT_A_KEY_CODE, + x, y, isKeyRepeat); } + mLatinIME.onEvent(event); // Also see the comment at the top of this function about onReleaseKey //mLatinIME.onReleaseKey(codePoint, false /* withSliding */); } diff --git a/tests/src/com/android/inputmethod/latin/makedict/BinaryDictEncoderUtils.java b/tests/src/com/android/inputmethod/latin/makedict/BinaryDictEncoderUtils.java index 084371944..eabd8d722 100644 --- a/tests/src/com/android/inputmethod/latin/makedict/BinaryDictEncoderUtils.java +++ b/tests/src/com/android/inputmethod/latin/makedict/BinaryDictEncoderUtils.java @@ -802,20 +802,13 @@ public class BinaryDictEncoderUtils { } MakedictLog.i("Statistics:\n" - + " total file size " + size + "\n" + + " Total file size " + size + "\n" + " " + ptNodeArrays.size() + " node arrays\n" + " " + ptNodes + " PtNodes (" + ((float)ptNodes / ptNodeArrays.size()) + " PtNodes per node)\n" - + " first terminal at " + firstTerminalAddress + "\n" - + " last terminal at " + lastTerminalAddress + "\n" + + " First terminal at " + firstTerminalAddress + "\n" + + " Last terminal at " + lastTerminalAddress + "\n" + " PtNode stats : max = " + maxNodes); - for (int i = 0; i < ptNodeCounts.length; ++i) { - MakedictLog.i(" " + i + " : " + ptNodeCounts[i]); - } - MakedictLog.i(" Character run stats : max = " + maxRuns); - for (int i = 0; i < runCounts.length; ++i) { - MakedictLog.i(" " + i + " : " + runCounts[i]); - } } /** |