Cleanups in JNI related code
Removed the malloc version in binary dictionary support -- this has not really been tested well so far, and the mmap version has been working pretty well after all. Several cosmetic fixes etc. Change-Id: Iad0da58b300b769fb5946a3e73fc96f56215980emain
parent
11dc3a371d
commit
ad0c6d7b36
|
@ -43,13 +43,17 @@ static void latinime_Keyboard_release(JNIEnv *env, jclass clazz, jlong proximity
|
||||||
delete pi;
|
delete pi;
|
||||||
}
|
}
|
||||||
|
|
||||||
static JNINativeMethod sMethods[] = {
|
static const JNINativeMethod sMethods[] = {
|
||||||
{const_cast<char *>("setProximityInfoNative"),
|
{
|
||||||
const_cast<char *>("(Ljava/lang/String;IIIIII[II[I[I[I[I[I[F[F[F)J"),
|
const_cast<char *>("setProximityInfoNative"),
|
||||||
reinterpret_cast<void *>(latinime_Keyboard_setProximityInfo)},
|
const_cast<char *>("(Ljava/lang/String;IIIIII[II[I[I[I[I[I[F[F[F)J"),
|
||||||
{const_cast<char *>("releaseProximityInfoNative"),
|
reinterpret_cast<void *>(latinime_Keyboard_setProximityInfo)
|
||||||
const_cast<char *>("(J)V"),
|
},
|
||||||
reinterpret_cast<void *>(latinime_Keyboard_release)}
|
{
|
||||||
|
const_cast<char *>("releaseProximityInfoNative"),
|
||||||
|
const_cast<char *>("(J)V"),
|
||||||
|
reinterpret_cast<void *>(latinime_Keyboard_release)
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
int register_ProximityInfo(JNIEnv *env) {
|
int register_ProximityInfo(JNIEnv *env) {
|
||||||
|
|
|
@ -14,23 +14,16 @@
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <cstring> // for memset()
|
|
||||||
|
|
||||||
#define LOG_TAG "LatinIME: jni: BinaryDictionary"
|
#define LOG_TAG "LatinIME: jni: BinaryDictionary"
|
||||||
|
|
||||||
#include "defines.h" // for macros below
|
|
||||||
|
|
||||||
#ifdef USE_MMAP_FOR_DICTIONARY
|
|
||||||
#include <cerrno>
|
|
||||||
#include <fcntl.h>
|
|
||||||
#include <sys/mman.h>
|
|
||||||
#else // USE_MMAP_FOR_DICTIONARY
|
|
||||||
#include <cstdlib>
|
|
||||||
#include <cstdio> // for fopen() etc.
|
|
||||||
#endif // USE_MMAP_FOR_DICTIONARY
|
|
||||||
|
|
||||||
#include "com_android_inputmethod_latin_BinaryDictionary.h"
|
#include "com_android_inputmethod_latin_BinaryDictionary.h"
|
||||||
|
|
||||||
|
#include <cerrno>
|
||||||
|
#include <cstring> // for memset()
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include <sys/mman.h>
|
||||||
|
|
||||||
|
#include "defines.h"
|
||||||
#include "jni.h"
|
#include "jni.h"
|
||||||
#include "jni_common.h"
|
#include "jni_common.h"
|
||||||
#include "obsolete/correction.h"
|
#include "obsolete/correction.h"
|
||||||
|
@ -60,8 +53,6 @@ static jlong latinime_BinaryDictionary_open(JNIEnv *env, jclass clazz, jstring s
|
||||||
int fd = 0;
|
int fd = 0;
|
||||||
void *dictBuf = 0;
|
void *dictBuf = 0;
|
||||||
int adjust = 0;
|
int adjust = 0;
|
||||||
#ifdef USE_MMAP_FOR_DICTIONARY
|
|
||||||
/* mmap version */
|
|
||||||
fd = open(sourceDirChars, O_RDONLY);
|
fd = open(sourceDirChars, O_RDONLY);
|
||||||
if (fd < 0) {
|
if (fd < 0) {
|
||||||
AKLOGE("DICT: Can't open sourceDir. sourceDirChars=%s errno=%d", sourceDirChars, errno);
|
AKLOGE("DICT: Can't open sourceDir. sourceDirChars=%s errno=%d", sourceDirChars, errno);
|
||||||
|
@ -77,35 +68,6 @@ static jlong latinime_BinaryDictionary_open(JNIEnv *env, jclass clazz, jstring s
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
dictBuf = static_cast<char *>(dictBuf) + adjust;
|
dictBuf = static_cast<char *>(dictBuf) + adjust;
|
||||||
#else // USE_MMAP_FOR_DICTIONARY
|
|
||||||
/* malloc version */
|
|
||||||
FILE *file = 0;
|
|
||||||
file = fopen(sourceDirChars, "rb");
|
|
||||||
if (file == 0) {
|
|
||||||
AKLOGE("DICT: Can't fopen sourceDir. sourceDirChars=%s errno=%d", sourceDirChars, errno);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
dictBuf = malloc(dictSize);
|
|
||||||
if (!dictBuf) {
|
|
||||||
AKLOGE("DICT: Can't allocate memory region for dictionary. errno=%d", errno);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
int ret = fseek(file, static_cast<long>(dictOffset), SEEK_SET);
|
|
||||||
if (ret != 0) {
|
|
||||||
AKLOGE("DICT: Failure in fseek. ret=%d errno=%d", ret, errno);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
ret = fread(dictBuf, dictSize, 1, file);
|
|
||||||
if (ret != 1) {
|
|
||||||
AKLOGE("DICT: Failure in fread. ret=%d errno=%d", ret, errno);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
ret = fclose(file);
|
|
||||||
if (ret != 0) {
|
|
||||||
AKLOGE("DICT: Failure in fclose. ret=%d errno=%d", ret, errno);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
#endif // USE_MMAP_FOR_DICTIONARY
|
|
||||||
if (!dictBuf) {
|
if (!dictBuf) {
|
||||||
AKLOGE("DICT: dictBuf is null");
|
AKLOGE("DICT: dictBuf is null");
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -115,11 +77,7 @@ static jlong latinime_BinaryDictionary_open(JNIEnv *env, jclass clazz, jstring s
|
||||||
== BinaryDictionaryFormat::detectFormatVersion(static_cast<uint8_t *>(dictBuf),
|
== BinaryDictionaryFormat::detectFormatVersion(static_cast<uint8_t *>(dictBuf),
|
||||||
static_cast<int>(dictSize))) {
|
static_cast<int>(dictSize))) {
|
||||||
AKLOGE("DICT: dictionary format is unknown, bad magic number");
|
AKLOGE("DICT: dictionary format is unknown, bad magic number");
|
||||||
#ifdef USE_MMAP_FOR_DICTIONARY
|
|
||||||
releaseDictBuf(static_cast<const char *>(dictBuf) - adjust, adjDictSize, fd);
|
releaseDictBuf(static_cast<const char *>(dictBuf) - adjust, adjDictSize, fd);
|
||||||
#else // USE_MMAP_FOR_DICTIONARY
|
|
||||||
releaseDictBuf(dictBuf, 0, 0);
|
|
||||||
#endif // USE_MMAP_FOR_DICTIONARY
|
|
||||||
} else {
|
} else {
|
||||||
dictionary = new Dictionary(dictBuf, static_cast<int>(dictSize), fd, adjust);
|
dictionary = new Dictionary(dictBuf, static_cast<int>(dictSize), fd, adjust);
|
||||||
}
|
}
|
||||||
|
@ -264,17 +222,12 @@ static void latinime_BinaryDictionary_close(JNIEnv *env, jclass clazz, jlong dic
|
||||||
if (!dictionary) return;
|
if (!dictionary) return;
|
||||||
const void *dictBuf = dictionary->getBinaryDictionaryInfo()->getDictBuf();
|
const void *dictBuf = dictionary->getBinaryDictionaryInfo()->getDictBuf();
|
||||||
if (!dictBuf) return;
|
if (!dictBuf) return;
|
||||||
#ifdef USE_MMAP_FOR_DICTIONARY
|
|
||||||
releaseDictBuf(static_cast<const char *>(dictBuf) - dictionary->getDictBufAdjust(),
|
releaseDictBuf(static_cast<const char *>(dictBuf) - dictionary->getDictBufAdjust(),
|
||||||
dictionary->getDictSize() + dictionary->getDictBufAdjust(), dictionary->getMmapFd());
|
dictionary->getDictSize() + dictionary->getDictBufAdjust(), dictionary->getMmapFd());
|
||||||
#else // USE_MMAP_FOR_DICTIONARY
|
|
||||||
releaseDictBuf(dictBuf, 0, 0);
|
|
||||||
#endif // USE_MMAP_FOR_DICTIONARY
|
|
||||||
delete dictionary;
|
delete dictionary;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void releaseDictBuf(const void *dictBuf, const size_t length, const int fd) {
|
static void releaseDictBuf(const void *dictBuf, const size_t length, const int fd) {
|
||||||
#ifdef USE_MMAP_FOR_DICTIONARY
|
|
||||||
int ret = munmap(const_cast<void *>(dictBuf), length);
|
int ret = munmap(const_cast<void *>(dictBuf), length);
|
||||||
if (ret != 0) {
|
if (ret != 0) {
|
||||||
AKLOGE("DICT: Failure in munmap. ret=%d errno=%d", ret, errno);
|
AKLOGE("DICT: Failure in munmap. ret=%d errno=%d", ret, errno);
|
||||||
|
@ -283,33 +236,44 @@ static void releaseDictBuf(const void *dictBuf, const size_t length, const int f
|
||||||
if (ret != 0) {
|
if (ret != 0) {
|
||||||
AKLOGE("DICT: Failure in close. ret=%d errno=%d", ret, errno);
|
AKLOGE("DICT: Failure in close. ret=%d errno=%d", ret, errno);
|
||||||
}
|
}
|
||||||
#else // USE_MMAP_FOR_DICTIONARY
|
|
||||||
free(const_cast<void *>(dictBuf));
|
|
||||||
#endif // USE_MMAP_FOR_DICTIONARY
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static JNINativeMethod sMethods[] = {
|
static const JNINativeMethod sMethods[] = {
|
||||||
{const_cast<char *>("openNative"),
|
{
|
||||||
const_cast<char *>("(Ljava/lang/String;JJ)J"),
|
const_cast<char *>("openNative"),
|
||||||
reinterpret_cast<void *>(latinime_BinaryDictionary_open)},
|
const_cast<char *>("(Ljava/lang/String;JJ)J"),
|
||||||
{const_cast<char *>("closeNative"),
|
reinterpret_cast<void *>(latinime_BinaryDictionary_open)
|
||||||
const_cast<char *>("(J)V"),
|
},
|
||||||
reinterpret_cast<void *>(latinime_BinaryDictionary_close)},
|
{
|
||||||
{const_cast<char *>("getSuggestionsNative"),
|
const_cast<char *>("closeNative"),
|
||||||
const_cast<char *>("(JJJ[I[I[I[I[III[I[I[I[I[I[I)I"),
|
const_cast<char *>("(J)V"),
|
||||||
reinterpret_cast<void *>(latinime_BinaryDictionary_getSuggestions)},
|
reinterpret_cast<void *>(latinime_BinaryDictionary_close)
|
||||||
{const_cast<char *>("getProbabilityNative"),
|
},
|
||||||
const_cast<char *>("(J[I)I"),
|
{
|
||||||
reinterpret_cast<void *>(latinime_BinaryDictionary_getProbability)},
|
const_cast<char *>("getSuggestionsNative"),
|
||||||
{const_cast<char *>("isValidBigramNative"),
|
const_cast<char *>("(JJJ[I[I[I[I[III[I[I[I[I[I[I)I"),
|
||||||
const_cast<char *>("(J[I[I)Z"),
|
reinterpret_cast<void *>(latinime_BinaryDictionary_getSuggestions)
|
||||||
reinterpret_cast<void *>(latinime_BinaryDictionary_isValidBigram)},
|
},
|
||||||
{const_cast<char *>("calcNormalizedScoreNative"),
|
{
|
||||||
const_cast<char *>("([I[II)F"),
|
const_cast<char *>("getProbabilityNative"),
|
||||||
reinterpret_cast<void *>(latinime_BinaryDictionary_calcNormalizedScore)},
|
const_cast<char *>("(J[I)I"),
|
||||||
{const_cast<char *>("editDistanceNative"),
|
reinterpret_cast<void *>(latinime_BinaryDictionary_getProbability)
|
||||||
const_cast<char *>("([I[I)I"),
|
},
|
||||||
reinterpret_cast<void *>(latinime_BinaryDictionary_editDistance)}
|
{
|
||||||
|
const_cast<char *>("isValidBigramNative"),
|
||||||
|
const_cast<char *>("(J[I[I)Z"),
|
||||||
|
reinterpret_cast<void *>(latinime_BinaryDictionary_isValidBigram)
|
||||||
|
},
|
||||||
|
{
|
||||||
|
const_cast<char *>("calcNormalizedScoreNative"),
|
||||||
|
const_cast<char *>("([I[II)F"),
|
||||||
|
reinterpret_cast<void *>(latinime_BinaryDictionary_calcNormalizedScore)
|
||||||
|
},
|
||||||
|
{
|
||||||
|
const_cast<char *>("editDistanceNative"),
|
||||||
|
const_cast<char *>("([I[I)I"),
|
||||||
|
reinterpret_cast<void *>(latinime_BinaryDictionary_editDistance)
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
int register_BinaryDictionary(JNIEnv *env) {
|
int register_BinaryDictionary(JNIEnv *env) {
|
||||||
|
|
|
@ -50,16 +50,22 @@ static void latinime_releaseDicTraverseSession(JNIEnv *env, jclass clazz, jlong
|
||||||
DicTraverseSession::releaseSessionInstance(ts);
|
DicTraverseSession::releaseSessionInstance(ts);
|
||||||
}
|
}
|
||||||
|
|
||||||
static JNINativeMethod sMethods[] = {
|
static const JNINativeMethod sMethods[] = {
|
||||||
{const_cast<char *>("setDicTraverseSessionNative"),
|
{
|
||||||
const_cast<char *>("(Ljava/lang/String;)J"),
|
const_cast<char *>("setDicTraverseSessionNative"),
|
||||||
reinterpret_cast<void *>(latinime_setDicTraverseSession)},
|
const_cast<char *>("(Ljava/lang/String;)J"),
|
||||||
{const_cast<char *>("initDicTraverseSessionNative"),
|
reinterpret_cast<void *>(latinime_setDicTraverseSession)
|
||||||
const_cast<char *>("(JJ[II)V"),
|
},
|
||||||
reinterpret_cast<void *>(latinime_initDicTraverseSession)},
|
{
|
||||||
{const_cast<char *>("releaseDicTraverseSessionNative"),
|
const_cast<char *>("initDicTraverseSessionNative"),
|
||||||
const_cast<char *>("(J)V"),
|
const_cast<char *>("(JJ[II)V"),
|
||||||
reinterpret_cast<void *>(latinime_releaseDicTraverseSession)}
|
reinterpret_cast<void *>(latinime_initDicTraverseSession)
|
||||||
|
},
|
||||||
|
{
|
||||||
|
const_cast<char *>("releaseDicTraverseSessionNative"),
|
||||||
|
const_cast<char *>("(J)V"),
|
||||||
|
reinterpret_cast<void *>(latinime_releaseDicTraverseSession)
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
int register_DicTraverseSession(JNIEnv *env) {
|
int register_DicTraverseSession(JNIEnv *env) {
|
||||||
|
|
|
@ -55,8 +55,8 @@ jint JNI_OnLoad(JavaVM *vm, void *reserved) {
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace latinime {
|
namespace latinime {
|
||||||
int registerNativeMethods(JNIEnv *env, const char *className, JNINativeMethod *methods,
|
int registerNativeMethods(JNIEnv *env, const char *const className, const JNINativeMethod *methods,
|
||||||
int numMethods) {
|
const int numMethods) {
|
||||||
jclass clazz = env->FindClass(className);
|
jclass clazz = env->FindClass(className);
|
||||||
if (!clazz) {
|
if (!clazz) {
|
||||||
AKLOGE("Native registration unable to find class '%s'", className);
|
AKLOGE("Native registration unable to find class '%s'", className);
|
||||||
|
|
|
@ -20,7 +20,7 @@
|
||||||
#include "jni.h"
|
#include "jni.h"
|
||||||
|
|
||||||
namespace latinime {
|
namespace latinime {
|
||||||
int registerNativeMethods(JNIEnv *env, const char *className, JNINativeMethod *methods,
|
int registerNativeMethods(JNIEnv *env, const char *const className, const JNINativeMethod *methods,
|
||||||
int numMethods);
|
const int numMethods);
|
||||||
} // namespace latinime
|
} // namespace latinime
|
||||||
#endif // LATINIME_JNI_COMMON_H
|
#endif // LATINIME_JNI_COMMON_H
|
||||||
|
|
|
@ -264,11 +264,6 @@ static inline void prof_out(void) {
|
||||||
// of the binary dictionary where a {key,value} string pair scheme is used.
|
// of the binary dictionary where a {key,value} string pair scheme is used.
|
||||||
#define LARGEST_INT_DIGIT_COUNT 11
|
#define LARGEST_INT_DIGIT_COUNT 11
|
||||||
|
|
||||||
// Define this to use mmap() for dictionary loading. Undefine to use malloc() instead of mmap().
|
|
||||||
// We measured and compared performance of both, and found mmap() is fairly good in terms of
|
|
||||||
// loading time, and acceptable even for several initial lookups which involve page faults.
|
|
||||||
#define USE_MMAP_FOR_DICTIONARY
|
|
||||||
|
|
||||||
#define NOT_VALID_WORD (-99)
|
#define NOT_VALID_WORD (-99)
|
||||||
#define NOT_A_CODE_POINT (-1)
|
#define NOT_A_CODE_POINT (-1)
|
||||||
#define NOT_A_DISTANCE (-1)
|
#define NOT_A_DISTANCE (-1)
|
||||||
|
|
Loading…
Reference in New Issue