Use SparseIntArray instead of TreeMap<Integer, Integer>

Change-Id: I56a64228a5fd85d440d0d08ac67cba8bf2e5690d
This commit is contained in:
Tadashi G. Takaoka 2013-03-21 13:27:20 +09:00
parent 4fdfce6dcc
commit 869ea1e555

View file

@ -16,11 +16,10 @@
package com.android.inputmethod.latin.spellcheck; package com.android.inputmethod.latin.spellcheck;
import com.android.inputmethod.keyboard.ProximityInfo; import android.util.SparseIntArray;
import com.android.inputmethod.latin.CollectionUtils;
import com.android.inputmethod.latin.Constants;
import java.util.TreeMap; import com.android.inputmethod.keyboard.ProximityInfo;
import com.android.inputmethod.latin.Constants;
public final class SpellCheckerProximityInfo extends ProximityInfo { public final class SpellCheckerProximityInfo extends ProximityInfo {
public SpellCheckerProximityInfo(final int script) { public SpellCheckerProximityInfo(final int script) {
@ -43,29 +42,14 @@ public final class SpellCheckerProximityInfo extends ProximityInfo {
public static final int NOT_A_COORDINATE_PAIR = -1; public static final int NOT_A_COORDINATE_PAIR = -1;
// Helper methods // Helper methods
static void buildProximityIndices(final int[] proximity, static void buildProximityIndices(final int[] proximity, final int rowSize,
final TreeMap<Integer, Integer> indices) { final SparseIntArray indices) {
for (int i = 0; i < proximity.length; i += ROW_SIZE) { for (int i = 0; i < proximity.length; i += rowSize) {
if (NUL != proximity[i]) indices.put(proximity[i], i / ROW_SIZE); if (NUL != proximity[i]) indices.put(proximity[i], i / rowSize);
} }
} }
static int computeIndex(final int characterCode,
final TreeMap<Integer, Integer> indices) {
final Integer result = indices.get(characterCode);
if (null == result) return NOT_AN_INDEX;
return result;
}
private static final class Latin { private static final class Latin {
// This is a map from the code point to the index in the PROXIMITY array.
// At the time the native code to read the binary dictionary needs the proximity info be
// passed as a flat array spaced by MAX_PROXIMITY_CHARS_SIZE columns, one for each input
// character.
// Since we need to build such an array, we want to be able to search in our big proximity
// data quickly by character, and a map is probably the best way to do this.
private static final TreeMap<Integer, Integer> INDICES = CollectionUtils.newTreeMap();
// The proximity here is the union of // The proximity here is the union of
// - the proximity for a QWERTY keyboard. // - the proximity for a QWERTY keyboard.
// - the proximity for an AZERTY keyboard. // - the proximity for an AZERTY keyboard.
@ -125,17 +109,20 @@ public final class SpellCheckerProximityInfo extends ProximityInfo {
NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL,
}; };
static { // This is a mapping array from the code point to the index in the PROXIMITY array.
buildProximityIndices(PROXIMITY, INDICES); // When we check the spelling of a word, we need to pass (x,y) coordinates to the native
} // code for each letter of the word. These are most easily computed from the index in the
// PROXIMITY array. Since we'll need to do that very often, the index lookup from the code
// point needs to be as fast as possible, and a map is probably the best way to do this.
// To avoid unnecessary boxing conversion to Integer, here we use SparseIntArray.
static final SparseIntArray INDICES = new SparseIntArray(PROXIMITY.length / ROW_SIZE);
static int getIndexOf(int characterCode) { static {
return computeIndex(characterCode, INDICES); buildProximityIndices(PROXIMITY, ROW_SIZE, INDICES);
} }
} }
private static final class Cyrillic { private static final class Cyrillic {
private static final TreeMap<Integer, Integer> INDICES = CollectionUtils.newTreeMap();
// TODO: The following table is solely based on the keyboard layout. Consult with Russian // TODO: The following table is solely based on the keyboard layout. Consult with Russian
// speakers on commonly misspelled words/letters. // speakers on commonly misspelled words/letters.
/* /*
@ -286,17 +273,14 @@ public final class SpellCheckerProximityInfo extends ProximityInfo {
NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL,
}; };
static { static final SparseIntArray INDICES = new SparseIntArray(PROXIMITY.length / ROW_SIZE);
buildProximityIndices(PROXIMITY, INDICES);
}
static int getIndexOf(int characterCode) { static {
return computeIndex(characterCode, INDICES); buildProximityIndices(PROXIMITY, ROW_SIZE, INDICES);
} }
} }
private static final class Greek { private static final class Greek {
private static final TreeMap<Integer, Integer> INDICES = CollectionUtils.newTreeMap();
// TODO: The following table is solely based on the keyboard layout. Consult with Greek // TODO: The following table is solely based on the keyboard layout. Consult with Greek
// speakers on commonly misspelled words/letters. // speakers on commonly misspelled words/letters.
/* /*
@ -427,12 +411,10 @@ public final class SpellCheckerProximityInfo extends ProximityInfo {
NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL,
}; };
static { static final SparseIntArray INDICES = new SparseIntArray(PROXIMITY.length / ROW_SIZE);
buildProximityIndices(PROXIMITY, INDICES);
}
static int getIndexOf(int characterCode) { static {
return computeIndex(characterCode, INDICES); buildProximityIndices(PROXIMITY, ROW_SIZE, INDICES);
} }
} }
@ -452,11 +434,11 @@ public final class SpellCheckerProximityInfo extends ProximityInfo {
private static int getIndexOfCodeForScript(final int codePoint, final int script) { private static int getIndexOfCodeForScript(final int codePoint, final int script) {
switch (script) { switch (script) {
case AndroidSpellCheckerService.SCRIPT_LATIN: case AndroidSpellCheckerService.SCRIPT_LATIN:
return Latin.getIndexOf(codePoint); return Latin.INDICES.get(codePoint, NOT_AN_INDEX);
case AndroidSpellCheckerService.SCRIPT_CYRILLIC: case AndroidSpellCheckerService.SCRIPT_CYRILLIC:
return Cyrillic.getIndexOf(codePoint); return Cyrillic.INDICES.get(codePoint, NOT_AN_INDEX);
case AndroidSpellCheckerService.SCRIPT_GREEK: case AndroidSpellCheckerService.SCRIPT_GREEK:
return Greek.getIndexOf(codePoint); return Greek.INDICES.get(codePoint, NOT_AN_INDEX);
default: default:
throw new RuntimeException("Wrong script supplied: " + script); throw new RuntimeException("Wrong script supplied: " + script);
} }