diff options
-rw-r--r-- | java/res/values/attrs.xml | 3 | ||||
-rw-r--r-- | java/res/values/dimens.xml | 3 | ||||
-rw-r--r-- | java/res/values/styles.xml | 3 | ||||
-rw-r--r-- | java/src/com/android/inputmethod/keyboard/internal/GesturePreviewTrail.java | 59 | ||||
-rw-r--r-- | java/src/com/android/inputmethod/keyboard/internal/PreviewPlacerView.java | 36 | ||||
-rw-r--r-- | java/src/com/android/inputmethod/latin/UserHistoryDictIOUtils.java | 2 | ||||
-rw-r--r-- | native/jni/src/binary_format.h | 4 | ||||
-rw-r--r-- | native/jni/src/unigram_dictionary.cpp | 8 | ||||
-rw-r--r-- | tests/src/com/android/inputmethod/latin/makedict/BinaryDictIOTests.java | 281 |
9 files changed, 249 insertions, 150 deletions
diff --git a/java/res/values/attrs.xml b/java/res/values/attrs.xml index e60139704..7e8c77e13 100644 --- a/java/res/values/attrs.xml +++ b/java/res/values/attrs.xml @@ -90,7 +90,8 @@ <!-- Interval of updating gesture preview trail in millisecond. --> <attr name="gesturePreviewTrailUpdateInterval" format="integer" /> <attr name="gesturePreviewTrailColor" format="color" /> - <attr name="gesturePreviewTrailWidth" format="dimension" /> + <attr name="gesturePreviewTrailStartWidth" format="dimension" /> + <attr name="gesturePreviewTrailEndWidth" format="dimension" /> </declare-styleable> <declare-styleable name="MainKeyboardView"> diff --git a/java/res/values/dimens.xml b/java/res/values/dimens.xml index 9ccaaaf4e..d92a71560 100644 --- a/java/res/values/dimens.xml +++ b/java/res/values/dimens.xml @@ -100,7 +100,8 @@ <fraction name="center_suggestion_percentile">36%</fraction> <!-- Gesture preview trail parameters --> - <dimen name="gesture_preview_trail_width">2.5dp</dimen> + <dimen name="gesture_preview_trail_start_width">18.0dp</dimen> + <dimen name="gesture_preview_trail_end_width">2.5dp</dimen> <!-- Gesture floating preview text parameters --> <dimen name="gesture_floating_preview_text_size">24dp</dimen> <dimen name="gesture_floating_preview_text_offset">73dp</dimen> diff --git a/java/res/values/styles.xml b/java/res/values/styles.xml index 94fdbeb53..ed92440ef 100644 --- a/java/res/values/styles.xml +++ b/java/res/values/styles.xml @@ -77,7 +77,8 @@ <item name="gesturePreviewTrailFadeoutDuration">@integer/config_gesture_preview_trail_fadeout_duration</item> <item name="gesturePreviewTrailUpdateInterval">@integer/config_gesture_preview_trail_update_interval</item> <item name="gesturePreviewTrailColor">@android:color/holo_blue_light</item> - <item name="gesturePreviewTrailWidth">@dimen/gesture_preview_trail_width</item> + <item name="gesturePreviewTrailStartWidth">@dimen/gesture_preview_trail_start_width</item> + <item name="gesturePreviewTrailEndWidth">@dimen/gesture_preview_trail_end_width</item> <!-- Common attributes of MainKeyboardView --> <item name="keyHysteresisDistance">@dimen/config_key_hysteresis_distance</item> <item name="touchNoiseThresholdTime">@integer/config_touch_noise_threshold_time</item> diff --git a/java/src/com/android/inputmethod/keyboard/internal/GesturePreviewTrail.java b/java/src/com/android/inputmethod/keyboard/internal/GesturePreviewTrail.java index e814d8009..7442b7fad 100644 --- a/java/src/com/android/inputmethod/keyboard/internal/GesturePreviewTrail.java +++ b/java/src/com/android/inputmethod/keyboard/internal/GesturePreviewTrail.java @@ -17,16 +17,18 @@ package com.android.inputmethod.keyboard.internal; import android.content.res.TypedArray; import android.graphics.Canvas; import android.graphics.Paint; +import android.graphics.PorterDuff; +import android.graphics.PorterDuffXfermode; +import android.graphics.Xfermode; import android.os.SystemClock; import com.android.inputmethod.latin.Constants; import com.android.inputmethod.latin.R; import com.android.inputmethod.latin.ResizableIntArray; -class GesturePreviewTrail { +final class GesturePreviewTrail { private static final int DEFAULT_CAPACITY = GestureStrokeWithPreviewTrail.PREVIEW_CAPACITY; - private final GesturePreviewTrailParams mPreviewParams; private final ResizableIntArray mXCoordinates = new ResizableIntArray(DEFAULT_CAPACITY); private final ResizableIntArray mYCoordinates = new ResizableIntArray(DEFAULT_CAPACITY); private final ResizableIntArray mEventTimes = new ResizableIntArray(DEFAULT_CAPACITY); @@ -34,28 +36,39 @@ class GesturePreviewTrail { private long mCurrentDownTime; private int mTrailStartIndex; + private final static Xfermode PORTER_DUFF_MODE_SRC = + new PorterDuffXfermode(PorterDuff.Mode.SRC); + // Use this value as imaginary zero because x-coordinates may be zero. private static final int DOWN_EVENT_MARKER = -128; - static class GesturePreviewTrailParams { + static final class Params { + public final int mTrailColor; + public final float mTrailStartWidth; + public final float mTrailEndWidth; public final int mFadeoutStartDelay; public final int mFadeoutDuration; public final int mUpdateInterval; - public GesturePreviewTrailParams(final TypedArray keyboardViewAttr) { + public final int mTrailLingerDuration; + + public Params(final TypedArray keyboardViewAttr) { + mTrailColor = keyboardViewAttr.getColor( + R.styleable.KeyboardView_gesturePreviewTrailColor, 0); + mTrailStartWidth = keyboardViewAttr.getDimension( + R.styleable.KeyboardView_gesturePreviewTrailStartWidth, 0.0f); + mTrailEndWidth = keyboardViewAttr.getDimension( + R.styleable.KeyboardView_gesturePreviewTrailEndWidth, 0.0f); mFadeoutStartDelay = keyboardViewAttr.getInt( R.styleable.KeyboardView_gesturePreviewTrailFadeoutStartDelay, 0); mFadeoutDuration = keyboardViewAttr.getInt( R.styleable.KeyboardView_gesturePreviewTrailFadeoutDuration, 0); + mTrailLingerDuration = mFadeoutStartDelay + mFadeoutDuration; mUpdateInterval = keyboardViewAttr.getInt( R.styleable.KeyboardView_gesturePreviewTrailUpdateInterval, 0); } } - public GesturePreviewTrail(final GesturePreviewTrailParams params) { - mPreviewParams = params; - } - private static int markAsDownEvent(final int xCoord) { return DOWN_EVENT_MARKER - xCoord; } @@ -94,23 +107,30 @@ class GesturePreviewTrail { } } - private int getAlpha(final int elapsedTime) { - if (elapsedTime < mPreviewParams.mFadeoutStartDelay) { + private static int getAlpha(final int elapsedTime, final Params params) { + if (elapsedTime < params.mFadeoutStartDelay) { return Constants.Color.ALPHA_OPAQUE; } final int decreasingAlpha = Constants.Color.ALPHA_OPAQUE - * (elapsedTime - mPreviewParams.mFadeoutStartDelay) - / mPreviewParams.mFadeoutDuration; + * (elapsedTime - params.mFadeoutStartDelay) + / params.mFadeoutDuration; return Constants.Color.ALPHA_OPAQUE - decreasingAlpha; } + private static float getWidth(final int elapsedTime, final Params params) { + return Math.max((params.mTrailLingerDuration - elapsedTime) + * (params.mTrailStartWidth - params.mTrailEndWidth) + / params.mTrailLingerDuration, 0.0f); + } + /** * Draw gesture preview trail * @param canvas The canvas to draw the gesture preview trail * @param paint The paint object to be used to draw the gesture preview trail + * @param params The drawing parameters of gesture preview trail * @return true if some gesture preview trails remain to be drawn */ - public boolean drawGestureTrail(final Canvas canvas, final Paint paint) { + public boolean drawGestureTrail(final Canvas canvas, final Paint paint, final Params params) { final int trailSize = mEventTimes.getLength(); if (trailSize == 0) { return false; @@ -120,13 +140,11 @@ class GesturePreviewTrail { final int[] xCoords = mXCoordinates.getPrimitiveArray(); final int[] yCoords = mYCoordinates.getPrimitiveArray(); final int sinceDown = (int)(SystemClock.uptimeMillis() - mCurrentDownTime); - final int lingeringDuration = mPreviewParams.mFadeoutStartDelay - + mPreviewParams.mFadeoutDuration; int startIndex; for (startIndex = mTrailStartIndex; startIndex < trailSize; startIndex++) { final int elapsedTime = sinceDown - eventTimes[startIndex]; // Skip too old trail points. - if (elapsedTime < lingeringDuration) { + if (elapsedTime < params.mTrailLingerDuration) { break; } } @@ -135,13 +153,20 @@ class GesturePreviewTrail { if (startIndex < trailSize) { int lastX = getXCoordValue(xCoords[startIndex]); int lastY = yCoords[startIndex]; + paint.setColor(params.mTrailColor); + paint.setStyle(Paint.Style.STROKE); + paint.setStrokeCap(Paint.Cap.ROUND); + paint.setXfermode(PORTER_DUFF_MODE_SRC); for (int i = startIndex + 1; i < trailSize - 1; i++) { final int x = xCoords[i]; final int y = yCoords[i]; final int elapsedTime = sinceDown - eventTimes[i]; // Draw trail line only when the current point isn't a down point. if (!isDownEventXCoord(x)) { - paint.setAlpha(getAlpha(elapsedTime)); + final int alpha = getAlpha(elapsedTime, params); + paint.setAlpha(alpha); + final float width = getWidth(elapsedTime, params); + paint.setStrokeWidth(width); canvas.drawLine(lastX, lastY, x, y, paint); } lastX = getXCoordValue(x); diff --git a/java/src/com/android/inputmethod/keyboard/internal/PreviewPlacerView.java b/java/src/com/android/inputmethod/keyboard/internal/PreviewPlacerView.java index 641fadf6d..8dde4d671 100644 --- a/java/src/com/android/inputmethod/keyboard/internal/PreviewPlacerView.java +++ b/java/src/com/android/inputmethod/keyboard/internal/PreviewPlacerView.java @@ -21,6 +21,8 @@ import android.content.res.TypedArray; import android.graphics.Canvas; import android.graphics.Paint; import android.graphics.Paint.Align; +import android.graphics.PorterDuff; +import android.graphics.PorterDuffXfermode; import android.graphics.Rect; import android.graphics.RectF; import android.os.Message; @@ -30,14 +32,12 @@ import android.util.SparseArray; import android.widget.RelativeLayout; import com.android.inputmethod.keyboard.PointerTracker; -import com.android.inputmethod.keyboard.internal.GesturePreviewTrail.GesturePreviewTrailParams; +import com.android.inputmethod.keyboard.internal.GesturePreviewTrail.Params; import com.android.inputmethod.latin.CollectionUtils; import com.android.inputmethod.latin.R; import com.android.inputmethod.latin.StaticInnerHandlerWrapper; public class PreviewPlacerView extends RelativeLayout { - private final Paint mGesturePaint; - private final Paint mTextPaint; private final int mGestureFloatingPreviewTextColor; private final int mGestureFloatingPreviewTextOffset; private final int mGestureFloatingPreviewColor; @@ -51,8 +51,11 @@ public class PreviewPlacerView extends RelativeLayout { private final SparseArray<GesturePreviewTrail> mGesturePreviewTrails = CollectionUtils.newSparseArray(); - private final GesturePreviewTrailParams mGesturePreviewTrailParams; + private final Params mGesturePreviewTrailParams; + private final Paint mGesturePaint; + private boolean mDrawsGesturePreviewTrail; + private final Paint mTextPaint; private String mGestureFloatingPreviewText; private final int mGestureFloatingPreviewTextHeight; // {@link RectF} is needed for {@link Canvas#drawRoundRect(RectF, float, float, Paint)}. @@ -60,8 +63,6 @@ public class PreviewPlacerView extends RelativeLayout { private int mLastPointerX; private int mLastPointerY; private static final char[] TEXT_HEIGHT_REFERENCE_CHAR = { 'M' }; - - private boolean mDrawsGesturePreviewTrail; private boolean mDrawsGestureFloatingPreviewText; private final DrawingHandler mDrawingHandler; @@ -70,10 +71,10 @@ public class PreviewPlacerView extends RelativeLayout { private static final int MSG_DISMISS_GESTURE_FLOATING_PREVIEW_TEXT = 0; private static final int MSG_UPDATE_GESTURE_PREVIEW_TRAIL = 1; - private final GesturePreviewTrailParams mGesturePreviewTrailParams; + private final Params mGesturePreviewTrailParams; public DrawingHandler(final PreviewPlacerView outerInstance, - final GesturePreviewTrailParams gesturePreviewTrailParams) { + final Params gesturePreviewTrailParams) { super(outerInstance); mGesturePreviewTrailParams = gesturePreviewTrailParams; } @@ -146,21 +147,13 @@ public class PreviewPlacerView extends RelativeLayout { R.styleable.KeyboardView_gestureFloatingPreviewRoundRadius, 0.0f); mGestureFloatingPreviewTextLingerTimeout = keyboardViewAttr.getInt( R.styleable.KeyboardView_gestureFloatingPreviewTextLingerTimeout, 0); - final int gesturePreviewTrailColor = keyboardViewAttr.getColor( - R.styleable.KeyboardView_gesturePreviewTrailColor, 0); - final int gesturePreviewTrailWidth = keyboardViewAttr.getDimensionPixelSize( - R.styleable.KeyboardView_gesturePreviewTrailWidth, 0); - mGesturePreviewTrailParams = new GesturePreviewTrailParams(keyboardViewAttr); + mGesturePreviewTrailParams = new Params(keyboardViewAttr); keyboardViewAttr.recycle(); mDrawingHandler = new DrawingHandler(this, mGesturePreviewTrailParams); final Paint gesturePaint = new Paint(); gesturePaint.setAntiAlias(true); - gesturePaint.setStyle(Paint.Style.STROKE); - gesturePaint.setStrokeJoin(Paint.Join.ROUND); - gesturePaint.setColor(gesturePreviewTrailColor); - gesturePaint.setStrokeWidth(gesturePreviewTrailWidth); mGesturePaint = gesturePaint; final Paint textPaint = new Paint(); @@ -172,6 +165,10 @@ public class PreviewPlacerView extends RelativeLayout { final Rect textRect = new Rect(); textPaint.getTextBounds(TEXT_HEIGHT_REFERENCE_CHAR, 0, 1, textRect); mGestureFloatingPreviewTextHeight = textRect.height(); + + final Paint layerPaint = new Paint(); + layerPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_OVER)); + setLayerType(LAYER_TYPE_HARDWARE, layerPaint); } public void setOrigin(final int x, final int y) { @@ -190,7 +187,7 @@ public class PreviewPlacerView extends RelativeLayout { synchronized (mGesturePreviewTrails) { trail = mGesturePreviewTrails.get(tracker.mPointerId); if (trail == null) { - trail = new GesturePreviewTrail(mGesturePreviewTrailParams); + trail = new GesturePreviewTrail(); mGesturePreviewTrails.put(tracker.mPointerId, trail); } } @@ -214,7 +211,8 @@ public class PreviewPlacerView extends RelativeLayout { for (int index = 0; index < trailsCount; index++) { final GesturePreviewTrail trail = mGesturePreviewTrails.valueAt(index); needsUpdatingGesturePreviewTrail |= - trail.drawGestureTrail(canvas, mGesturePaint); + trail.drawGestureTrail(canvas, mGesturePaint, + mGesturePreviewTrailParams); } } if (needsUpdatingGesturePreviewTrail) { diff --git a/java/src/com/android/inputmethod/latin/UserHistoryDictIOUtils.java b/java/src/com/android/inputmethod/latin/UserHistoryDictIOUtils.java index 81d61e957..d6fa66131 100644 --- a/java/src/com/android/inputmethod/latin/UserHistoryDictIOUtils.java +++ b/java/src/com/android/inputmethod/latin/UserHistoryDictIOUtils.java @@ -54,7 +54,7 @@ public class UserHistoryDictIOUtils { private byte[] mBuffer; private int mPosition; - ByteArrayWrapper(final byte[] buffer) { + public ByteArrayWrapper(final byte[] buffer) { mBuffer = buffer; mPosition = 0; } diff --git a/native/jni/src/binary_format.h b/native/jni/src/binary_format.h index 5d8b2a0f2..eec52e323 100644 --- a/native/jni/src/binary_format.h +++ b/native/jni/src/binary_format.h @@ -360,7 +360,7 @@ inline int BinaryFormat::getTerminalPosition(const uint8_t *const root, while (true) { // If we already traversed the tree further than the word is long, there means // there was no match (or we would have found it). - if (wordPos > length) return NOT_VALID_WORD; + if (wordPos >= length) return NOT_VALID_WORD; int charGroupCount = BinaryFormat::getGroupCountAndForwardPointer(root, &pos); const int32_t wChar = forceLowerCaseSearch ? toLowerCase(inWord[wordPos]) : inWord[wordPos]; while (true) { @@ -383,7 +383,7 @@ inline int BinaryFormat::getTerminalPosition(const uint8_t *const root, // character that does not match, as explained above, it means the word is // not in the dictionary (by virtue of this chargroup being the only one to // match the word on the first character, but not matching the whole word). - if (wordPos > length) return NOT_VALID_WORD; + if (wordPos >= length) return NOT_VALID_WORD; if (inWord[wordPos] != character) return NOT_VALID_WORD; character = BinaryFormat::getCodePointAndForwardPointer(root, &pos); } diff --git a/native/jni/src/unigram_dictionary.cpp b/native/jni/src/unigram_dictionary.cpp index b7e245a6c..cf806c111 100644 --- a/native/jni/src/unigram_dictionary.cpp +++ b/native/jni/src/unigram_dictionary.cpp @@ -451,7 +451,7 @@ int UnigramDictionary::getSubStringSuggestion( const bool hasAutoCorrectionCandidate, const int currentWordIndex, const int inputWordStartPos, const int inputWordLength, const int outputWordStartPos, const bool isSpaceProximity, int *freqArray, - int*wordLengthArray, unsigned short *outputWord, int *outputWordLength) const { + int *wordLengthArray, unsigned short *outputWord, int *outputWordLength) const { if (inputWordLength > MULTIPLE_WORDS_SUGGESTION_MAX_WORD_LENGTH) { return FLAG_MULTIPLE_SUGGEST_ABORT; } @@ -546,9 +546,9 @@ int UnigramDictionary::getSubStringSuggestion( freq = score >> (nextWordLength + TWO_WORDS_PLUS_OTHER_ERROR_CORRECTION_DEMOTION_DIVIDER); } if (DEBUG_DICT) { - AKLOGI("Freq(%d): %d, length: %d, input length: %d, input start: %d (%d)" - , currentWordIndex, freq, nextWordLength, inputWordLength, inputWordStartPos, - wordLengthArray[0]); + AKLOGI("Freq(%d): %d, length: %d, input length: %d, input start: %d (%d)", + currentWordIndex, freq, nextWordLength, inputWordLength, inputWordStartPos, + (currentWordIndex > 0) ? wordLengthArray[0] : 0); } if (freq <= 0 || nextWordLength <= 0 || MAX_WORD_LENGTH <= (outputWordStartPos + nextWordLength)) { diff --git a/tests/src/com/android/inputmethod/latin/makedict/BinaryDictIOTests.java b/tests/src/com/android/inputmethod/latin/makedict/BinaryDictIOTests.java index 6036562a8..523287b48 100644 --- a/tests/src/com/android/inputmethod/latin/makedict/BinaryDictIOTests.java +++ b/tests/src/com/android/inputmethod/latin/makedict/BinaryDictIOTests.java @@ -17,23 +17,22 @@ package com.android.inputmethod.latin.makedict; import com.android.inputmethod.latin.CollectionUtils; -import com.android.inputmethod.latin.makedict.BinaryDictInputOutput; -import com.android.inputmethod.latin.makedict.FusionDictionary; +import com.android.inputmethod.latin.UserHistoryDictIOUtils; +import com.android.inputmethod.latin.makedict.BinaryDictInputOutput.FusionDictionaryBufferInterface; import com.android.inputmethod.latin.makedict.FusionDictionary.CharGroup; import com.android.inputmethod.latin.makedict.FusionDictionary.Node; -import com.android.inputmethod.latin.makedict.PendingAttribute; -import com.android.inputmethod.latin.makedict.UnsupportedFormatException; +import com.android.inputmethod.latin.makedict.FusionDictionary.WeightedString; import android.test.AndroidTestCase; import android.util.Log; import android.util.SparseArray; -import java.nio.ByteBuffer; -import java.nio.channels.FileChannel; import java.io.File; -import java.io.FileOutputStream; import java.io.FileInputStream; +import java.io.FileOutputStream; import java.io.IOException; +import java.nio.ByteBuffer; +import java.nio.channels.FileChannel; import java.util.ArrayList; import java.util.HashMap; import java.util.HashSet; @@ -53,16 +52,76 @@ public class BinaryDictIOTests extends AndroidTestCase { private static final int BIGRAM_FREQ = 50; private static final int TOLERANCE_OF_BIGRAM_FREQ = 5; + private static final int USE_BYTE_ARRAY = 1; + private static final int USE_BYTE_BUFFER = 2; + + private static final List<String> sWords = CollectionUtils.newArrayList(); + private static final SparseArray<List<Integer>> sEmptyBigrams = + CollectionUtils.newSparseArray(); + private static final SparseArray<List<Integer>> sStarBigrams = CollectionUtils.newSparseArray(); + private static final SparseArray<List<Integer>> sChainBigrams = + CollectionUtils.newSparseArray(); + private static final BinaryDictInputOutput.FormatOptions VERSION2 = new BinaryDictInputOutput.FormatOptions(2); - private static final String[] CHARACTERS = - { + private static final String[] CHARACTERS = { "a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z" - }; + }; + + public BinaryDictIOTests() { + super(); + + final Random random = new Random(123456); + sWords.clear(); + generateWords(MAX_UNIGRAMS, random); + + for (int i = 0; i < sWords.size(); ++i) { + sChainBigrams.put(i, new ArrayList<Integer>()); + if (i > 0) { + sChainBigrams.get(i-1).add(i); + } + } + + sStarBigrams.put(0, new ArrayList<Integer>()); + for (int i = 1; i < sWords.size(); ++i) { + sStarBigrams.get(0).add(i); + } + } // Utilities for test + + /** + * Makes new buffer according to BUFFER_TYPE. + */ + private FusionDictionaryBufferInterface getBuffer(final File file,final int bufferType) { + FileInputStream inStream = null; + try { + inStream = new FileInputStream(file); + if (bufferType == USE_BYTE_ARRAY) { + final byte[] array = new byte[(int)file.length()]; + inStream.read(array); + return new UserHistoryDictIOUtils.ByteArrayWrapper(array); + } else if (bufferType == USE_BYTE_BUFFER){ + final ByteBuffer buffer = inStream.getChannel().map( + FileChannel.MapMode.READ_ONLY, 0, file.length()); + return new BinaryDictInputOutput.ByteBufferWrapper(buffer); + } + } catch (IOException e) { + Log.e(TAG, "IOException while making buffer: " + e); + } finally { + if (inStream != null) { + try { + inStream.close(); + } catch (IOException e) { + Log.e(TAG, "IOException while closing stream: " + e); + } + } + } + return null; + } + /** * Generates a random word. */ @@ -77,23 +136,29 @@ public class BinaryDictIOTests extends AndroidTestCase { return builder.toString(); } - private List<String> generateWords(final int number, final Random random) { + private void generateWords(final int number, final Random random) { final Set<String> wordSet = CollectionUtils.newHashSet(); while (wordSet.size() < number) { wordSet.add(generateWord(random.nextInt())); } - return new ArrayList<String>(wordSet); + sWords.addAll(wordSet); } /** * Adds unigrams to the dictionary. */ - private void addUnigrams(final int number, - final FusionDictionary dict, - final List<String> words) { + private void addUnigrams(final int number, final FusionDictionary dict, + final List<String> words, final Map<String, List<String>> shortcutMap) { for (int i = 0; i < number; ++i) { final String word = words.get(i); - dict.add(word, UNIGRAM_FREQ, null, false /* isNotAWord */); + final ArrayList<WeightedString> shortcuts = CollectionUtils.newArrayList(); + if (shortcutMap != null && shortcutMap.containsKey(word)) { + for (final String shortcut : shortcutMap.get(word)) { + shortcuts.add(new WeightedString(shortcut, UNIGRAM_FREQ)); + } + } + dict.add(word, UNIGRAM_FREQ, (shortcutMap == null) ? null : shortcuts, + false /* isNotAWord */); } } @@ -130,9 +195,8 @@ public class BinaryDictIOTests extends AndroidTestCase { return diff; } - private void checkDictionary(final FusionDictionary dict, - final List<String> words, - final SparseArray<List<Integer>> bigrams) { + private void checkDictionary(final FusionDictionary dict, final List<String> words, + final SparseArray<List<Integer>> bigrams, final Map<String, List<String>> shortcutMap) { assertNotNull(dict); // check unigram @@ -149,94 +213,93 @@ public class BinaryDictIOTests extends AndroidTestCase { assertNotNull(words.get(w1) + "," + words.get(w2), cg.getBigram(words.get(w2))); } } + + // check shortcut + if (shortcutMap != null) { + for (final Map.Entry<String, List<String>> entry : shortcutMap.entrySet()) { + final CharGroup group = FusionDictionary.findWordInTree(dict.mRoot, entry.getKey()); + for (final String word : entry.getValue()) { + assertNotNull("shortcut not found: " + entry.getKey() + ", " + word, + group.getShortcut(word)); + } + } + } } // Tests for readDictionaryBinary and writeDictionaryBinary private long timeReadingAndCheckDict(final File file, final List<String> words, - final SparseArray<List<Integer>> bigrams) { - + final SparseArray<List<Integer>> bigrams, final Map<String, List<String>> shortcutMap, + final int bufferType) { long now, diff = -1; + final FusionDictionaryBufferInterface buffer = getBuffer(file, bufferType); + assertNotNull(buffer); - FileInputStream inStream = null; + FusionDictionary dict = null; try { - inStream = new FileInputStream(file); - final ByteBuffer buffer = inStream.getChannel().map( - FileChannel.MapMode.READ_ONLY, 0, file.length()); - now = System.currentTimeMillis(); - - final FusionDictionary dict = - BinaryDictInputOutput.readDictionaryBinary(buffer, null); - - diff = System.currentTimeMillis() - now; - - checkDictionary(dict, words, bigrams); - return diff; - + dict = BinaryDictInputOutput.readDictionaryBinary(buffer, null); + diff = System.currentTimeMillis() - now; } catch (IOException e) { - Log.e(TAG, "raise IOException while reading file " + e); + Log.e(TAG, "IOException while reading dictionary: " + e); } catch (UnsupportedFormatException e) { - Log.e(TAG, "Unsupported format: " + e); - } finally { - if (inStream != null) { - try { - inStream.close(); - } catch (IOException e) { - // do nothing - } - } + Log.e(TAG, "Unsupported format: "+ e); } + checkDictionary(dict, words, bigrams, shortcutMap); return diff; } + // Tests for readDictionaryBinary and writeDictionaryBinary private String runReadAndWrite(final List<String> words, - final SparseArray<List<Integer>> bigrams, - final String message) { - final FusionDictionary dict = new FusionDictionary(new Node(), - new FusionDictionary.DictionaryOptions( - new HashMap<String,String>(), false, false)); - + final SparseArray<List<Integer>> bigrams, final Map<String, List<String>> shortcuts, + final int bufferType, final String message) { File file = null; try { file = File.createTempFile("runReadAndWrite", ".dict"); } catch (IOException e) { Log.e(TAG, "IOException: " + e); } - assertNotNull(file); - addUnigrams(words.size(), dict, words); + final FusionDictionary dict = new FusionDictionary(new Node(), + new FusionDictionary.DictionaryOptions( + new HashMap<String,String>(), false, false)); + addUnigrams(words.size(), dict, words, shortcuts); addBigrams(dict, words, bigrams); - // check original dictionary - checkDictionary(dict, words, bigrams); + checkDictionary(dict, words, bigrams, shortcuts); final long write = timeWritingDictToFile(file, dict); - final long read = timeReadingAndCheckDict(file, words, bigrams); + final long read = timeReadingAndCheckDict(file, words, bigrams, shortcuts, bufferType); - return "PROF: read=" + read + "ms, write=" + write + "ms :" + message; + return "PROF: read=" + read + "ms, write=" + write + "ms :" + message + + " : buffer type = " + bufferType; } - public void testReadAndWrite() { - final List<String> results = new ArrayList<String>(); + public void testReadAndWriteWithByteBuffer() { + final List<String> results = CollectionUtils.newArrayList(); - final Random random = new Random(123456); - final List<String> words = generateWords(MAX_UNIGRAMS, random); - final SparseArray<List<Integer>> emptyArray = CollectionUtils.newSparseArray(); + results.add(runReadAndWrite(sWords, sEmptyBigrams, null /* shortcuts */, USE_BYTE_BUFFER, + "unigram")); + results.add(runReadAndWrite(sWords, sChainBigrams, null /* shortcuts */, USE_BYTE_BUFFER, + "chain")); + results.add(runReadAndWrite(sWords, sStarBigrams, null /* shortcuts */, USE_BYTE_BUFFER, + "star")); - final SparseArray<List<Integer>> chain = CollectionUtils.newSparseArray(); - for (int i = 0; i < words.size(); ++i) chain.put(i, new ArrayList<Integer>()); - for (int i = 1; i < words.size(); ++i) chain.get(i-1).add(i); + for (final String result : results) { + Log.d(TAG, result); + } + } - final SparseArray<List<Integer>> star = CollectionUtils.newSparseArray(); - final List<Integer> list0 = CollectionUtils.newArrayList(); - star.put(0, list0); - for (int i = 1; i < words.size(); ++i) star.get(0).add(i); + public void testReadAndWriteWithByteArray() { + final List<String> results = CollectionUtils.newArrayList(); - results.add(runReadAndWrite(words, emptyArray, "only unigram")); - results.add(runReadAndWrite(words, chain, "chain")); - results.add(runReadAndWrite(words, star, "star")); + results.add(runReadAndWrite(sWords, sEmptyBigrams, null /* shortcuts */, USE_BYTE_ARRAY, + "unigram")); + results.add(runReadAndWrite(sWords, sChainBigrams, null /* shortcuts */, USE_BYTE_ARRAY, + "chain")); + results.add(runReadAndWrite(sWords, sStarBigrams, null /* shortcuts */, USE_BYTE_ARRAY, + "star")); for (final String result : results) { Log.d(TAG, result); @@ -292,7 +355,7 @@ public class BinaryDictIOTests extends AndroidTestCase { } private long timeAndCheckReadUnigramsAndBigramsBinary(final File file, final List<String> words, - final SparseArray<List<Integer>> bigrams) { + final SparseArray<List<Integer>> bigrams, final int bufferType) { FileInputStream inStream = null; final Map<Integer, String> resultWords = CollectionUtils.newTreeMap(); @@ -301,17 +364,13 @@ public class BinaryDictIOTests extends AndroidTestCase { final Map<Integer, Integer> resultFreqs = CollectionUtils.newTreeMap(); long now = -1, diff = -1; + final FusionDictionaryBufferInterface buffer = getBuffer(file, bufferType); + assertNotNull("Can't get buffer.", buffer); try { - inStream = new FileInputStream(file); - final ByteBuffer buffer = inStream.getChannel().map( - FileChannel.MapMode.READ_ONLY, 0, file.length()); - now = System.currentTimeMillis(); - BinaryDictInputOutput.readUnigramsAndBigramsBinary( - new BinaryDictInputOutput.ByteBufferWrapper(buffer), resultWords, resultFreqs, + BinaryDictInputOutput.readUnigramsAndBigramsBinary(buffer, resultWords, resultFreqs, resultBigrams); diff = System.currentTimeMillis() - now; - checkWordMap(words, bigrams, resultWords, resultFreqs, resultBigrams); } catch (IOException e) { Log.e(TAG, "IOException " + e); } catch (UnsupportedFormatException e) { @@ -326,50 +385,64 @@ public class BinaryDictIOTests extends AndroidTestCase { } } + checkWordMap(words, bigrams, resultWords, resultFreqs, resultBigrams); return diff; } - private void runReadUnigramsAndBigramsBinary(final List<String> words, - final SparseArray<List<Integer>> bigrams) { - - // making the dictionary from lists of words. - final FusionDictionary dict = new FusionDictionary(new Node(), - new FusionDictionary.DictionaryOptions( - new HashMap<String, String>(), false, false)); - + private String runReadUnigramsAndBigramsBinary(final List<String> words, + final SparseArray<List<Integer>> bigrams, final int bufferType, + final String message) { File file = null; try { file = File.createTempFile("runReadUnigrams", ".dict"); } catch (IOException e) { Log.e(TAG, "IOException: " + e); } - assertNotNull(file); - addUnigrams(words.size(), dict, words); + // making the dictionary from lists of words. + final FusionDictionary dict = new FusionDictionary(new Node(), + new FusionDictionary.DictionaryOptions( + new HashMap<String, String>(), false, false)); + addUnigrams(words.size(), dict, words, null /* shortcutMap */); addBigrams(dict, words, bigrams); + timeWritingDictToFile(file, dict); - long wordMap = timeAndCheckReadUnigramsAndBigramsBinary(file, words, bigrams); - long fullReading = timeReadingAndCheckDict(file, words, bigrams); + long wordMap = timeAndCheckReadUnigramsAndBigramsBinary(file, words, bigrams, bufferType); + long fullReading = timeReadingAndCheckDict(file, words, bigrams, null /* shortcutMap */, + bufferType); - Log.d(TAG, "read=" + fullReading + ", bytearray=" + wordMap); + return "readDictionaryBinary=" + fullReading + ", readUnigramsAndBigramsBinary=" + wordMap + + " : " + message + " : buffer type = " + bufferType; } - public void testReadUnigramsAndBigramsBinary() { - final List<String> results = new ArrayList<String>(); + public void testReadUnigramsAndBigramsBinaryWithByteBuffer() { + final List<String> results = CollectionUtils.newArrayList(); - final Random random = new Random(123456); - final List<String> words = generateWords(MAX_UNIGRAMS, random); - final SparseArray<List<Integer>> emptyArray = CollectionUtils.newSparseArray(); + results.add(runReadUnigramsAndBigramsBinary(sWords, sEmptyBigrams, USE_BYTE_BUFFER, + "unigram")); + results.add(runReadUnigramsAndBigramsBinary(sWords, sChainBigrams, USE_BYTE_BUFFER, + "chain")); + results.add(runReadUnigramsAndBigramsBinary(sWords, sStarBigrams, USE_BYTE_BUFFER, + "star")); + + for (final String result : results) { + Log.d(TAG, result); + } + } - runReadUnigramsAndBigramsBinary(words, emptyArray); + public void testReadUnigramsAndBigramsBinaryWithByteArray() { + final List<String> results = CollectionUtils.newArrayList(); - final SparseArray<List<Integer>> star = CollectionUtils.newSparseArray(); - for (int i = 1; i < words.size(); ++i) { - star.put(i-1, new ArrayList<Integer>()); - star.get(i-1).add(i); + results.add(runReadUnigramsAndBigramsBinary(sWords, sEmptyBigrams, USE_BYTE_ARRAY, + "unigram")); + results.add(runReadUnigramsAndBigramsBinary(sWords, sChainBigrams, USE_BYTE_ARRAY, + "chain")); + results.add(runReadUnigramsAndBigramsBinary(sWords, sStarBigrams, USE_BYTE_ARRAY, "star")); + + for (final String result : results) { + Log.d(TAG, result); } - runReadUnigramsAndBigramsBinary(words, star); } } |