Merge "Prepare dictionary saving in native code."
This commit is contained in:
commit
ac7e005ef0
11 changed files with 147 additions and 10 deletions
|
@ -19,6 +19,7 @@ package com.android.inputmethod.latin;
|
|||
import android.text.TextUtils;
|
||||
import android.util.SparseArray;
|
||||
|
||||
import com.android.inputmethod.annotations.UsedForTesting;
|
||||
import com.android.inputmethod.keyboard.ProximityInfo;
|
||||
import com.android.inputmethod.latin.SuggestedWords.SuggestedWordInfo;
|
||||
import com.android.inputmethod.latin.settings.NativeSuggestOptions;
|
||||
|
@ -47,6 +48,7 @@ public final class BinaryDictionary extends Dictionary {
|
|||
private long mNativeDict;
|
||||
private final Locale mLocale;
|
||||
private final long mDictSize;
|
||||
private final String mDictFilePath;
|
||||
private final int[] mInputCodePoints = new int[MAX_WORD_LENGTH];
|
||||
private final int[] mOutputCodePoints = new int[MAX_WORD_LENGTH * MAX_RESULTS];
|
||||
private final int[] mSpaceIndices = new int[MAX_RESULTS];
|
||||
|
@ -91,6 +93,7 @@ public final class BinaryDictionary extends Dictionary {
|
|||
super(dictType);
|
||||
mLocale = locale;
|
||||
mDictSize = length;
|
||||
mDictFilePath = filename;
|
||||
mNativeSuggestOptions.setUseFullEditDistance(useFullEditDistance);
|
||||
loadDictionary(filename, offset, length, isUpdatable);
|
||||
}
|
||||
|
@ -101,6 +104,9 @@ public final class BinaryDictionary extends Dictionary {
|
|||
|
||||
private static native long openNative(String sourceDir, long dictOffset, long dictSize,
|
||||
boolean isUpdatable);
|
||||
private static native void flushNative(long dict, String filePath);
|
||||
private static native boolean needsToRunGCNative(long dict);
|
||||
private static native void flushWithGCNative(long dict, String filePath);
|
||||
private static native void closeNative(long dict);
|
||||
private static native int getProbabilityNative(long dict, int[] word);
|
||||
private static native boolean isValidBigramNative(long dict, int[] word0, int[] word1);
|
||||
|
@ -261,6 +267,24 @@ public final class BinaryDictionary extends Dictionary {
|
|||
removeBigramWordsNative(mNativeDict, codePoints0, codePoints1);
|
||||
}
|
||||
|
||||
@UsedForTesting
|
||||
public void flush() {
|
||||
if (!isValidDictionary()) return;
|
||||
flushNative(mNativeDict, mDictFilePath);
|
||||
}
|
||||
|
||||
@UsedForTesting
|
||||
public void flushWithGC() {
|
||||
if (!isValidDictionary()) return;
|
||||
flushWithGCNative(mNativeDict, mDictFilePath);
|
||||
}
|
||||
|
||||
@UsedForTesting
|
||||
public boolean needsToRunGC() {
|
||||
if (!isValidDictionary()) return false;
|
||||
return needsToRunGCNative(mNativeDict);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean shouldAutoCommit(final SuggestedWordInfo candidate) {
|
||||
// TODO: actually use the confidence rather than use this completely broken heuristic
|
||||
|
|
|
@ -46,8 +46,7 @@ static jlong latinime_BinaryDictionary_open(JNIEnv *env, jclass clazz, jstring s
|
|||
sourceDirChars[sourceDirUtf8Length] = '\0';
|
||||
DictionaryStructureWithBufferPolicy *const dictionaryStructureWithBufferPolicy =
|
||||
DictionaryStructureWithBufferPolicyFactory::newDictionaryStructureWithBufferPolicy(
|
||||
sourceDirChars, static_cast<int>(sourceDirUtf8Length),
|
||||
static_cast<int>(dictOffset), static_cast<int>(dictSize),
|
||||
sourceDirChars, static_cast<int>(dictOffset), static_cast<int>(dictSize),
|
||||
isUpdatable == JNI_TRUE);
|
||||
if (!dictionaryStructureWithBufferPolicy) {
|
||||
return 0;
|
||||
|
@ -59,6 +58,35 @@ static jlong latinime_BinaryDictionary_open(JNIEnv *env, jclass clazz, jstring s
|
|||
return reinterpret_cast<jlong>(dictionary);
|
||||
}
|
||||
|
||||
static void latinime_BinaryDictionary_flush(JNIEnv *env, jclass clazz, jlong dict,
|
||||
jstring filePath) {
|
||||
Dictionary *dictionary = reinterpret_cast<Dictionary *>(dict);
|
||||
if (!dictionary) return;
|
||||
const jsize filePathUtf8Length = env->GetStringUTFLength(filePath);
|
||||
char filePathChars[filePathUtf8Length + 1];
|
||||
env->GetStringUTFRegion(filePath, 0, env->GetStringLength(filePath), filePathChars);
|
||||
filePathChars[filePathUtf8Length] = '\0';
|
||||
dictionary->flush(filePathChars);
|
||||
}
|
||||
|
||||
static bool latinime_BinaryDictionary_needsToRunGC(JNIEnv *env, jclass clazz,
|
||||
jlong dict) {
|
||||
Dictionary *dictionary = reinterpret_cast<Dictionary *>(dict);
|
||||
if (!dictionary) return false;
|
||||
return dictionary->needsToRunGC();
|
||||
}
|
||||
|
||||
static void latinime_BinaryDictionary_flushWithGC(JNIEnv *env, jclass clazz, jlong dict,
|
||||
jstring filePath) {
|
||||
Dictionary *dictionary = reinterpret_cast<Dictionary *>(dict);
|
||||
if (!dictionary) return;
|
||||
const jsize filePathUtf8Length = env->GetStringUTFLength(filePath);
|
||||
char filePathChars[filePathUtf8Length + 1];
|
||||
env->GetStringUTFRegion(filePath, 0, env->GetStringLength(filePath), filePathChars);
|
||||
filePathChars[filePathUtf8Length] = '\0';
|
||||
dictionary->flushWithGC(filePathChars);
|
||||
}
|
||||
|
||||
static void latinime_BinaryDictionary_close(JNIEnv *env, jclass clazz, jlong dict) {
|
||||
Dictionary *dictionary = reinterpret_cast<Dictionary *>(dict);
|
||||
if (!dictionary) return;
|
||||
|
@ -252,6 +280,21 @@ static const JNINativeMethod sMethods[] = {
|
|||
const_cast<char *>("(J)V"),
|
||||
reinterpret_cast<void *>(latinime_BinaryDictionary_close)
|
||||
},
|
||||
{
|
||||
const_cast<char *>("flushNative"),
|
||||
const_cast<char *>("(JLjava/lang/String;)V"),
|
||||
reinterpret_cast<void *>(latinime_BinaryDictionary_flush)
|
||||
},
|
||||
{
|
||||
const_cast<char *>("needsToRunGCNative"),
|
||||
const_cast<char *>("(J)Z"),
|
||||
reinterpret_cast<void *>(latinime_BinaryDictionary_needsToRunGC)
|
||||
},
|
||||
{
|
||||
const_cast<char *>("flushWithGCNative"),
|
||||
const_cast<char *>("(JLjava/lang/String;)V"),
|
||||
reinterpret_cast<void *>(latinime_BinaryDictionary_flushWithGC)
|
||||
},
|
||||
{
|
||||
const_cast<char *>("getSuggestionsNative"),
|
||||
const_cast<char *>("(JJJ[I[I[I[I[III[I[I[I[I[I[I[I)I"),
|
||||
|
|
|
@ -112,6 +112,18 @@ void Dictionary::removeBigramWords(const int *const word0, const int length0,
|
|||
mDictionaryStructureWithBufferPolicy->removeBigramWords(word0, length0, word1, length1);
|
||||
}
|
||||
|
||||
void Dictionary::flush(const char *const filePath) {
|
||||
mDictionaryStructureWithBufferPolicy->flush(filePath);
|
||||
}
|
||||
|
||||
void Dictionary::flushWithGC(const char *const filePath) {
|
||||
mDictionaryStructureWithBufferPolicy->flushWithGC(filePath);
|
||||
}
|
||||
|
||||
bool Dictionary::needsToRunGC() {
|
||||
return mDictionaryStructureWithBufferPolicy->needsToRunGC();
|
||||
}
|
||||
|
||||
void Dictionary::logDictionaryInfo(JNIEnv *const env) const {
|
||||
const int BUFFER_SIZE = 16;
|
||||
int dictionaryIdCodePointBuffer[BUFFER_SIZE];
|
||||
|
|
|
@ -77,6 +77,12 @@ class Dictionary {
|
|||
void removeBigramWords(const int *const word0, const int length0, const int *const word1,
|
||||
const int length1);
|
||||
|
||||
void flush(const char *const filePath);
|
||||
|
||||
void flushWithGC(const char *const filePath);
|
||||
|
||||
bool needsToRunGC();
|
||||
|
||||
const DictionaryStructureWithBufferPolicy *getDictionaryStructurePolicy() const {
|
||||
return mDictionaryStructureWithBufferPolicy;
|
||||
}
|
||||
|
|
|
@ -74,6 +74,12 @@ class DictionaryStructureWithBufferPolicy {
|
|||
virtual bool removeBigramWords(const int *const word0, const int length0,
|
||||
const int *const word1, const int length1) = 0;
|
||||
|
||||
virtual void flush(const char *const filePath) = 0;
|
||||
|
||||
virtual void flushWithGC(const char *const filePath) = 0;
|
||||
|
||||
virtual bool needsToRunGC() const = 0;
|
||||
|
||||
protected:
|
||||
DictionaryStructureWithBufferPolicy() {}
|
||||
|
||||
|
|
|
@ -27,12 +27,12 @@
|
|||
namespace latinime {
|
||||
|
||||
/* static */ DictionaryStructureWithBufferPolicy *DictionaryStructureWithBufferPolicyFactory
|
||||
::newDictionaryStructureWithBufferPolicy(const char *const path, const int pathLength,
|
||||
const int bufOffset, const int size, const bool isUpdatable) {
|
||||
::newDictionaryStructureWithBufferPolicy(const char *const path, const int bufOffset,
|
||||
const int size, const bool isUpdatable) {
|
||||
// Allocated buffer in MmapedBuffer::openBuffer() will be freed in the destructor of
|
||||
// impl classes of DictionaryStructureWithBufferPolicy.
|
||||
const MmappedBuffer *const mmapedBuffer = MmappedBuffer::openBuffer(path, pathLength, bufOffset,
|
||||
size, isUpdatable);
|
||||
const MmappedBuffer *const mmapedBuffer = MmappedBuffer::openBuffer(path, bufOffset, size,
|
||||
isUpdatable);
|
||||
if (!mmapedBuffer) {
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -27,8 +27,7 @@ namespace latinime {
|
|||
class DictionaryStructureWithBufferPolicyFactory {
|
||||
public:
|
||||
static DictionaryStructureWithBufferPolicy *newDictionaryStructureWithBufferPolicy(
|
||||
const char *const path, const int pathLength, const int bufOffset, const int size,
|
||||
const bool isUpdatable);
|
||||
const char *const path, const int bufOffset, const int size, const bool isUpdatable);
|
||||
|
||||
private:
|
||||
DISALLOW_IMPLICIT_CONSTRUCTORS(DictionaryStructureWithBufferPolicyFactory);
|
||||
|
|
|
@ -243,4 +243,29 @@ bool DynamicPatriciaTriePolicy::removeBigramWords(const int *const word0, const
|
|||
return writingHelper.removeBigramWords(word0Pos, word1Pos);
|
||||
}
|
||||
|
||||
void DynamicPatriciaTriePolicy::flush(const char *const filePath) {
|
||||
if (!mBuffer->isUpdatable()) {
|
||||
AKLOGI("Warning: flush() is called for non-updatable dictionary.");
|
||||
return;
|
||||
}
|
||||
// TODO: Implement.
|
||||
}
|
||||
|
||||
void DynamicPatriciaTriePolicy::flushWithGC(const char *const filePath) {
|
||||
if (!mBuffer->isUpdatable()) {
|
||||
AKLOGI("Warning: flushWithGC() is called for non-updatable dictionary.");
|
||||
return;
|
||||
}
|
||||
// TODO: Implement.
|
||||
}
|
||||
|
||||
bool DynamicPatriciaTriePolicy::needsToRunGC() const {
|
||||
if (!mBuffer->isUpdatable()) {
|
||||
AKLOGI("Warning: needsToRunGC() is called for non-updatable dictionary.");
|
||||
return false;
|
||||
}
|
||||
// TODO: Implement.
|
||||
return false;
|
||||
}
|
||||
|
||||
} // namespace latinime
|
||||
|
|
|
@ -85,6 +85,12 @@ class DynamicPatriciaTriePolicy : public DictionaryStructureWithBufferPolicy {
|
|||
bool removeBigramWords(const int *const word0, const int length0, const int *const word1,
|
||||
const int length1);
|
||||
|
||||
void flush(const char *const filePath);
|
||||
|
||||
void flushWithGC(const char *const filePath);
|
||||
|
||||
bool needsToRunGC() const;
|
||||
|
||||
private:
|
||||
DISALLOW_IMPLICIT_CONSTRUCTORS(DynamicPatriciaTriePolicy);
|
||||
|
||||
|
|
|
@ -96,6 +96,22 @@ class PatriciaTriePolicy : public DictionaryStructureWithBufferPolicy {
|
|||
return false;
|
||||
}
|
||||
|
||||
void flush(const char *const filePath) {
|
||||
// This method should not be called for non-updatable dictionary.
|
||||
AKLOGI("Warning: flush() is called for non-updatable dictionary.");
|
||||
}
|
||||
|
||||
void flushWithGC(const char *const filePath) {
|
||||
// This method should not be called for non-updatable dictionary.
|
||||
AKLOGI("Warning: flushWithGC() is called for non-updatable dictionary.");
|
||||
}
|
||||
|
||||
bool needsToRunGC() const {
|
||||
// This method should not be called for non-updatable dictionary.
|
||||
AKLOGI("Warning: needsToRunGC() is called for non-updatable dictionary.");
|
||||
return false;
|
||||
}
|
||||
|
||||
private:
|
||||
DISALLOW_IMPLICIT_CONSTRUCTORS(PatriciaTriePolicy);
|
||||
|
||||
|
|
|
@ -29,8 +29,8 @@ namespace latinime {
|
|||
|
||||
class MmappedBuffer {
|
||||
public:
|
||||
static MmappedBuffer* openBuffer(const char *const path, const int pathLength,
|
||||
const int bufferOffset, const int bufferSize, const bool isUpdatable) {
|
||||
static MmappedBuffer* openBuffer(const char *const path, const int bufferOffset,
|
||||
const int bufferSize, const bool isUpdatable) {
|
||||
const int openMode = isUpdatable ? O_RDWR : O_RDONLY;
|
||||
const int mmapFd = open(path, openMode);
|
||||
if (mmapFd < 0) {
|
||||
|
|
Loading…
Reference in a new issue