Merge "Add ArraysCompatUtils.binarySearch"

This commit is contained in:
Tadashi G. Takaoka 2011-06-21 01:42:17 -07:00 committed by Android (Google) Code Review
commit 6313db1d11
3 changed files with 156 additions and 2 deletions

View File

@ -0,0 +1,50 @@
/*
* Copyright (C) 2011 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.compat;
import java.lang.reflect.Method;
import java.util.Arrays;
public class ArraysCompatUtils {
private static final Method METHOD_Arrays_binarySearch = CompatUtils
.getMethod(Arrays.class, "binarySearch", int[].class, int.class, int.class, int.class);
public static int binarySearch(int[] array, int startIndex, int endIndex, int value) {
if (METHOD_Arrays_binarySearch != null) {
final Object index = CompatUtils.invoke(null, 0, METHOD_Arrays_binarySearch,
array, startIndex, endIndex, value);
return (Integer)index;
} else {
return compatBinarySearch(array, startIndex, endIndex, value);
}
}
/* package */ static int compatBinarySearch(int[] array, int startIndex, int endIndex,
int value) {
if (startIndex > endIndex) throw new IllegalArgumentException();
if (startIndex < 0 || endIndex > array.length) throw new ArrayIndexOutOfBoundsException();
final int work[] = new int[endIndex - startIndex];
System.arraycopy(array, startIndex, work, 0, work.length);
final int index = Arrays.binarySearch(work, value);
if (index >= 0) {
return index + startIndex;
} else {
return ~(~index + startIndex);
}
}
}

View File

@ -19,6 +19,7 @@ package com.android.inputmethod.latin.spellcheck;
import android.content.Context;
import android.content.res.Resources;
import com.android.inputmethod.compat.ArraysCompatUtils;
import com.android.inputmethod.latin.Dictionary;
import com.android.inputmethod.latin.Dictionary.DataType;
import com.android.inputmethod.latin.Dictionary.WordCallback;
@ -26,7 +27,6 @@ import com.android.inputmethod.latin.DictionaryFactory;
import com.android.inputmethod.latin.Utils;
import com.android.inputmethod.latin.WordComposer;
import java.util.Arrays;
import java.util.LinkedList;
import java.util.List;
import java.util.Locale;
@ -64,13 +64,14 @@ public class SpellChecker {
private int[] mScores = new int[DEFAULT_SUGGESTION_LENGTH];
private int mLength = 0;
@Override
synchronized public boolean addWord(char[] word, int wordOffset, int wordLength, int score,
int dicTypeId, DataType dataType) {
if (mLength >= mScores.length) {
final int newLength = mScores.length * 2;
mScores = new int[newLength];
}
final int positionIndex = Arrays.binarySearch(mScores, 0, mLength, score);
final int positionIndex = ArraysCompatUtils.binarySearch(mScores, 0, mLength, score);
// binarySearch returns the index if the element exists, and -<insertion index> - 1
// if it doesn't. See documentation for binarySearch.
final int insertionIndex = positionIndex >= 0 ? positionIndex : -positionIndex - 1;

View File

@ -0,0 +1,103 @@
/*
* Copyright (C) 2011 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.compat;
import android.test.AndroidTestCase;
public class ArraysCompatUtilsTests extends AndroidTestCase {
// See {@link tests.api.java.util.ArraysTest}.
private static final int ARRAY_SIZE = 100;
private final int[] mIntArray = new int[ARRAY_SIZE];
@Override
protected void setUp() throws Exception {
super.setUp();
for (int counter = 0; counter < ARRAY_SIZE; counter++) {
mIntArray[counter] = counter;
}
}
public void testEmptyArray() {
final int index = ArraysCompatUtils.binarySearch(mIntArray, 0, 0, 0);
assertEquals("empty", ~0, index);
final int compat = ArraysCompatUtils.compatBinarySearch(mIntArray, 0, 0, 0);
assertEquals("empty compat", ~0, compat);
}
public void testEmptyRangeArray() {
final int mid = ARRAY_SIZE / 3;
final int index = ArraysCompatUtils.binarySearch(mIntArray, mid, mid, 1);
assertEquals("empty", ~mid, index);
final int compat = ArraysCompatUtils.compatBinarySearch(mIntArray, mid, mid, 1);
assertEquals("empty compat", ~mid, compat);
}
public void testFind() {
for (int counter = 0; counter < ARRAY_SIZE; counter++) {
final int index = ArraysCompatUtils.binarySearch(mIntArray, 0, ARRAY_SIZE, counter);
assertEquals("found", counter, index);
}
for (int counter = 0; counter < ARRAY_SIZE; counter++) {
final int compat = ArraysCompatUtils.compatBinarySearch(
mIntArray, 0, ARRAY_SIZE, counter);
assertEquals("found compat", counter, compat);
}
}
public void testFindNegative() {
final int offset = ARRAY_SIZE / 2;
for (int counter = 0; counter < ARRAY_SIZE; counter++) {
mIntArray[counter] -= offset;
}
for (int counter = 0; counter < ARRAY_SIZE; counter++) {
final int index = ArraysCompatUtils.binarySearch(
mIntArray, 0, ARRAY_SIZE, counter - offset);
assertEquals("found", counter, index);
}
for (int counter = 0; counter < ARRAY_SIZE; counter++) {
final int compat = ArraysCompatUtils.compatBinarySearch(
mIntArray, 0, ARRAY_SIZE, counter - offset);
assertEquals("found compat", counter, compat);
}
}
public void testNotFountAtTop() {
final int index = ArraysCompatUtils.binarySearch(mIntArray, 0, ARRAY_SIZE, -1);
assertEquals("not found top", ~0, index);
final int compat = ArraysCompatUtils.compatBinarySearch(
mIntArray, 0, ARRAY_SIZE, -1);
assertEquals("not found top compat", ~0, compat);
}
public void testNotFountAtEnd() {
final int index = ArraysCompatUtils.binarySearch(mIntArray, 0, ARRAY_SIZE, ARRAY_SIZE);
assertEquals("not found end", ~ARRAY_SIZE, index);
final int compat = ArraysCompatUtils.compatBinarySearch(
mIntArray, 0, ARRAY_SIZE, ARRAY_SIZE);
assertEquals("not found end compat", ~ARRAY_SIZE, compat);
}
public void testNotFountAtMid() {
final int mid = ARRAY_SIZE / 3;
mIntArray[mid] = mIntArray[mid + 1];
final int index = ArraysCompatUtils.binarySearch(mIntArray, 0, ARRAY_SIZE, mid);
assertEquals("not found mid", ~mid, index);
final int compat = ArraysCompatUtils.compatBinarySearch(
mIntArray, 0, ARRAY_SIZE, mid);
assertEquals("not found mid compat", ~mid, compat);
}
}